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 (c) 2018, Joyent, Inc.
25 */
26
27 #include <pthread.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <sys/types.h>
32 #include <security/cryptoki.h>
33 #include <modes/modes.h>
34 #include <arcfour.h>
35 #include "softSession.h"
36 #include "softObject.h"
37 #include "softOps.h"
38 #include "softCrypt.h"
39 #include "softRSA.h"
40
41 /*
42 * Remove padding bytes.
43 */
44 CK_RV
45 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
46 CK_ULONG *pulDataLen)
47 {
48 CK_RV rv;
49
50 #ifdef __sparcv9
51 if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK)
52 #else /* !__sparcv9 */
53 if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK)
54 #endif /* __sparcv9 */
55 return (rv);
56
57 *pulDataLen = padded_len;
58 return (CKR_OK);
59 }
60
61
62 /*
63 * soft_decrypt_init()
64 *
65 * Arguments:
66 * session_p: pointer to soft_session_t struct
67 * pMechanism: pointer to CK_MECHANISM struct provided by application
68 * key_p: pointer to key soft_object_t struct
69 *
70 * Description:
71 * called by C_DecryptInit(). This function calls the corresponding
72 * decrypt init routine based on the mechanism.
73 *
74 * Returns:
75 * CKR_OK: success
76 * CKR_HOST_MEMORY: run out of system memory
77 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
78 * CKR_MECHANISM_INVALID: invalid mechanism type
79 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
80 * with the specified mechanism
81 */
82 CK_RV
83 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
84 soft_object_t *key_p)
85 {
86
87 CK_RV rv;
88
89 switch (pMechanism->mechanism) {
90
91 case CKM_DES_ECB:
92
93 if (key_p->key_type != CKK_DES) {
94 return (CKR_KEY_TYPE_INCONSISTENT);
95 }
96
97 goto ecb_common;
98
99 case CKM_DES3_ECB:
100
101 if ((key_p->key_type != CKK_DES2) &&
102 (key_p->key_type != CKK_DES3)) {
103 return (CKR_KEY_TYPE_INCONSISTENT);
104 }
105
106 ecb_common:
107
108 return (soft_des_crypt_init_common(session_p, pMechanism,
109 key_p, B_FALSE));
110
111 case CKM_DES_CBC:
112 case CKM_DES_CBC_PAD:
113
114 if (key_p->key_type != CKK_DES) {
115 return (CKR_KEY_TYPE_INCONSISTENT);
116 }
117
118 goto cbc_common;
119
120 case CKM_DES3_CBC:
121 case CKM_DES3_CBC_PAD:
122 {
123 soft_des_ctx_t *soft_des_ctx;
124
125 if ((key_p->key_type != CKK_DES2) &&
126 (key_p->key_type != CKK_DES3)) {
127 return (CKR_KEY_TYPE_INCONSISTENT);
128 }
129
130 cbc_common:
131 if ((pMechanism->pParameter == NULL) ||
132 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
133 return (CKR_MECHANISM_PARAM_INVALID);
134 }
135
136 rv = soft_des_crypt_init_common(session_p, pMechanism,
137 key_p, B_FALSE);
138
139 if (rv != CKR_OK)
140 return (rv);
141
142 (void) pthread_mutex_lock(&session_p->session_mutex);
143
144 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
145 /* Save Initialization Vector (IV) in the context. */
146 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
147 DES_BLOCK_LEN);
148
149 /* Allocate a context for DES cipher-block chaining. */
150 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
151 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
152 soft_des_ctx->ivec, key_p->key_type);
153
154 if (soft_des_ctx->des_cbc == NULL) {
155 freezero(soft_des_ctx->key_sched,
156 soft_des_ctx->keysched_len);
157 freezero(session_p->decrypt.context,
158 sizeof (soft_des_ctx_t));
159 session_p->decrypt.context = NULL;
160 (void) pthread_mutex_unlock(&session_p->session_mutex);
161 return (CKR_HOST_MEMORY);
162 }
163
164 (void) pthread_mutex_unlock(&session_p->session_mutex);
165
166 return (rv);
167 }
168 case CKM_AES_ECB:
169
170 if (key_p->key_type != CKK_AES) {
171 return (CKR_KEY_TYPE_INCONSISTENT);
172 }
173
174 return (soft_aes_crypt_init_common(session_p, pMechanism,
175 key_p, B_FALSE));
176
177 case CKM_AES_CBC:
178 case CKM_AES_CBC_PAD:
179 {
180 soft_aes_ctx_t *soft_aes_ctx;
181
182 if (key_p->key_type != CKK_AES) {
183 return (CKR_KEY_TYPE_INCONSISTENT);
184 }
185
186 if ((pMechanism->pParameter == NULL) ||
187 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
188 return (CKR_MECHANISM_PARAM_INVALID);
189 }
190
191 rv = soft_aes_crypt_init_common(session_p, pMechanism,
192 key_p, B_FALSE);
193
194 if (rv != CKR_OK)
195 return (rv);
196
197 (void) pthread_mutex_lock(&session_p->session_mutex);
198
199 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
200
201 /* Save Initialization Vector (IV) in the context. */
202 (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
203 AES_BLOCK_LEN);
204
205 /* Allocate a context for AES cipher-block chaining. */
206 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
207 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
208 soft_aes_ctx->ivec);
209
210 if (soft_aes_ctx->aes_cbc == NULL) {
211 freezero(soft_aes_ctx->key_sched,
212 soft_aes_ctx->keysched_len);
213 freezero(session_p->decrypt.context,
214 sizeof (soft_aes_ctx_t));
215 session_p->decrypt.context = NULL;
216 (void) pthread_mutex_unlock(&session_p->session_mutex);
217 return (CKR_HOST_MEMORY);
218 }
219
220 (void) pthread_mutex_unlock(&session_p->session_mutex);
221
222 return (rv);
223 }
224 case CKM_AES_CTR:
225 {
226 soft_aes_ctx_t *soft_aes_ctx;
227
228 if (key_p->key_type != CKK_AES) {
229 return (CKR_KEY_TYPE_INCONSISTENT);
230 }
231
232 if (pMechanism->pParameter == NULL ||
233 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
234 return (CKR_MECHANISM_PARAM_INVALID);
235 }
236
237 rv = soft_aes_crypt_init_common(session_p, pMechanism,
238 key_p, B_FALSE);
239
240 if (rv != CKR_OK)
241 return (rv);
242
243 (void) pthread_mutex_lock(&session_p->session_mutex);
244
245 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
246 soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
247 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
248 pMechanism->pParameter);
249
250 if (soft_aes_ctx->aes_cbc == NULL) {
251 freezero(soft_aes_ctx->key_sched,
252 soft_aes_ctx->keysched_len);
253 freezero(session_p->decrypt.context,
254 sizeof (soft_aes_ctx_t));
255 session_p->decrypt.context = NULL;
256 rv = CKR_HOST_MEMORY;
257 }
258
259 (void) pthread_mutex_unlock(&session_p->session_mutex);
260
261 return (rv);
262 }
263 case CKM_BLOWFISH_CBC:
264 {
265 soft_blowfish_ctx_t *soft_blowfish_ctx;
266
267 if (key_p->key_type != CKK_BLOWFISH)
268 return (CKR_KEY_TYPE_INCONSISTENT);
269
270 if ((pMechanism->pParameter == NULL) ||
271 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
272 return (CKR_MECHANISM_PARAM_INVALID);
273
274 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
275 key_p, B_FALSE);
276
277 if (rv != CKR_OK)
278 return (rv);
279
280 (void) pthread_mutex_lock(&session_p->session_mutex);
281
282 soft_blowfish_ctx =
283 (soft_blowfish_ctx_t *)session_p->decrypt.context;
284
285 /* Save Initialization Vector in the context. */
286 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
287 BLOWFISH_BLOCK_LEN);
288
289 /* Allocate a context for CBC */
290 soft_blowfish_ctx->blowfish_cbc =
291 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
292 soft_blowfish_ctx->keysched_len,
293 soft_blowfish_ctx->ivec);
294
295 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
296 freezero(soft_blowfish_ctx->key_sched,
297 soft_blowfish_ctx->keysched_len);
298 freezero(session_p->decrypt.context,
299 sizeof (soft_blowfish_ctx_t));
300 session_p->decrypt.context = NULL;
301 (void) pthread_mutex_unlock(&session_p->session_mutex);
302 return (CKR_HOST_MEMORY);
303 }
304
305 (void) pthread_mutex_unlock(&session_p->session_mutex);
306 return (rv);
307 }
308
309 case CKM_RC4:
310
311 if (key_p->key_type != CKK_RC4) {
312 return (CKR_KEY_TYPE_INCONSISTENT);
313 }
314
315 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
316 B_FALSE));
317
318 case CKM_RSA_X_509:
319 case CKM_RSA_PKCS:
320
321 if (key_p->key_type != CKK_RSA) {
322 return (CKR_KEY_TYPE_INCONSISTENT);
323 }
324
325 return (soft_rsa_crypt_init_common(session_p, pMechanism,
326 key_p, B_FALSE));
327
328 default:
329 return (CKR_MECHANISM_INVALID);
330 }
331 }
332
333
334 /*
335 * soft_decrypt_common()
336 *
337 * Arguments:
338 * session_p: pointer to soft_session_t struct
339 * pEncrypted: pointer to the encrypted data as input
340 * ulEncryptedLen: length of the input data
341 * pData: pointer to the output data contains plaintext
342 * pulDataLen: pointer to the length of the output data
343 * Update: boolean flag indicates caller is soft_decrypt
344 * or soft_decrypt_update
345 *
346 * Description:
347 * This function calls the corresponding decrypt routine based
348 * on the mechanism.
349 *
350 * Returns:
351 * see soft_decrypt_common().
352 */
353 CK_RV
354 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
355 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
356 CK_ULONG_PTR pulDataLen, boolean_t Update)
357 {
358
359 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
360
361 switch (mechanism) {
362
363 case CKM_DES_ECB:
364 case CKM_DES_CBC:
365 case CKM_DES3_ECB:
366 case CKM_DES3_CBC:
367
368 if (ulEncryptedLen == 0) {
369 *pulDataLen = 0;
370 return (CKR_OK);
371 }
372 /* FALLTHROUGH */
373
374 case CKM_DES_CBC_PAD:
375 case CKM_DES3_CBC_PAD:
376
377 return (soft_des_decrypt_common(session_p, pEncrypted,
378 ulEncryptedLen, pData, pulDataLen, Update));
379
380 case CKM_AES_ECB:
381 case CKM_AES_CBC:
382 case CKM_AES_CTR:
383
384 if (ulEncryptedLen == 0) {
385 *pulDataLen = 0;
386 return (CKR_OK);
387 }
388 /* FALLTHROUGH */
389
390 case CKM_AES_CBC_PAD:
391
392 return (soft_aes_decrypt_common(session_p, pEncrypted,
393 ulEncryptedLen, pData, pulDataLen, Update));
394
395 case CKM_BLOWFISH_CBC:
396
397 if (ulEncryptedLen == 0) {
398 *pulDataLen = 0;
399 return (CKR_OK);
400 }
401
402 return (soft_blowfish_decrypt_common(session_p, pEncrypted,
403 ulEncryptedLen, pData, pulDataLen, Update));
404
405 case CKM_RC4:
406
407 if (ulEncryptedLen == 0) {
408 *pulDataLen = 0;
409 return (CKR_OK);
410 }
411
412
413 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted,
414 ulEncryptedLen, pData, pulDataLen));
415
416 case CKM_RSA_X_509:
417 case CKM_RSA_PKCS:
418
419 return (soft_rsa_decrypt_common(session_p, pEncrypted,
420 ulEncryptedLen, pData, pulDataLen, mechanism));
421
422 default:
423 return (CKR_MECHANISM_INVALID);
424
425 }
426 }
427
428
429 /*
430 * soft_decrypt()
431 *
432 * Arguments:
433 * session_p: pointer to soft_session_t struct
434 * pEncryptedData: pointer to the encrypted data as input
435 * ulEncryptedDataLen: length of the input data
436 * pData: pointer to the output data contains plaintext
437 * pulDataLen: pointer to the length of the output data
438 *
439 * Description:
440 * called by C_Decrypt(). This function calls the soft_decrypt_common
441 * routine.
442 *
443 * Returns:
444 * see soft_decrypt_common().
445 */
446 CK_RV
447 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData,
448 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
449 CK_ULONG_PTR pulDataLen)
450 {
451
452 return (soft_decrypt_common(session_p, pEncryptedData,
453 ulEncryptedDataLen, pData, pulDataLen, B_FALSE));
454 }
455
456
457 /*
458 * soft_decrypt_update()
459 *
460 * Arguments:
461 * session_p: pointer to soft_session_t struct
462 * pEncryptedPart: pointer to the encrypted data as input
463 * ulEncryptedPartLen: length of the input data
464 * pPart: pointer to the output data contains plaintext
465 * pulPartLen: pointer to the length of the output data
466 *
467 * Description:
468 * called by C_DecryptUpdate(). This function calls the
469 * soft_decrypt_common routine (with update flag on).
470 *
471 * Returns:
472 * see soft_decrypt_common().
473 */
474 CK_RV
475 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart,
476 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
477 CK_ULONG_PTR pulPartLen)
478 {
479 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
480
481 switch (mechanism) {
482
483 case CKM_DES_ECB:
484 case CKM_DES_CBC:
485 case CKM_DES_CBC_PAD:
486 case CKM_DES3_ECB:
487 case CKM_DES3_CBC:
488 case CKM_DES3_CBC_PAD:
489 case CKM_AES_ECB:
490 case CKM_AES_CBC:
491 case CKM_AES_CBC_PAD:
492 case CKM_AES_CTR:
493 case CKM_BLOWFISH_CBC:
494 case CKM_RC4:
495
496 return (soft_decrypt_common(session_p, pEncryptedPart,
497 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE));
498
499 default:
500 /* PKCS11: The mechanism only supports single-part operation. */
501 return (CKR_MECHANISM_INVALID);
502 }
503
504 }
505
506
507 /*
508 * soft_decrypt_final()
509 *
510 * Arguments:
511 * session_p: pointer to soft_session_t struct
512 * pLastPart: pointer to the last recovered data part
513 * pulLastPartLen: pointer to the length of the last recovered data part
514 *
515 * Description:
516 * called by C_DecryptFinal().
517 *
518 * Returns:
519 * CKR_OK: success
520 * CKR_FUNCTION_FAILED: decrypt final function failed
521 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
522 */
523 CK_RV
524 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
525 CK_ULONG_PTR pulLastPartLen)
526 {
527
528 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
529 CK_ULONG out_len;
530 CK_RV rv = CKR_OK;
531 int rc;
532
533 (void) pthread_mutex_lock(&session_p->session_mutex);
534
535 if (session_p->decrypt.context == NULL) {
536 rv = CKR_OPERATION_NOT_INITIALIZED;
537 *pulLastPartLen = 0;
538 goto clean2;
539 }
540 switch (mechanism) {
541
542 case CKM_DES_CBC_PAD:
543 case CKM_DES3_CBC_PAD:
544 {
545
546 soft_des_ctx_t *soft_des_ctx;
547
548 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
549
550 /*
551 * We should have only one block of data left in the
552 * remaining buffer.
553 */
554 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) {
555 *pulLastPartLen = 0;
556 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
557 /* Cleanup memory space. */
558 free(soft_des_ctx->des_cbc);
559 freezero(soft_des_ctx->key_sched,
560 soft_des_ctx->keysched_len);
561
562 goto clean1;
563 }
564
565 out_len = DES_BLOCK_LEN;
566
567 /*
568 * If application asks for the length of the output buffer
569 * to hold the plaintext?
570 */
571 if (pLastPart == NULL) {
572 *pulLastPartLen = out_len;
573 rv = CKR_OK;
574 goto clean2;
575 } else {
576 crypto_data_t out;
577
578 /* Copy remaining data to the output buffer. */
579 (void) memcpy(pLastPart, soft_des_ctx->data,
580 DES_BLOCK_LEN);
581
582 out.cd_format = CRYPTO_DATA_RAW;
583 out.cd_offset = 0;
584 out.cd_length = DES_BLOCK_LEN;
585 out.cd_raw.iov_base = (char *)pLastPart;
586 out.cd_raw.iov_len = DES_BLOCK_LEN;
587
588 /* Decrypt final block of data. */
589 rc = des_decrypt_contiguous_blocks(
590 (des_ctx_t *)soft_des_ctx->des_cbc,
591 (char *)pLastPart, DES_BLOCK_LEN, &out);
592
593 if (rc == 0) {
594 /*
595 * Remove padding bytes after decryption of
596 * ciphertext block to produce the original
597 * plaintext.
598 */
599 rv = soft_remove_pkcs7_padding(pLastPart,
600 DES_BLOCK_LEN, &out_len);
601 if (rv != CKR_OK)
602 *pulLastPartLen = 0;
603 else
604 *pulLastPartLen = out_len;
605 } else {
606 *pulLastPartLen = 0;
607 rv = CKR_FUNCTION_FAILED;
608 }
609
610 /* Cleanup memory space. */
611 free(soft_des_ctx->des_cbc);
612 freezero(soft_des_ctx->key_sched,
613 soft_des_ctx->keysched_len);
614
615 }
616
617 break;
618 }
619
620 case CKM_DES_CBC:
621 case CKM_DES_ECB:
622 case CKM_DES3_CBC:
623 case CKM_DES3_ECB:
624 {
625
626 soft_des_ctx_t *soft_des_ctx;
627
628 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
629 /*
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.
633 */
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;
640 }
641
642 /* Cleanup memory space. */
643 free(soft_des_ctx->des_cbc);
644 freezero(soft_des_ctx->key_sched,
645 soft_des_ctx->keysched_len);
646
647 break;
648 }
649
650 case CKM_AES_CBC_PAD:
651 {
652
653 soft_aes_ctx_t *soft_aes_ctx;
654
655 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
656
657 /*
658 * We should have only one block of data left in the
659 * remaining buffer.
660 */
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 freezero(soft_aes_ctx->key_sched,
667 soft_aes_ctx->keysched_len);
668
669 goto clean1;
670 }
671
672 out_len = AES_BLOCK_LEN;
673
674 /*
675 * If application asks for the length of the output buffer
676 * to hold the plaintext?
677 */
678 if (pLastPart == NULL) {
679 *pulLastPartLen = out_len;
680 rv = CKR_OK;
681 goto clean2;
682 } else {
683 crypto_data_t out;
684
685 /* Copy remaining data to the output buffer. */
686 (void) memcpy(pLastPart, soft_aes_ctx->data,
687 AES_BLOCK_LEN);
688
689 out.cd_format = CRYPTO_DATA_RAW;
690 out.cd_offset = 0;
691 out.cd_length = AES_BLOCK_LEN;
692 out.cd_raw.iov_base = (char *)pLastPart;
693 out.cd_raw.iov_len = AES_BLOCK_LEN;
694
695 /* Decrypt final block of data. */
696 rc = aes_decrypt_contiguous_blocks(
697 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
698 (char *)pLastPart, AES_BLOCK_LEN, &out);
699
700 if (rc == 0) {
701 /*
702 * Remove padding bytes after decryption of
703 * ciphertext block to produce the original
704 * plaintext.
705 */
706 rv = soft_remove_pkcs7_padding(pLastPart,
707 AES_BLOCK_LEN, &out_len);
708 if (rv != CKR_OK)
709 *pulLastPartLen = 0;
710 else
711 *pulLastPartLen = out_len;
712 } else {
713 *pulLastPartLen = 0;
714 rv = CKR_FUNCTION_FAILED;
715 }
716
717 /* Cleanup memory space. */
718 free(soft_aes_ctx->aes_cbc);
719 freezero(soft_aes_ctx->key_sched,
720 soft_aes_ctx->keysched_len);
721
722 }
723
724 break;
725 }
726
727 case CKM_AES_CBC:
728 case CKM_AES_ECB:
729 {
730 soft_aes_ctx_t *soft_aes_ctx;
731
732 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
733 /*
734 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
735 * so when the final is called, the remaining buffer
736 * should not contain any more data.
737 */
738 *pulLastPartLen = 0;
739 if (soft_aes_ctx->remain_len != 0) {
740 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
741 } else {
742 if (pLastPart == NULL)
743 goto clean2;
744 }
745
746 /* Cleanup memory space. */
747 free(soft_aes_ctx->aes_cbc);
748 freezero(soft_aes_ctx->key_sched,
749 soft_aes_ctx->keysched_len);
750
751 break;
752 }
753 case CKM_AES_CTR:
754 {
755 crypto_data_t out;
756 soft_aes_ctx_t *soft_aes_ctx;
757 ctr_ctx_t *ctr_ctx;
758 size_t len;
759
760 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
761 ctr_ctx = soft_aes_ctx->aes_cbc;
762 len = ctr_ctx->ctr_remainder_len;
763 if (pLastPart == NULL) {
764 *pulLastPartLen = len;
765 goto clean1;
766 }
767 if (len > 0) {
768 out.cd_format = CRYPTO_DATA_RAW;
769 out.cd_offset = 0;
770 out.cd_length = len;
771 out.cd_raw.iov_base = (char *)pLastPart;
772 out.cd_raw.iov_len = len;
773
774 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
775 if (rv == CRYPTO_DATA_LEN_RANGE)
776 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
777 }
778 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
779 *pulLastPartLen = len;
780 goto clean1;
781 }
782
783 /* Cleanup memory space. */
784 free(ctr_ctx);
785 freezero(soft_aes_ctx->key_sched,
786 soft_aes_ctx->keysched_len);
787
788 break;
789 }
790 case CKM_BLOWFISH_CBC:
791 {
792 soft_blowfish_ctx_t *soft_blowfish_ctx;
793
794 soft_blowfish_ctx =
795 (soft_blowfish_ctx_t *)session_p->decrypt.context;
796
797 *pulLastPartLen = 0;
798 if (soft_blowfish_ctx->remain_len != 0)
799 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
800 else {
801 if (pLastPart == NULL)
802 goto clean2;
803 }
804
805 free(soft_blowfish_ctx->blowfish_cbc);
806 freezero(soft_blowfish_ctx->key_sched,
807 soft_blowfish_ctx->keysched_len);
808
809 break;
810 }
811
812 case CKM_RC4:
813 {
814 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
815 explicit_bzero(key, sizeof (*key));
816 *pulLastPartLen = 0;
817 break;
818 }
819
820 default:
821 /* PKCS11: The mechanism only supports single-part operation. */
822 rv = CKR_MECHANISM_INVALID;
823 break;
824 }
825
826 clean1:
827 free(session_p->decrypt.context);
828 session_p->decrypt.context = NULL;
829
830 clean2:
831 (void) pthread_mutex_unlock(&session_p->session_mutex);
832
833 return (rv);
834
835 }