8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softDecryptUtil.c
blob355c3b5bdde021b78b163d1718fa244fcaa9a797
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <pthread.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <sys/types.h>
31 #include <security/cryptoki.h>
32 #include <modes/modes.h>
33 #include <arcfour.h>
34 #include "softSession.h"
35 #include "softObject.h"
36 #include "softOps.h"
37 #include "softCrypt.h"
38 #include "softRSA.h"
41 * Remove padding bytes.
43 CK_RV
44 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
45 CK_ULONG *pulDataLen)
47 CK_RV rv;
49 #ifdef __sparcv9
50 if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK)
51 #else /* !__sparcv9 */
52 if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK)
53 #endif /* __sparcv9 */
54 return (rv);
56 *pulDataLen = padded_len;
57 return (CKR_OK);
62 * soft_decrypt_init()
64 * Arguments:
65 * session_p: pointer to soft_session_t struct
66 * pMechanism: pointer to CK_MECHANISM struct provided by application
67 * key_p: pointer to key soft_object_t struct
69 * Description:
70 * called by C_DecryptInit(). This function calls the corresponding
71 * decrypt init routine based on the mechanism.
73 * Returns:
74 * CKR_OK: success
75 * CKR_HOST_MEMORY: run out of system memory
76 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
77 * CKR_MECHANISM_INVALID: invalid mechanism type
78 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
79 * with the specified mechanism
81 CK_RV
82 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
83 soft_object_t *key_p)
86 CK_RV rv;
88 switch (pMechanism->mechanism) {
90 case CKM_DES_ECB:
92 if (key_p->key_type != CKK_DES) {
93 return (CKR_KEY_TYPE_INCONSISTENT);
96 goto ecb_common;
98 case CKM_DES3_ECB:
100 if ((key_p->key_type != CKK_DES2) &&
101 (key_p->key_type != CKK_DES3)) {
102 return (CKR_KEY_TYPE_INCONSISTENT);
105 ecb_common:
107 return (soft_des_crypt_init_common(session_p, pMechanism,
108 key_p, B_FALSE));
110 case CKM_DES_CBC:
111 case CKM_DES_CBC_PAD:
113 if (key_p->key_type != CKK_DES) {
114 return (CKR_KEY_TYPE_INCONSISTENT);
117 goto cbc_common;
119 case CKM_DES3_CBC:
120 case CKM_DES3_CBC_PAD:
122 soft_des_ctx_t *soft_des_ctx;
124 if ((key_p->key_type != CKK_DES2) &&
125 (key_p->key_type != CKK_DES3)) {
126 return (CKR_KEY_TYPE_INCONSISTENT);
129 cbc_common:
130 if ((pMechanism->pParameter == NULL) ||
131 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
132 return (CKR_MECHANISM_PARAM_INVALID);
135 rv = soft_des_crypt_init_common(session_p, pMechanism,
136 key_p, B_FALSE);
138 if (rv != CKR_OK)
139 return (rv);
141 (void) pthread_mutex_lock(&session_p->session_mutex);
143 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
144 /* Save Initialization Vector (IV) in the context. */
145 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
146 DES_BLOCK_LEN);
148 /* Allocate a context for DES cipher-block chaining. */
149 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
150 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
151 soft_des_ctx->ivec, key_p->key_type);
153 if (soft_des_ctx->des_cbc == NULL) {
154 bzero(soft_des_ctx->key_sched,
155 soft_des_ctx->keysched_len);
156 free(soft_des_ctx->key_sched);
157 free(session_p->decrypt.context);
158 session_p->decrypt.context = NULL;
159 (void) pthread_mutex_unlock(&session_p->session_mutex);
160 return (CKR_HOST_MEMORY);
163 (void) pthread_mutex_unlock(&session_p->session_mutex);
165 return (rv);
167 case CKM_AES_ECB:
169 if (key_p->key_type != CKK_AES) {
170 return (CKR_KEY_TYPE_INCONSISTENT);
173 return (soft_aes_crypt_init_common(session_p, pMechanism,
174 key_p, B_FALSE));
176 case CKM_AES_CBC:
177 case CKM_AES_CBC_PAD:
179 soft_aes_ctx_t *soft_aes_ctx;
181 if (key_p->key_type != CKK_AES) {
182 return (CKR_KEY_TYPE_INCONSISTENT);
185 if ((pMechanism->pParameter == NULL) ||
186 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
187 return (CKR_MECHANISM_PARAM_INVALID);
190 rv = soft_aes_crypt_init_common(session_p, pMechanism,
191 key_p, B_FALSE);
193 if (rv != CKR_OK)
194 return (rv);
196 (void) pthread_mutex_lock(&session_p->session_mutex);
198 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
200 /* Save Initialization Vector (IV) in the context. */
201 (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
202 AES_BLOCK_LEN);
204 /* Allocate a context for AES cipher-block chaining. */
205 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
206 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
207 soft_aes_ctx->ivec);
209 if (soft_aes_ctx->aes_cbc == NULL) {
210 bzero(soft_aes_ctx->key_sched,
211 soft_aes_ctx->keysched_len);
212 free(soft_aes_ctx->key_sched);
213 free(session_p->decrypt.context);
214 session_p->decrypt.context = NULL;
215 (void) pthread_mutex_unlock(&session_p->session_mutex);
216 return (CKR_HOST_MEMORY);
219 (void) pthread_mutex_unlock(&session_p->session_mutex);
221 return (rv);
223 case CKM_AES_CTR:
225 soft_aes_ctx_t *soft_aes_ctx;
227 if (key_p->key_type != CKK_AES) {
228 return (CKR_KEY_TYPE_INCONSISTENT);
231 if (pMechanism->pParameter == NULL ||
232 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
233 return (CKR_MECHANISM_PARAM_INVALID);
236 rv = soft_aes_crypt_init_common(session_p, pMechanism,
237 key_p, B_FALSE);
239 if (rv != CKR_OK)
240 return (rv);
242 (void) pthread_mutex_lock(&session_p->session_mutex);
244 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
245 soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
246 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
247 pMechanism->pParameter);
249 if (soft_aes_ctx->aes_cbc == NULL) {
250 bzero(soft_aes_ctx->key_sched,
251 soft_aes_ctx->keysched_len);
252 free(soft_aes_ctx->key_sched);
253 free(session_p->decrypt.context);
254 session_p->decrypt.context = NULL;
255 rv = CKR_HOST_MEMORY;
258 (void) pthread_mutex_unlock(&session_p->session_mutex);
260 return (rv);
262 case CKM_BLOWFISH_CBC:
264 soft_blowfish_ctx_t *soft_blowfish_ctx;
266 if (key_p->key_type != CKK_BLOWFISH)
267 return (CKR_KEY_TYPE_INCONSISTENT);
269 if ((pMechanism->pParameter == NULL) ||
270 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
271 return (CKR_MECHANISM_PARAM_INVALID);
273 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
274 key_p, B_FALSE);
276 if (rv != CKR_OK)
277 return (rv);
279 (void) pthread_mutex_lock(&session_p->session_mutex);
281 soft_blowfish_ctx =
282 (soft_blowfish_ctx_t *)session_p->decrypt.context;
284 /* Save Initialization Vector in the context. */
285 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
286 BLOWFISH_BLOCK_LEN);
288 /* Allocate a context for CBC */
289 soft_blowfish_ctx->blowfish_cbc =
290 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
291 soft_blowfish_ctx->keysched_len,
292 soft_blowfish_ctx->ivec);
294 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
295 bzero(soft_blowfish_ctx->key_sched,
296 soft_blowfish_ctx->keysched_len);
297 free(soft_blowfish_ctx->key_sched);
298 free(session_p->decrypt.context = NULL);
299 (void) pthread_mutex_unlock(&session_p->session_mutex);
300 return (CKR_HOST_MEMORY);
303 (void) pthread_mutex_unlock(&session_p->session_mutex);
304 return (rv);
307 case CKM_RC4:
309 if (key_p->key_type != CKK_RC4) {
310 return (CKR_KEY_TYPE_INCONSISTENT);
313 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
314 B_FALSE));
316 case CKM_RSA_X_509:
317 case CKM_RSA_PKCS:
319 if (key_p->key_type != CKK_RSA) {
320 return (CKR_KEY_TYPE_INCONSISTENT);
323 return (soft_rsa_crypt_init_common(session_p, pMechanism,
324 key_p, B_FALSE));
326 default:
327 return (CKR_MECHANISM_INVALID);
333 * soft_decrypt_common()
335 * Arguments:
336 * session_p: pointer to soft_session_t struct
337 * pEncrypted: pointer to the encrypted data as input
338 * ulEncryptedLen: length of the input data
339 * pData: pointer to the output data contains plaintext
340 * pulDataLen: pointer to the length of the output data
341 * Update: boolean flag indicates caller is soft_decrypt
342 * or soft_decrypt_update
344 * Description:
345 * This function calls the corresponding decrypt routine based
346 * on the mechanism.
348 * Returns:
349 * see soft_decrypt_common().
351 CK_RV
352 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
353 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
354 CK_ULONG_PTR pulDataLen, boolean_t Update)
357 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
359 switch (mechanism) {
361 case CKM_DES_ECB:
362 case CKM_DES_CBC:
363 case CKM_DES3_ECB:
364 case CKM_DES3_CBC:
366 if (ulEncryptedLen == 0) {
367 *pulDataLen = 0;
368 return (CKR_OK);
370 /* FALLTHROUGH */
372 case CKM_DES_CBC_PAD:
373 case CKM_DES3_CBC_PAD:
375 return (soft_des_decrypt_common(session_p, pEncrypted,
376 ulEncryptedLen, pData, pulDataLen, Update));
378 case CKM_AES_ECB:
379 case CKM_AES_CBC:
380 case CKM_AES_CTR:
382 if (ulEncryptedLen == 0) {
383 *pulDataLen = 0;
384 return (CKR_OK);
386 /* FALLTHROUGH */
388 case CKM_AES_CBC_PAD:
390 return (soft_aes_decrypt_common(session_p, pEncrypted,
391 ulEncryptedLen, pData, pulDataLen, Update));
393 case CKM_BLOWFISH_CBC:
395 if (ulEncryptedLen == 0) {
396 *pulDataLen = 0;
397 return (CKR_OK);
400 return (soft_blowfish_decrypt_common(session_p, pEncrypted,
401 ulEncryptedLen, pData, pulDataLen, Update));
403 case CKM_RC4:
405 if (ulEncryptedLen == 0) {
406 *pulDataLen = 0;
407 return (CKR_OK);
411 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted,
412 ulEncryptedLen, pData, pulDataLen));
414 case CKM_RSA_X_509:
415 case CKM_RSA_PKCS:
417 return (soft_rsa_decrypt_common(session_p, pEncrypted,
418 ulEncryptedLen, pData, pulDataLen, mechanism));
420 default:
421 return (CKR_MECHANISM_INVALID);
428 * soft_decrypt()
430 * Arguments:
431 * session_p: pointer to soft_session_t struct
432 * pEncryptedData: pointer to the encrypted data as input
433 * ulEncryptedDataLen: length of the input data
434 * pData: pointer to the output data contains plaintext
435 * pulDataLen: pointer to the length of the output data
437 * Description:
438 * called by C_Decrypt(). This function calls the soft_decrypt_common
439 * routine.
441 * Returns:
442 * see soft_decrypt_common().
444 CK_RV
445 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData,
446 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
447 CK_ULONG_PTR pulDataLen)
450 return (soft_decrypt_common(session_p, pEncryptedData,
451 ulEncryptedDataLen, pData, pulDataLen, B_FALSE));
456 * soft_decrypt_update()
458 * Arguments:
459 * session_p: pointer to soft_session_t struct
460 * pEncryptedPart: pointer to the encrypted data as input
461 * ulEncryptedPartLen: length of the input data
462 * pPart: pointer to the output data contains plaintext
463 * pulPartLen: pointer to the length of the output data
465 * Description:
466 * called by C_DecryptUpdate(). This function calls the
467 * soft_decrypt_common routine (with update flag on).
469 * Returns:
470 * see soft_decrypt_common().
472 CK_RV
473 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart,
474 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
475 CK_ULONG_PTR pulPartLen)
477 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
479 switch (mechanism) {
481 case CKM_DES_ECB:
482 case CKM_DES_CBC:
483 case CKM_DES_CBC_PAD:
484 case CKM_DES3_ECB:
485 case CKM_DES3_CBC:
486 case CKM_DES3_CBC_PAD:
487 case CKM_AES_ECB:
488 case CKM_AES_CBC:
489 case CKM_AES_CBC_PAD:
490 case CKM_AES_CTR:
491 case CKM_BLOWFISH_CBC:
492 case CKM_RC4:
494 return (soft_decrypt_common(session_p, pEncryptedPart,
495 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE));
497 default:
498 /* PKCS11: The mechanism only supports single-part operation. */
499 return (CKR_MECHANISM_INVALID);
506 * soft_decrypt_final()
508 * Arguments:
509 * session_p: pointer to soft_session_t struct
510 * pLastPart: pointer to the last recovered data part
511 * pulLastPartLen: pointer to the length of the last recovered data part
513 * Description:
514 * called by C_DecryptFinal().
516 * Returns:
517 * CKR_OK: success
518 * CKR_FUNCTION_FAILED: decrypt final function failed
519 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
521 CK_RV
522 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
523 CK_ULONG_PTR pulLastPartLen)
526 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
527 CK_ULONG out_len;
528 CK_RV rv = CKR_OK;
529 int rc;
531 (void) pthread_mutex_lock(&session_p->session_mutex);
533 if (session_p->decrypt.context == NULL) {
534 rv = CKR_OPERATION_NOT_INITIALIZED;
535 *pulLastPartLen = 0;
536 goto clean2;
538 switch (mechanism) {
540 case CKM_DES_CBC_PAD:
541 case CKM_DES3_CBC_PAD:
544 soft_des_ctx_t *soft_des_ctx;
546 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
549 * We should have only one block of data left in the
550 * remaining buffer.
552 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) {
553 *pulLastPartLen = 0;
554 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
555 /* Cleanup memory space. */
556 free(soft_des_ctx->des_cbc);
557 bzero(soft_des_ctx->key_sched,
558 soft_des_ctx->keysched_len);
559 free(soft_des_ctx->key_sched);
561 goto clean1;
564 out_len = DES_BLOCK_LEN;
567 * If application asks for the length of the output buffer
568 * to hold the plaintext?
570 if (pLastPart == NULL) {
571 *pulLastPartLen = out_len;
572 rv = CKR_OK;
573 goto clean2;
574 } else {
575 crypto_data_t out;
577 /* Copy remaining data to the output buffer. */
578 (void) memcpy(pLastPart, soft_des_ctx->data,
579 DES_BLOCK_LEN);
581 out.cd_format = CRYPTO_DATA_RAW;
582 out.cd_offset = 0;
583 out.cd_length = DES_BLOCK_LEN;
584 out.cd_raw.iov_base = (char *)pLastPart;
585 out.cd_raw.iov_len = DES_BLOCK_LEN;
587 /* Decrypt final block of data. */
588 rc = des_decrypt_contiguous_blocks(
589 (des_ctx_t *)soft_des_ctx->des_cbc,
590 (char *)pLastPart, DES_BLOCK_LEN, &out);
592 if (rc == 0) {
594 * Remove padding bytes after decryption of
595 * ciphertext block to produce the original
596 * plaintext.
598 rv = soft_remove_pkcs7_padding(pLastPart,
599 DES_BLOCK_LEN, &out_len);
600 if (rv != CKR_OK)
601 *pulLastPartLen = 0;
602 else
603 *pulLastPartLen = out_len;
604 } else {
605 *pulLastPartLen = 0;
606 rv = CKR_FUNCTION_FAILED;
609 /* Cleanup memory space. */
610 free(soft_des_ctx->des_cbc);
611 bzero(soft_des_ctx->key_sched,
612 soft_des_ctx->keysched_len);
613 free(soft_des_ctx->key_sched);
617 break;
620 case CKM_DES_CBC:
621 case CKM_DES_ECB:
622 case CKM_DES3_CBC:
623 case CKM_DES3_ECB:
626 soft_des_ctx_t *soft_des_ctx;
628 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
630 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
631 * so when the final is called, the remaining buffer
632 * should not contain any more data.
634 *pulLastPartLen = 0;
635 if (soft_des_ctx->remain_len != 0) {
636 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
637 } else {
638 if (pLastPart == NULL)
639 goto clean2;
642 /* Cleanup memory space. */
643 free(soft_des_ctx->des_cbc);
644 bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
645 free(soft_des_ctx->key_sched);
647 break;
650 case CKM_AES_CBC_PAD:
653 soft_aes_ctx_t *soft_aes_ctx;
655 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
658 * We should have only one block of data left in the
659 * remaining buffer.
661 if (soft_aes_ctx->remain_len != AES_BLOCK_LEN) {
662 *pulLastPartLen = 0;
663 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
664 /* Cleanup memory space. */
665 free(soft_aes_ctx->aes_cbc);
666 bzero(soft_aes_ctx->key_sched,
667 soft_aes_ctx->keysched_len);
668 free(soft_aes_ctx->key_sched);
670 goto clean1;
673 out_len = AES_BLOCK_LEN;
676 * If application asks for the length of the output buffer
677 * to hold the plaintext?
679 if (pLastPart == NULL) {
680 *pulLastPartLen = out_len;
681 rv = CKR_OK;
682 goto clean2;
683 } else {
684 crypto_data_t out;
686 /* Copy remaining data to the output buffer. */
687 (void) memcpy(pLastPart, soft_aes_ctx->data,
688 AES_BLOCK_LEN);
690 out.cd_format = CRYPTO_DATA_RAW;
691 out.cd_offset = 0;
692 out.cd_length = AES_BLOCK_LEN;
693 out.cd_raw.iov_base = (char *)pLastPart;
694 out.cd_raw.iov_len = AES_BLOCK_LEN;
696 /* Decrypt final block of data. */
697 rc = aes_decrypt_contiguous_blocks(
698 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
699 (char *)pLastPart, AES_BLOCK_LEN, &out);
701 if (rc == 0) {
703 * Remove padding bytes after decryption of
704 * ciphertext block to produce the original
705 * plaintext.
707 rv = soft_remove_pkcs7_padding(pLastPart,
708 AES_BLOCK_LEN, &out_len);
709 if (rv != CKR_OK)
710 *pulLastPartLen = 0;
711 else
712 *pulLastPartLen = out_len;
713 } else {
714 *pulLastPartLen = 0;
715 rv = CKR_FUNCTION_FAILED;
718 /* Cleanup memory space. */
719 free(soft_aes_ctx->aes_cbc);
720 bzero(soft_aes_ctx->key_sched,
721 soft_aes_ctx->keysched_len);
722 free(soft_aes_ctx->key_sched);
726 break;
729 case CKM_AES_CBC:
730 case CKM_AES_ECB:
732 soft_aes_ctx_t *soft_aes_ctx;
734 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
736 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
737 * so when the final is called, the remaining buffer
738 * should not contain any more data.
740 *pulLastPartLen = 0;
741 if (soft_aes_ctx->remain_len != 0) {
742 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
743 } else {
744 if (pLastPart == NULL)
745 goto clean2;
748 /* Cleanup memory space. */
749 free(soft_aes_ctx->aes_cbc);
750 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
751 free(soft_aes_ctx->key_sched);
753 break;
755 case CKM_AES_CTR:
757 crypto_data_t out;
758 soft_aes_ctx_t *soft_aes_ctx;
759 ctr_ctx_t *ctr_ctx;
760 size_t len;
762 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
763 ctr_ctx = soft_aes_ctx->aes_cbc;
764 len = ctr_ctx->ctr_remainder_len;
765 if (pLastPart == NULL) {
766 *pulLastPartLen = len;
767 goto clean1;
769 if (len > 0) {
770 out.cd_format = CRYPTO_DATA_RAW;
771 out.cd_offset = 0;
772 out.cd_length = len;
773 out.cd_raw.iov_base = (char *)pLastPart;
774 out.cd_raw.iov_len = len;
776 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
777 if (rv == CRYPTO_DATA_LEN_RANGE)
778 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
780 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
781 *pulLastPartLen = len;
782 goto clean1;
785 /* Cleanup memory space. */
786 free(ctr_ctx);
787 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
788 free(soft_aes_ctx->key_sched);
790 break;
792 case CKM_BLOWFISH_CBC:
794 soft_blowfish_ctx_t *soft_blowfish_ctx;
796 soft_blowfish_ctx =
797 (soft_blowfish_ctx_t *)session_p->decrypt.context;
799 *pulLastPartLen = 0;
800 if (soft_blowfish_ctx->remain_len != 0)
801 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
802 else {
803 if (pLastPart == NULL)
804 goto clean2;
807 free(soft_blowfish_ctx->blowfish_cbc);
808 bzero(soft_blowfish_ctx->key_sched,
809 soft_blowfish_ctx->keysched_len);
810 free(soft_blowfish_ctx->key_sched);
812 break;
815 case CKM_RC4:
817 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
818 bzero(key, sizeof (*key));
819 *pulLastPartLen = 0;
820 break;
823 default:
824 /* PKCS11: The mechanism only supports single-part operation. */
825 rv = CKR_MECHANISM_INVALID;
826 break;
829 clean1:
830 free(session_p->decrypt.context);
831 session_p->decrypt.context = NULL;
833 clean2:
834 (void) pthread_mutex_unlock(&session_p->session_mutex);
836 return (rv);