dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softEncryptUtil.c
blob39e863065e2a61f38d28a5345b4893913978a00d
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 * Add padding bytes with the value of length of padding.
43 void
44 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
46 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
50 * Perform encrypt init operation internally for the support of
51 * CKM_DES_MAC and CKM_DES_MAC_GENERAL
53 * This function is called with the session being held, and without
54 * its mutex taken.
56 CK_RV
57 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
58 pMechanism, soft_object_t *key_p)
60 CK_RV rv;
62 (void) pthread_mutex_lock(&session_p->session_mutex);
64 /* Check to see if encrypt operation is already active */
65 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
66 (void) pthread_mutex_unlock(&session_p->session_mutex);
67 return (CKR_OPERATION_ACTIVE);
70 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
72 (void) pthread_mutex_unlock(&session_p->session_mutex);
74 rv = soft_encrypt_init(session_p, pMechanism, key_p);
76 if (rv != CKR_OK) {
77 (void) pthread_mutex_lock(&session_p->session_mutex);
78 session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
79 (void) pthread_mutex_unlock(&session_p->session_mutex);
82 return (rv);
86 * soft_encrypt_init()
88 * Arguments:
89 * session_p: pointer to soft_session_t struct
90 * pMechanism: pointer to CK_MECHANISM struct provided by application
91 * key_p: pointer to key soft_object_t struct
93 * Description:
94 * called by C_EncryptInit(). This function calls the corresponding
95 * encrypt init routine based on the mechanism.
97 * Returns:
98 * CKR_OK: success
99 * CKR_HOST_MEMORY: run out of system memory
100 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
101 * CKR_MECHANISM_INVALID: invalid mechanism type
102 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
103 * with the specified mechanism
105 CK_RV
106 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
107 soft_object_t *key_p)
110 CK_RV rv;
112 switch (pMechanism->mechanism) {
114 case CKM_DES_ECB:
116 if (key_p->key_type != CKK_DES) {
117 return (CKR_KEY_TYPE_INCONSISTENT);
119 goto ecb_common;
121 case CKM_DES3_ECB:
123 if ((key_p->key_type != CKK_DES2) &&
124 (key_p->key_type != CKK_DES3)) {
125 return (CKR_KEY_TYPE_INCONSISTENT);
128 ecb_common:
129 return (soft_des_crypt_init_common(session_p, pMechanism,
130 key_p, B_TRUE));
132 case CKM_DES_CBC:
133 case CKM_DES_CBC_PAD:
135 if (key_p->key_type != CKK_DES) {
136 return (CKR_KEY_TYPE_INCONSISTENT);
139 goto cbc_common;
141 case CKM_DES3_CBC:
142 case CKM_DES3_CBC_PAD:
145 soft_des_ctx_t *soft_des_ctx;
147 if ((key_p->key_type != CKK_DES2) &&
148 (key_p->key_type != CKK_DES3)) {
149 return (CKR_KEY_TYPE_INCONSISTENT);
152 cbc_common:
153 if ((pMechanism->pParameter == NULL) ||
154 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
155 return (CKR_MECHANISM_PARAM_INVALID);
158 rv = soft_des_crypt_init_common(session_p, pMechanism,
159 key_p, B_TRUE);
161 if (rv != CKR_OK)
162 return (rv);
164 (void) pthread_mutex_lock(&session_p->session_mutex);
166 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
167 /* Copy Initialization Vector (IV) into the context. */
168 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
169 DES_BLOCK_LEN);
171 /* Allocate a context for DES cipher-block chaining. */
172 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
173 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
174 soft_des_ctx->ivec, key_p->key_type);
176 if (soft_des_ctx->des_cbc == NULL) {
177 bzero(soft_des_ctx->key_sched,
178 soft_des_ctx->keysched_len);
179 free(soft_des_ctx->key_sched);
180 free(session_p->encrypt.context);
181 session_p->encrypt.context = NULL;
182 rv = CKR_HOST_MEMORY;
185 (void) pthread_mutex_unlock(&session_p->session_mutex);
187 return (rv);
189 case CKM_AES_ECB:
191 if (key_p->key_type != CKK_AES) {
192 return (CKR_KEY_TYPE_INCONSISTENT);
195 return (soft_aes_crypt_init_common(session_p, pMechanism,
196 key_p, B_TRUE));
198 case CKM_AES_CBC:
199 case CKM_AES_CBC_PAD:
201 soft_aes_ctx_t *soft_aes_ctx;
203 if (key_p->key_type != CKK_AES) {
204 return (CKR_KEY_TYPE_INCONSISTENT);
207 if ((pMechanism->pParameter == NULL) ||
208 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
209 return (CKR_MECHANISM_PARAM_INVALID);
212 rv = soft_aes_crypt_init_common(session_p, pMechanism,
213 key_p, B_TRUE);
215 if (rv != CKR_OK)
216 return (rv);
218 (void) pthread_mutex_lock(&session_p->session_mutex);
220 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
221 /* Copy Initialization Vector (IV) into the context. */
222 (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
223 AES_BLOCK_LEN);
225 /* Allocate a context for AES cipher-block chaining. */
226 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
227 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
228 soft_aes_ctx->ivec);
230 if (soft_aes_ctx->aes_cbc == NULL) {
231 bzero(soft_aes_ctx->key_sched,
232 soft_aes_ctx->keysched_len);
233 free(soft_aes_ctx->key_sched);
234 free(session_p->encrypt.context);
235 session_p->encrypt.context = NULL;
236 rv = CKR_HOST_MEMORY;
239 (void) pthread_mutex_unlock(&session_p->session_mutex);
241 return (rv);
243 case CKM_AES_CTR:
245 soft_aes_ctx_t *soft_aes_ctx;
247 if (key_p->key_type != CKK_AES) {
248 return (CKR_KEY_TYPE_INCONSISTENT);
251 if (pMechanism->pParameter == NULL ||
252 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
253 return (CKR_MECHANISM_PARAM_INVALID);
256 rv = soft_aes_crypt_init_common(session_p, pMechanism,
257 key_p, B_TRUE);
259 if (rv != CKR_OK)
260 return (rv);
262 (void) pthread_mutex_lock(&session_p->session_mutex);
264 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
265 soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
266 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
267 pMechanism->pParameter);
269 if (soft_aes_ctx->aes_cbc == NULL) {
270 bzero(soft_aes_ctx->key_sched,
271 soft_aes_ctx->keysched_len);
272 free(soft_aes_ctx->key_sched);
273 free(session_p->encrypt.context);
274 session_p->encrypt.context = NULL;
275 rv = CKR_HOST_MEMORY;
278 (void) pthread_mutex_unlock(&session_p->session_mutex);
280 return (rv);
282 case CKM_RC4:
284 if (key_p->key_type != CKK_RC4) {
285 return (CKR_KEY_TYPE_INCONSISTENT);
288 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
289 B_TRUE));
291 case CKM_RSA_X_509:
292 case CKM_RSA_PKCS:
294 if (key_p->key_type != CKK_RSA) {
295 return (CKR_KEY_TYPE_INCONSISTENT);
298 return (soft_rsa_crypt_init_common(session_p, pMechanism,
299 key_p, B_TRUE));
301 case CKM_BLOWFISH_CBC:
303 soft_blowfish_ctx_t *soft_blowfish_ctx;
305 if (key_p->key_type != CKK_BLOWFISH)
306 return (CKR_KEY_TYPE_INCONSISTENT);
308 if ((pMechanism->pParameter == NULL) ||
309 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
310 return (CKR_MECHANISM_PARAM_INVALID);
312 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
313 key_p, B_TRUE);
315 if (rv != CKR_OK)
316 return (rv);
318 (void) pthread_mutex_lock(&session_p->session_mutex);
320 soft_blowfish_ctx =
321 (soft_blowfish_ctx_t *)session_p->encrypt.context;
322 /* Copy Initialization Vector (IV) into the context. */
323 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
324 BLOWFISH_BLOCK_LEN);
326 /* Allocate a context for Blowfish cipher-block chaining */
327 soft_blowfish_ctx->blowfish_cbc =
328 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
329 soft_blowfish_ctx->keysched_len,
330 soft_blowfish_ctx->ivec);
332 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
333 bzero(soft_blowfish_ctx->key_sched,
334 soft_blowfish_ctx->keysched_len);
335 free(soft_blowfish_ctx->key_sched);
336 free(session_p->encrypt.context);
337 session_p->encrypt.context = NULL;
338 rv = CKR_HOST_MEMORY;
341 (void) pthread_mutex_unlock(&session_p->session_mutex);
343 return (rv);
345 default:
346 return (CKR_MECHANISM_INVALID);
352 * soft_encrypt_common()
354 * Arguments:
355 * session_p: pointer to soft_session_t struct
356 * pData: pointer to the input data to be encrypted
357 * ulDataLen: length of the input data
358 * pEncrypted: pointer to the output data after encryption
359 * pulEncryptedLen: pointer to the length of the output data
360 * update: boolean flag indicates caller is soft_encrypt
361 * or soft_encrypt_update
363 * Description:
364 * This function calls the corresponding encrypt routine based
365 * on the mechanism.
367 * Returns:
368 * see corresponding encrypt routine.
370 CK_RV
371 soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
372 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
373 CK_ULONG_PTR pulEncryptedLen, boolean_t update)
376 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
378 switch (mechanism) {
380 case CKM_DES_ECB:
381 case CKM_DES_CBC:
382 case CKM_DES3_ECB:
383 case CKM_DES3_CBC:
385 if (ulDataLen == 0) {
386 *pulEncryptedLen = 0;
387 return (CKR_OK);
389 /* FALLTHROUGH */
391 case CKM_DES_CBC_PAD:
392 case CKM_DES3_CBC_PAD:
394 return (soft_des_encrypt_common(session_p, pData,
395 ulDataLen, pEncrypted, pulEncryptedLen, update));
397 case CKM_AES_ECB:
398 case CKM_AES_CBC:
399 case CKM_AES_CTR:
401 if (ulDataLen == 0) {
402 *pulEncryptedLen = 0;
403 return (CKR_OK);
405 /* FALLTHROUGH */
407 case CKM_AES_CBC_PAD:
409 return (soft_aes_encrypt_common(session_p, pData,
410 ulDataLen, pEncrypted, pulEncryptedLen, update));
412 case CKM_BLOWFISH_CBC:
414 if (ulDataLen == 0) {
415 *pulEncryptedLen = 0;
416 return (CKR_OK);
419 return (soft_blowfish_encrypt_common(session_p, pData,
420 ulDataLen, pEncrypted, pulEncryptedLen, update));
422 case CKM_RC4:
424 if (ulDataLen == 0) {
425 *pulEncryptedLen = 0;
426 return (CKR_OK);
429 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
430 ulDataLen, pEncrypted, pulEncryptedLen));
432 case CKM_RSA_X_509:
433 case CKM_RSA_PKCS:
435 return (soft_rsa_encrypt_common(session_p, pData,
436 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
438 default:
439 return (CKR_MECHANISM_INVALID);
445 * soft_encrypt()
447 * Arguments:
448 * session_p: pointer to soft_session_t struct
449 * pData: pointer to the input data to be encrypted
450 * ulDataLen: length of the input data
451 * pEncryptedData: pointer to the output data after encryption
452 * pulEncryptedDataLen: pointer to the length of the output data
454 * Description:
455 * called by C_Encrypt(). This function calls the soft_encrypt_common
456 * routine.
458 * Returns:
459 * see soft_encrypt_common().
461 CK_RV
462 soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
463 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
464 CK_ULONG_PTR pulEncryptedDataLen)
467 return (soft_encrypt_common(session_p, pData, ulDataLen,
468 pEncryptedData, pulEncryptedDataLen, B_FALSE));
473 * soft_encrypt_update()
475 * Arguments:
476 * session_p: pointer to soft_session_t struct
477 * pPart: pointer to the input data to be digested
478 * ulPartLen: length of the input data
479 * pEncryptedPart: pointer to the ciphertext
480 * pulEncryptedPartLen: pointer to the length of the ciphertext
482 * Description:
483 * called by C_EncryptUpdate(). This function calls the
484 * soft_encrypt_common routine (with update flag on).
486 * Returns:
487 * see soft_encrypt_common().
489 CK_RV
490 soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
491 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
492 CK_ULONG_PTR pulEncryptedPartLen)
495 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
497 switch (mechanism) {
499 case CKM_DES_ECB:
500 case CKM_DES_CBC:
501 case CKM_DES_CBC_PAD:
502 case CKM_DES3_ECB:
503 case CKM_DES3_CBC:
504 case CKM_DES3_CBC_PAD:
505 case CKM_AES_ECB:
506 case CKM_AES_CBC:
507 case CKM_AES_CBC_PAD:
508 case CKM_AES_CTR:
509 case CKM_BLOWFISH_CBC:
510 case CKM_RC4:
512 return (soft_encrypt_common(session_p, pPart, ulPartLen,
513 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
515 default:
516 /* PKCS11: The mechanism only supports single-part operation. */
517 return (CKR_MECHANISM_INVALID);
523 * soft_encrypt_final()
525 * Arguments:
526 * session_p: pointer to soft_session_t struct
527 * pLastEncryptedPart: pointer to the last encrypted data part
528 * pulLastEncryptedPartLen: pointer to the length of the last
529 * encrypted data part
531 * Description:
532 * called by C_EncryptFinal().
534 * Returns:
535 * CKR_OK: success
536 * CKR_FUNCTION_FAILED: encrypt final function failed
537 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
539 CK_RV
540 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
541 CK_ULONG_PTR pulLastEncryptedPartLen)
544 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
545 CK_ULONG out_len;
546 CK_RV rv = CKR_OK;
547 int rc;
549 (void) pthread_mutex_lock(&session_p->session_mutex);
551 if (session_p->encrypt.context == NULL) {
552 rv = CKR_OPERATION_NOT_INITIALIZED;
553 *pulLastEncryptedPartLen = 0;
554 goto clean1;
556 switch (mechanism) {
558 case CKM_DES_CBC_PAD:
559 case CKM_DES3_CBC_PAD:
561 soft_des_ctx_t *soft_des_ctx;
563 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
565 * For CKM_DES_CBC_PAD, compute output length with
566 * padding. If the remaining buffer has one block
567 * of data, then output length will be two blocksize of
568 * ciphertext. If the remaining buffer has less than
569 * one block of data, then output length will be
570 * one blocksize.
572 if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
573 out_len = 2 * DES_BLOCK_LEN;
574 else
575 out_len = DES_BLOCK_LEN;
577 if (pLastEncryptedPart == NULL) {
579 * Application asks for the length of the output
580 * buffer to hold the ciphertext.
582 *pulLastEncryptedPartLen = out_len;
583 goto clean1;
584 } else {
585 crypto_data_t out;
587 /* Copy remaining data to the output buffer. */
588 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
589 soft_des_ctx->remain_len);
592 * Add padding bytes prior to encrypt final.
594 soft_add_pkcs7_padding(pLastEncryptedPart +
595 soft_des_ctx->remain_len, DES_BLOCK_LEN,
596 soft_des_ctx->remain_len);
598 out.cd_format = CRYPTO_DATA_RAW;
599 out.cd_offset = 0;
600 out.cd_length = out_len;
601 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
602 out.cd_raw.iov_len = out_len;
604 /* Encrypt multiple blocks of data. */
605 rc = des_encrypt_contiguous_blocks(
606 (des_ctx_t *)soft_des_ctx->des_cbc,
607 (char *)pLastEncryptedPart, out_len, &out);
609 if (rc == 0) {
610 *pulLastEncryptedPartLen = out_len;
611 } else {
612 *pulLastEncryptedPartLen = 0;
613 rv = CKR_FUNCTION_FAILED;
616 /* Cleanup memory space. */
617 free(soft_des_ctx->des_cbc);
618 bzero(soft_des_ctx->key_sched,
619 soft_des_ctx->keysched_len);
620 free(soft_des_ctx->key_sched);
623 break;
625 case CKM_DES_CBC:
626 case CKM_DES_ECB:
627 case CKM_DES3_CBC:
628 case CKM_DES3_ECB:
631 soft_des_ctx_t *soft_des_ctx;
633 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
635 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
636 * so when the final is called, the remaining buffer
637 * should not contain any more data.
639 *pulLastEncryptedPartLen = 0;
640 if (soft_des_ctx->remain_len != 0) {
641 rv = CKR_DATA_LEN_RANGE;
642 } else {
643 if (pLastEncryptedPart == NULL)
644 goto clean1;
647 /* Cleanup memory space. */
648 free(soft_des_ctx->des_cbc);
649 bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
650 free(soft_des_ctx->key_sched);
652 break;
654 case CKM_AES_CBC_PAD:
656 soft_aes_ctx_t *soft_aes_ctx;
658 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
660 * For CKM_AES_CBC_PAD, compute output length with
661 * padding. If the remaining buffer has one block
662 * of data, then output length will be two blocksize of
663 * ciphertext. If the remaining buffer has less than
664 * one block of data, then output length will be
665 * one blocksize.
667 if (soft_aes_ctx->remain_len == AES_BLOCK_LEN)
668 out_len = 2 * AES_BLOCK_LEN;
669 else
670 out_len = AES_BLOCK_LEN;
672 if (pLastEncryptedPart == NULL) {
674 * Application asks for the length of the output
675 * buffer to hold the ciphertext.
677 *pulLastEncryptedPartLen = out_len;
678 goto clean1;
679 } else {
680 crypto_data_t out;
682 /* Copy remaining data to the output buffer. */
683 (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
684 soft_aes_ctx->remain_len);
687 * Add padding bytes prior to encrypt final.
689 soft_add_pkcs7_padding(pLastEncryptedPart +
690 soft_aes_ctx->remain_len, AES_BLOCK_LEN,
691 soft_aes_ctx->remain_len);
693 out.cd_format = CRYPTO_DATA_RAW;
694 out.cd_offset = 0;
695 out.cd_length = out_len;
696 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
697 out.cd_raw.iov_len = out_len;
699 /* Encrypt multiple blocks of data. */
700 rc = aes_encrypt_contiguous_blocks(
701 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
702 (char *)pLastEncryptedPart, out_len, &out);
704 if (rc == 0) {
705 *pulLastEncryptedPartLen = out_len;
706 } else {
707 *pulLastEncryptedPartLen = 0;
708 rv = CKR_FUNCTION_FAILED;
711 /* Cleanup memory space. */
712 free(soft_aes_ctx->aes_cbc);
713 bzero(soft_aes_ctx->key_sched,
714 soft_aes_ctx->keysched_len);
715 free(soft_aes_ctx->key_sched);
718 break;
720 case CKM_AES_CBC:
721 case CKM_AES_ECB:
723 soft_aes_ctx_t *soft_aes_ctx;
725 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
727 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
728 * so when the final is called, the remaining buffer
729 * should not contain any more data.
731 *pulLastEncryptedPartLen = 0;
732 if (soft_aes_ctx->remain_len != 0) {
733 rv = CKR_DATA_LEN_RANGE;
734 } else {
735 if (pLastEncryptedPart == NULL)
736 goto clean1;
739 /* Cleanup memory space. */
740 free(soft_aes_ctx->aes_cbc);
741 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
742 free(soft_aes_ctx->key_sched);
744 break;
746 case CKM_AES_CTR:
748 crypto_data_t out;
749 soft_aes_ctx_t *soft_aes_ctx;
750 ctr_ctx_t *ctr_ctx;
751 size_t len;
753 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
754 ctr_ctx = soft_aes_ctx->aes_cbc;
755 len = ctr_ctx->ctr_remainder_len;
757 if (pLastEncryptedPart == NULL) {
758 *pulLastEncryptedPartLen = len;
759 goto clean1;
761 if (len > 0) {
762 out.cd_format = CRYPTO_DATA_RAW;
763 out.cd_offset = 0;
764 out.cd_length = len;
765 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
766 out.cd_raw.iov_len = len;
768 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
770 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
771 *pulLastEncryptedPartLen = len;
772 goto clean1;
775 /* Cleanup memory space. */
776 free(ctr_ctx);
777 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
778 free(soft_aes_ctx->key_sched);
780 break;
782 case CKM_BLOWFISH_CBC:
784 soft_blowfish_ctx_t *soft_blowfish_ctx;
786 soft_blowfish_ctx =
787 (soft_blowfish_ctx_t *)session_p->encrypt.context;
789 * CKM_BLOWFISH_CBC does not do any padding, so when the
790 * final is called, the remaining buffer should not contain
791 * any more data
793 *pulLastEncryptedPartLen = 0;
794 if (soft_blowfish_ctx->remain_len != 0)
795 rv = CKR_DATA_LEN_RANGE;
796 else {
797 if (pLastEncryptedPart == NULL)
798 goto clean1;
801 free(soft_blowfish_ctx->blowfish_cbc);
802 bzero(soft_blowfish_ctx->key_sched,
803 soft_blowfish_ctx->keysched_len);
804 free(soft_blowfish_ctx->key_sched);
805 break;
808 case CKM_RC4:
810 ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
811 /* Remaining data size is always zero for RC4. */
812 *pulLastEncryptedPartLen = 0;
813 if (pLastEncryptedPart == NULL)
814 goto clean1;
815 bzero(key, sizeof (*key));
816 break;
818 default:
819 /* PKCS11: The mechanism only supports single-part operation. */
820 rv = CKR_MECHANISM_INVALID;
821 break;
824 free(session_p->encrypt.context);
825 session_p->encrypt.context = NULL;
826 clean1:
827 (void) pthread_mutex_unlock(&session_p->session_mutex);
829 return (rv);
833 * This function frees the allocated active crypto context and the
834 * lower level of allocated struct as needed.
835 * This function is called by the 1st tier of encrypt/decrypt routines
836 * or by the 2nd tier of session close routine. Since the 1st tier
837 * caller will always call this function without locking the session
838 * mutex and the 2nd tier caller will call with the lock, we add the
839 * third parameter "lock_held" to distinguish this case.
841 void
842 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
843 boolean_t lock_held)
846 crypto_active_op_t *active_op;
847 boolean_t lock_true = B_TRUE;
849 if (!lock_held)
850 (void) pthread_mutex_lock(&session_p->session_mutex);
852 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
854 switch (active_op->mech.mechanism) {
856 case CKM_DES_CBC_PAD:
857 case CKM_DES3_CBC_PAD:
858 case CKM_DES_CBC:
859 case CKM_DES_ECB:
860 case CKM_DES3_CBC:
861 case CKM_DES3_ECB:
864 soft_des_ctx_t *soft_des_ctx =
865 (soft_des_ctx_t *)active_op->context;
866 des_ctx_t *des_ctx;
868 if (soft_des_ctx != NULL) {
869 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
870 if (des_ctx != NULL) {
871 bzero(des_ctx->dc_keysched,
872 des_ctx->dc_keysched_len);
873 free(soft_des_ctx->des_cbc);
875 bzero(soft_des_ctx->key_sched,
876 soft_des_ctx->keysched_len);
877 free(soft_des_ctx->key_sched);
879 break;
882 case CKM_AES_CBC_PAD:
883 case CKM_AES_CBC:
884 case CKM_AES_ECB:
886 soft_aes_ctx_t *soft_aes_ctx =
887 (soft_aes_ctx_t *)active_op->context;
888 aes_ctx_t *aes_ctx;
890 if (soft_aes_ctx != NULL) {
891 aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
892 if (aes_ctx != NULL) {
893 bzero(aes_ctx->ac_keysched,
894 aes_ctx->ac_keysched_len);
895 free(soft_aes_ctx->aes_cbc);
897 bzero(soft_aes_ctx->key_sched,
898 soft_aes_ctx->keysched_len);
899 free(soft_aes_ctx->key_sched);
901 break;
904 case CKM_BLOWFISH_CBC:
906 soft_blowfish_ctx_t *soft_blowfish_ctx =
907 (soft_blowfish_ctx_t *)active_op->context;
908 blowfish_ctx_t *blowfish_ctx;
910 if (soft_blowfish_ctx != NULL) {
911 blowfish_ctx =
912 (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
913 if (blowfish_ctx != NULL) {
914 bzero(blowfish_ctx->bc_keysched,
915 blowfish_ctx->bc_keysched_len);
916 free(soft_blowfish_ctx->blowfish_cbc);
919 bzero(soft_blowfish_ctx->key_sched,
920 soft_blowfish_ctx->keysched_len);
921 free(soft_blowfish_ctx->key_sched);
923 break;
926 case CKM_RC4:
928 ARCFour_key *key = (ARCFour_key *)active_op->context;
930 if (key != NULL)
931 bzero(key, sizeof (*key));
932 break;
935 case CKM_RSA_X_509:
936 case CKM_RSA_PKCS:
938 soft_rsa_ctx_t *rsa_ctx =
939 (soft_rsa_ctx_t *)active_op->context;
941 if (rsa_ctx != NULL)
942 if (rsa_ctx->key != NULL) {
943 soft_cleanup_object(rsa_ctx->key);
944 free(rsa_ctx->key);
947 break;
950 } /* switch */
952 if (active_op->context != NULL) {
953 free(active_op->context);
954 active_op->context = NULL;
957 active_op->flags = 0;
959 if (!lock_held)
960 SES_REFRELE(session_p, lock_true);