1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 * Copyright 2017 Jason King.
27 */
28
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/types.h>
34 #include <security/cryptoki.h>
35 #include <modes/modes.h>
36 #include <arcfour.h>
37 #include "softSession.h"
38 #include "softObject.h"
39 #include "softOps.h"
40 #include "softCrypt.h"
41 #include "softRSA.h"
42
43 /*
44 * Add padding bytes with the value of length of padding.
45 */
46 void
soft_add_pkcs7_padding(CK_BYTE * buf,int block_size,CK_ULONG data_len)47 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
48 {
49 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
50 }
51
52 /*
53 * Perform encrypt init operation internally for the support of
54 * CKM_AES and CKM_DES MAC operations.
55 *
56 * This function is called with the session being held, and without
57 * its mutex taken.
58 */
59 CK_RV
soft_encrypt_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)60 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
61 pMechanism, soft_object_t *key_p)
62 {
63 CK_RV rv;
64
65 (void) pthread_mutex_lock(&session_p->session_mutex);
66
67 /* Check to see if encrypt operation is already active */
68 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
69 (void) pthread_mutex_unlock(&session_p->session_mutex);
70 return (CKR_OPERATION_ACTIVE);
71 }
72
73 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
74
75 (void) pthread_mutex_unlock(&session_p->session_mutex);
76
77 rv = soft_encrypt_init(session_p, pMechanism, key_p);
78
79 if (rv != CKR_OK) {
80 (void) pthread_mutex_lock(&session_p->session_mutex);
81 session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
82 (void) pthread_mutex_unlock(&session_p->session_mutex);
83 }
84
85 return (rv);
86 }
87
88 /*
89 * soft_encrypt_init()
90 *
91 * Arguments:
92 * session_p: pointer to soft_session_t struct
93 * pMechanism: pointer to CK_MECHANISM struct provided by application
94 * key_p: pointer to key soft_object_t struct
95 *
96 * Description:
97 * called by C_EncryptInit(). This function calls the corresponding
98 * encrypt init routine based on the mechanism.
99 *
100 * Returns:
101 * CKR_OK: success
102 * CKR_HOST_MEMORY: run out of system memory
103 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
104 * CKR_MECHANISM_INVALID: invalid mechanism type
105 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
106 * with the specified mechanism
107 */
108 CK_RV
soft_encrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)109 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
110 soft_object_t *key_p)
111 {
112
113 CK_RV rv;
114
115 switch (pMechanism->mechanism) {
116
117 case CKM_DES_ECB:
118
119 if (key_p->key_type != CKK_DES) {
120 return (CKR_KEY_TYPE_INCONSISTENT);
121 }
122 goto ecb_common;
123
124 case CKM_DES3_ECB:
125
126 if ((key_p->key_type != CKK_DES2) &&
127 (key_p->key_type != CKK_DES3)) {
128 return (CKR_KEY_TYPE_INCONSISTENT);
129 }
130
131 ecb_common:
132 return (soft_des_crypt_init_common(session_p, pMechanism,
133 key_p, B_TRUE));
134
135 case CKM_DES_CBC:
136 case CKM_DES_CBC_PAD:
137
138 if (key_p->key_type != CKK_DES) {
139 return (CKR_KEY_TYPE_INCONSISTENT);
140 }
141
142 goto cbc_common;
143
144 case CKM_DES3_CBC:
145 case CKM_DES3_CBC_PAD:
146 {
147
148 soft_des_ctx_t *soft_des_ctx;
149
150 if ((key_p->key_type != CKK_DES2) &&
151 (key_p->key_type != CKK_DES3)) {
152 return (CKR_KEY_TYPE_INCONSISTENT);
153 }
154
155 cbc_common:
156 if ((pMechanism->pParameter == NULL) ||
157 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
158 return (CKR_MECHANISM_PARAM_INVALID);
159 }
160
161 rv = soft_des_crypt_init_common(session_p, pMechanism,
162 key_p, B_TRUE);
163
164 if (rv != CKR_OK)
165 return (rv);
166
167 (void) pthread_mutex_lock(&session_p->session_mutex);
168
169 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
170 /* Copy Initialization Vector (IV) into the context. */
171 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
172 DES_BLOCK_LEN);
173
174 /* Allocate a context for DES cipher-block chaining. */
175 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
176 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
177 soft_des_ctx->ivec, key_p->key_type);
178
179 if (soft_des_ctx->des_cbc == NULL) {
180 freezero(soft_des_ctx->key_sched,
181 soft_des_ctx->keysched_len);
182 freezero(session_p->encrypt.context,
183 sizeof (soft_des_ctx_t));
184 session_p->encrypt.context = NULL;
185 rv = CKR_HOST_MEMORY;
186 }
187
188 (void) pthread_mutex_unlock(&session_p->session_mutex);
189
190 return (rv);
191 }
192
193 case CKM_AES_ECB:
194 case CKM_AES_CBC:
195 case CKM_AES_CBC_PAD:
196 case CKM_AES_CMAC:
197 case CKM_AES_CTR:
198 case CKM_AES_CCM:
199 case CKM_AES_GCM:
200 return (soft_aes_crypt_init_common(session_p, pMechanism,
201 key_p, B_TRUE));
202
203 case CKM_RC4:
204
205 if (key_p->key_type != CKK_RC4) {
206 return (CKR_KEY_TYPE_INCONSISTENT);
207 }
208
209 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
210 B_TRUE));
211
212 case CKM_RSA_X_509:
213 case CKM_RSA_PKCS:
214
215 if (key_p->key_type != CKK_RSA) {
216 return (CKR_KEY_TYPE_INCONSISTENT);
217 }
218
219 return (soft_rsa_crypt_init_common(session_p, pMechanism,
220 key_p, B_TRUE));
221
222 case CKM_BLOWFISH_CBC:
223 {
224 soft_blowfish_ctx_t *soft_blowfish_ctx;
225
226 if (key_p->key_type != CKK_BLOWFISH)
227 return (CKR_KEY_TYPE_INCONSISTENT);
228
229 if ((pMechanism->pParameter == NULL) ||
230 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
231 return (CKR_MECHANISM_PARAM_INVALID);
232
233 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
234 key_p, B_TRUE);
235
236 if (rv != CKR_OK)
237 return (rv);
238
239 (void) pthread_mutex_lock(&session_p->session_mutex);
240
241 soft_blowfish_ctx =
242 (soft_blowfish_ctx_t *)session_p->encrypt.context;
243 /* Copy Initialization Vector (IV) into the context. */
244 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
245 BLOWFISH_BLOCK_LEN);
246
247 /* Allocate a context for Blowfish cipher-block chaining */
248 soft_blowfish_ctx->blowfish_cbc =
249 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
250 soft_blowfish_ctx->keysched_len,
251 soft_blowfish_ctx->ivec);
252
253 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
254 freezero(soft_blowfish_ctx->key_sched,
255 soft_blowfish_ctx->keysched_len);
256 freezero(session_p->encrypt.context,
257 sizeof (soft_blowfish_ctx_t));
258 session_p->encrypt.context = NULL;
259 rv = CKR_HOST_MEMORY;
260 }
261
262 (void) pthread_mutex_unlock(&session_p->session_mutex);
263
264 return (rv);
265 }
266 default:
267 return (CKR_MECHANISM_INVALID);
268 }
269 }
270
271
272 /*
273 * soft_encrypt_common()
274 *
275 * Arguments:
276 * session_p: pointer to soft_session_t struct
277 * pData: pointer to the input data to be encrypted
278 * ulDataLen: length of the input data
279 * pEncrypted: pointer to the output data after encryption
280 * pulEncryptedLen: pointer to the length of the output data
281 * update: boolean flag indicates caller is soft_encrypt
282 * or soft_encrypt_update
283 *
284 * Description:
285 * This function calls the corresponding encrypt routine based
286 * on the mechanism.
287 *
288 * Returns:
289 * see corresponding encrypt routine.
290 */
291 CK_RV
soft_encrypt_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncrypted,CK_ULONG_PTR pulEncryptedLen,boolean_t update)292 soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
293 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
294 CK_ULONG_PTR pulEncryptedLen, boolean_t update)
295 {
296
297 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
298
299 switch (mechanism) {
300
301 case CKM_DES_ECB:
302 case CKM_DES_CBC:
303 case CKM_DES3_ECB:
304 case CKM_DES3_CBC:
305
306 if (ulDataLen == 0) {
307 *pulEncryptedLen = 0;
308 return (CKR_OK);
309 }
310 /* FALLTHROUGH */
311
312 case CKM_DES_CBC_PAD:
313 case CKM_DES3_CBC_PAD:
314
315 return (soft_des_encrypt_common(session_p, pData,
316 ulDataLen, pEncrypted, pulEncryptedLen, update));
317
318 case CKM_AES_ECB:
319 case CKM_AES_CBC:
320 case CKM_AES_CTR:
321 case CKM_AES_CCM:
322 case CKM_AES_CMAC:
323 case CKM_AES_CBC_PAD:
324 case CKM_AES_GCM:
325 if (update) {
326 return (soft_aes_encrypt_update(session_p, pData,
327 ulDataLen, pEncrypted, pulEncryptedLen));
328 } else {
329 return (soft_aes_encrypt(session_p, pData,
330 ulDataLen, pEncrypted, pulEncryptedLen));
331 }
332
333 case CKM_BLOWFISH_CBC:
334
335 if (ulDataLen == 0) {
336 *pulEncryptedLen = 0;
337 return (CKR_OK);
338 }
339
340 return (soft_blowfish_encrypt_common(session_p, pData,
341 ulDataLen, pEncrypted, pulEncryptedLen, update));
342
343 case CKM_RC4:
344
345 if (ulDataLen == 0) {
346 *pulEncryptedLen = 0;
347 return (CKR_OK);
348 }
349
350 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
351 ulDataLen, pEncrypted, pulEncryptedLen));
352
353 case CKM_RSA_X_509:
354 case CKM_RSA_PKCS:
355
356 return (soft_rsa_encrypt_common(session_p, pData,
357 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
358
359 default:
360 return (CKR_MECHANISM_INVALID);
361 }
362 }
363
364
365 /*
366 * soft_encrypt()
367 *
368 * Arguments:
369 * session_p: pointer to soft_session_t struct
370 * pData: pointer to the input data to be encrypted
371 * ulDataLen: length of the input data
372 * pEncryptedData: pointer to the output data after encryption
373 * pulEncryptedDataLen: pointer to the length of the output data
374 *
375 * Description:
376 * called by C_Encrypt(). This function calls the soft_encrypt_common
377 * routine.
378 *
379 * Returns:
380 * see soft_encrypt_common().
381 */
382 CK_RV
soft_encrypt(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)383 soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
384 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
385 CK_ULONG_PTR pulEncryptedDataLen)
386 {
387 return (soft_encrypt_common(session_p, pData, ulDataLen,
388 pEncryptedData, pulEncryptedDataLen, B_FALSE));
389 }
390
391
392 /*
393 * soft_encrypt_update()
394 *
395 * Arguments:
396 * session_p: pointer to soft_session_t struct
397 * pPart: pointer to the input data to be digested
398 * ulPartLen: length of the input data
399 * pEncryptedPart: pointer to the ciphertext
400 * pulEncryptedPartLen: pointer to the length of the ciphertext
401 *
402 * Description:
403 * called by C_EncryptUpdate(). This function calls the
404 * soft_encrypt_common routine (with update flag on).
405 *
406 * Returns:
407 * see soft_encrypt_common().
408 */
409 CK_RV
soft_encrypt_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)410 soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
411 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
412 CK_ULONG_PTR pulEncryptedPartLen)
413 {
414
415 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
416
417 switch (mechanism) {
418
419 case CKM_DES_ECB:
420 case CKM_DES_CBC:
421 case CKM_DES_CBC_PAD:
422 case CKM_DES3_ECB:
423 case CKM_DES3_CBC:
424 case CKM_DES3_CBC_PAD:
425 case CKM_AES_ECB:
426 case CKM_AES_CBC:
427 case CKM_AES_CBC_PAD:
428 case CKM_AES_CMAC:
429 case CKM_AES_CTR:
430 case CKM_AES_GCM:
431 case CKM_AES_CCM:
432 case CKM_BLOWFISH_CBC:
433 case CKM_RC4:
434
435 return (soft_encrypt_common(session_p, pPart, ulPartLen,
436 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
437
438 default:
439 /* PKCS11: The mechanism only supports single-part operation. */
440 return (CKR_MECHANISM_INVALID);
441 }
442 }
443
444
445 /*
446 * soft_encrypt_final()
447 *
448 * Arguments:
449 * session_p: pointer to soft_session_t struct
450 * pLastEncryptedPart: pointer to the last encrypted data part
451 * pulLastEncryptedPartLen: pointer to the length of the last
452 * encrypted data part
453 *
454 * Description:
455 * called by C_EncryptFinal().
456 *
457 * Returns:
458 * CKR_OK: success
459 * CKR_FUNCTION_FAILED: encrypt final function failed
460 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
461 */
462 CK_RV
soft_encrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)463 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
464 CK_ULONG_PTR pulLastEncryptedPartLen)
465 {
466
467 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
468 CK_ULONG out_len;
469 CK_RV rv = CKR_OK;
470 int rc;
471
472 (void) pthread_mutex_lock(&session_p->session_mutex);
473
474 if (session_p->encrypt.context == NULL) {
475 rv = CKR_OPERATION_NOT_INITIALIZED;
476 *pulLastEncryptedPartLen = 0;
477 goto clean1;
478 }
479 switch (mechanism) {
480
481 case CKM_DES_CBC_PAD:
482 case CKM_DES3_CBC_PAD:
483 {
484 soft_des_ctx_t *soft_des_ctx;
485
486 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
487 /*
488 * For CKM_DES_CBC_PAD, compute output length with
489 * padding. If the remaining buffer has one block
490 * of data, then output length will be two blocksize of
491 * ciphertext. If the remaining buffer has less than
492 * one block of data, then output length will be
493 * one blocksize.
494 */
495 if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
496 out_len = 2 * DES_BLOCK_LEN;
497 else
498 out_len = DES_BLOCK_LEN;
499
500 if (pLastEncryptedPart == NULL) {
501 /*
502 * Application asks for the length of the output
503 * buffer to hold the ciphertext.
504 */
505 *pulLastEncryptedPartLen = out_len;
506 goto clean1;
507 } else {
508 crypto_data_t out;
509
510 /* Copy remaining data to the output buffer. */
511 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
512 soft_des_ctx->remain_len);
513
514 /*
515 * Add padding bytes prior to encrypt final.
516 */
517 soft_add_pkcs7_padding(pLastEncryptedPart +
518 soft_des_ctx->remain_len, DES_BLOCK_LEN,
519 soft_des_ctx->remain_len);
520
521 out.cd_format = CRYPTO_DATA_RAW;
522 out.cd_offset = 0;
523 out.cd_length = out_len;
524 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
525 out.cd_raw.iov_len = out_len;
526
527 /* Encrypt multiple blocks of data. */
528 rc = des_encrypt_contiguous_blocks(
529 (des_ctx_t *)soft_des_ctx->des_cbc,
530 (char *)pLastEncryptedPart, out_len, &out);
531
532 if (rc == 0) {
533 *pulLastEncryptedPartLen = out_len;
534 } else {
535 *pulLastEncryptedPartLen = 0;
536 rv = CKR_FUNCTION_FAILED;
537 }
538
539 /* Cleanup memory space. */
540 free(soft_des_ctx->des_cbc);
541 freezero(soft_des_ctx->key_sched,
542 soft_des_ctx->keysched_len);
543 }
544
545 break;
546 }
547 case CKM_DES_CBC:
548 case CKM_DES_ECB:
549 case CKM_DES3_CBC:
550 case CKM_DES3_ECB:
551 {
552
553 soft_des_ctx_t *soft_des_ctx;
554
555 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
556 /*
557 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
558 * so when the final is called, the remaining buffer
559 * should not contain any more data.
560 */
561 *pulLastEncryptedPartLen = 0;
562 if (soft_des_ctx->remain_len != 0) {
563 rv = CKR_DATA_LEN_RANGE;
564 } else {
565 if (pLastEncryptedPart == NULL)
566 goto clean1;
567 }
568
569 /* Cleanup memory space. */
570 free(soft_des_ctx->des_cbc);
571 freezero(soft_des_ctx->key_sched,
572 soft_des_ctx->keysched_len);
573
574 break;
575 }
576 case CKM_AES_CBC_PAD:
577 case CKM_AES_CMAC:
578 case CKM_AES_CBC:
579 case CKM_AES_ECB:
580 case CKM_AES_CTR:
581 case CKM_AES_CCM:
582 case CKM_AES_GCM:
583 rv = soft_aes_encrypt_final(session_p, pLastEncryptedPart,
584 pulLastEncryptedPartLen);
585 break;
586
587 case CKM_BLOWFISH_CBC:
588 {
589 soft_blowfish_ctx_t *soft_blowfish_ctx;
590
591 soft_blowfish_ctx =
592 (soft_blowfish_ctx_t *)session_p->encrypt.context;
593 /*
594 * CKM_BLOWFISH_CBC does not do any padding, so when the
595 * final is called, the remaining buffer should not contain
596 * any more data
597 */
598 *pulLastEncryptedPartLen = 0;
599 if (soft_blowfish_ctx->remain_len != 0)
600 rv = CKR_DATA_LEN_RANGE;
601 else {
602 if (pLastEncryptedPart == NULL)
603 goto clean1;
604 }
605
606 free(soft_blowfish_ctx->blowfish_cbc);
607 freezero(soft_blowfish_ctx->key_sched,
608 soft_blowfish_ctx->keysched_len);
609 break;
610 }
611
612 case CKM_RC4:
613 {
614 ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
615 /* Remaining data size is always zero for RC4. */
616 *pulLastEncryptedPartLen = 0;
617 if (pLastEncryptedPart == NULL)
618 goto clean1;
619 explicit_bzero(key, sizeof (*key));
620 break;
621 }
622 default:
623 /* PKCS11: The mechanism only supports single-part operation. */
624 rv = CKR_MECHANISM_INVALID;
625 break;
626 }
627
628 free(session_p->encrypt.context);
629 session_p->encrypt.context = NULL;
630 clean1:
631 (void) pthread_mutex_unlock(&session_p->session_mutex);
632
633 return (rv);
634 }
635
636 /*
637 * This function frees the allocated active crypto context and the
638 * lower level of allocated struct as needed.
639 * This function is called by the 1st tier of encrypt/decrypt routines
640 * or by the 2nd tier of session close routine. Since the 1st tier
641 * caller will always call this function without locking the session
642 * mutex and the 2nd tier caller will call with the lock, we add the
643 * third parameter "lock_held" to distinguish this case.
644 */
645 void
soft_crypt_cleanup(soft_session_t * session_p,boolean_t encrypt,boolean_t lock_held)646 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
647 boolean_t lock_held)
648 {
649
650 crypto_active_op_t *active_op;
651 boolean_t lock_true = B_TRUE;
652
653 if (!lock_held)
654 (void) pthread_mutex_lock(&session_p->session_mutex);
655
656 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
657
658 switch (active_op->mech.mechanism) {
659
660 case CKM_DES_CBC_PAD:
661 case CKM_DES3_CBC_PAD:
662 case CKM_DES_CBC:
663 case CKM_DES_ECB:
664 case CKM_DES3_CBC:
665 case CKM_DES3_ECB:
666 {
667
668 soft_des_ctx_t *soft_des_ctx =
669 (soft_des_ctx_t *)active_op->context;
670 des_ctx_t *des_ctx;
671
672 if (soft_des_ctx != NULL) {
673 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
674 if (des_ctx != NULL) {
675 explicit_bzero(des_ctx->dc_keysched,
676 des_ctx->dc_keysched_len);
677 free(soft_des_ctx->des_cbc);
678 }
679 freezero(soft_des_ctx->key_sched,
680 soft_des_ctx->keysched_len);
681 }
682 break;
683 }
684
685 case CKM_AES_CBC_PAD:
686 case CKM_AES_CBC:
687 case CKM_AES_CMAC:
688 case CKM_AES_ECB:
689 case CKM_AES_GCM:
690 case CKM_AES_CCM:
691 case CKM_AES_CTR:
692 soft_aes_free_ctx(active_op->context);
693 active_op->context = NULL;
694 break;
695
696 case CKM_BLOWFISH_CBC:
697 {
698 soft_blowfish_ctx_t *soft_blowfish_ctx =
699 (soft_blowfish_ctx_t *)active_op->context;
700 blowfish_ctx_t *blowfish_ctx;
701
702 if (soft_blowfish_ctx != NULL) {
703 blowfish_ctx =
704 (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
705 if (blowfish_ctx != NULL) {
706 explicit_bzero(blowfish_ctx->bc_keysched,
707 blowfish_ctx->bc_keysched_len);
708 free(soft_blowfish_ctx->blowfish_cbc);
709 }
710
711 freezero(soft_blowfish_ctx->key_sched,
712 soft_blowfish_ctx->keysched_len);
713 }
714 break;
715 }
716
717 case CKM_RC4:
718 {
719 ARCFour_key *key = (ARCFour_key *)active_op->context;
720
721 if (key != NULL)
722 explicit_bzero(key, sizeof (*key));
723 break;
724 }
725
726 case CKM_RSA_X_509:
727 case CKM_RSA_PKCS:
728 {
729 soft_rsa_ctx_t *rsa_ctx =
730 (soft_rsa_ctx_t *)active_op->context;
731
732 if (rsa_ctx != NULL)
733 if (rsa_ctx->key != NULL) {
734 soft_cleanup_object(rsa_ctx->key);
735 free(rsa_ctx->key);
736 }
737
738 break;
739 }
740
741 } /* switch */
742
743 if (active_op->context != NULL) {
744 free(active_op->context);
745 active_op->context = NULL;
746 }
747
748 active_op->flags = 0;
749
750 if (!lock_held)
751 SES_REFRELE(session_p, lock_true);
752 }
753