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 */
27
28 #include <pthread.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/types.h>
33 #include <security/cryptoki.h>
34 #include <modes/modes.h>
35 #include <arcfour.h>
36 #include "softSession.h"
37 #include "softObject.h"
38 #include "softOps.h"
39 #include "softCrypt.h"
40 #include "softRSA.h"
41
42 /*
43 * Add padding bytes with the value of length of padding.
44 */
45 void
46 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
47 {
48 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
49 }
50
51 /*
52 * Perform encrypt init operation internally for the support of
53 * CKM_AES and CKM_DES MAC operations.
54 *
55 * This function is called with the session being held, and without
56 * its mutex taken.
57 */
58 CK_RV
59 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
60 pMechanism, soft_object_t *key_p)
61 {
62 CK_RV rv;
63
64 (void) pthread_mutex_lock(&session_p->session_mutex);
65
66 /* Check to see if encrypt operation is already active */
67 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
68 (void) pthread_mutex_unlock(&session_p->session_mutex);
69 return (CKR_OPERATION_ACTIVE);
70 }
71
72 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
73
74 (void) pthread_mutex_unlock(&session_p->session_mutex);
75
76 rv = soft_encrypt_init(session_p, pMechanism, key_p);
77
78 if (rv != CKR_OK) {
79 (void) pthread_mutex_lock(&session_p->session_mutex);
80 session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
81 (void) pthread_mutex_unlock(&session_p->session_mutex);
82 }
83
84 return (rv);
85 }
86
87 /*
88 * soft_encrypt_init()
89 *
90 * Arguments:
91 * session_p: pointer to soft_session_t struct
92 * pMechanism: pointer to CK_MECHANISM struct provided by application
93 * key_p: pointer to key soft_object_t struct
94 *
95 * Description:
96 * called by C_EncryptInit(). This function calls the corresponding
97 * encrypt init routine based on the mechanism.
98 *
99 * Returns:
100 * CKR_OK: success
101 * CKR_HOST_MEMORY: run out of system memory
102 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
103 * CKR_MECHANISM_INVALID: invalid mechanism type
104 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
105 * with the specified mechanism
106 */
107 CK_RV
108 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
109 soft_object_t *key_p)
110 {
111
112 CK_RV rv;
113
114 switch (pMechanism->mechanism) {
115
116 case CKM_DES_ECB:
117
118 if (key_p->key_type != CKK_DES) {
119 return (CKR_KEY_TYPE_INCONSISTENT);
120 }
121 goto ecb_common;
122
123 case CKM_DES3_ECB:
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 ecb_common:
131 return (soft_des_crypt_init_common(session_p, pMechanism,
132 key_p, B_TRUE));
133
134 case CKM_DES_CBC:
135 case CKM_DES_CBC_PAD:
136
137 if (key_p->key_type != CKK_DES) {
138 return (CKR_KEY_TYPE_INCONSISTENT);
139 }
140
141 goto cbc_common;
142
143 case CKM_DES3_CBC:
144 case CKM_DES3_CBC_PAD:
145 {
146
147 soft_des_ctx_t *soft_des_ctx;
148
149 if ((key_p->key_type != CKK_DES2) &&
150 (key_p->key_type != CKK_DES3)) {
151 return (CKR_KEY_TYPE_INCONSISTENT);
152 }
153
154 cbc_common:
155 if ((pMechanism->pParameter == NULL) ||
156 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
157 return (CKR_MECHANISM_PARAM_INVALID);
158 }
159
160 rv = soft_des_crypt_init_common(session_p, pMechanism,
161 key_p, B_TRUE);
162
163 if (rv != CKR_OK)
164 return (rv);
165
166 (void) pthread_mutex_lock(&session_p->session_mutex);
167
168 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
169 /* Copy Initialization Vector (IV) into the context. */
170 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
171 DES_BLOCK_LEN);
172
173 /* Allocate a context for DES cipher-block chaining. */
174 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
175 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
176 soft_des_ctx->ivec, key_p->key_type);
177
178 if (soft_des_ctx->des_cbc == NULL) {
179 freezero(soft_des_ctx->key_sched,
180 soft_des_ctx->keysched_len);
181 freezero(session_p->encrypt.context,
182 sizeof (soft_des_ctx_t));
183 session_p->encrypt.context = NULL;
184 rv = CKR_HOST_MEMORY;
185 }
186
187 (void) pthread_mutex_unlock(&session_p->session_mutex);
188
189 return (rv);
190 }
191 case CKM_AES_ECB:
192
193 if (key_p->key_type != CKK_AES) {
194 return (CKR_KEY_TYPE_INCONSISTENT);
195 }
196
197 return (soft_aes_crypt_init_common(session_p, pMechanism,
198 key_p, B_TRUE));
199
200 case CKM_AES_CBC:
201 case CKM_AES_CBC_PAD:
202 if ((pMechanism->pParameter == NULL) ||
203 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
204 return (CKR_MECHANISM_PARAM_INVALID);
205 }
206 /* FALLTHRU */
207 case CKM_AES_CMAC:
208 {
209 soft_aes_ctx_t *soft_aes_ctx;
210
211 if (key_p->key_type != CKK_AES) {
212 return (CKR_KEY_TYPE_INCONSISTENT);
213 }
214
215
216 rv = soft_aes_crypt_init_common(session_p, pMechanism,
217 key_p, B_TRUE);
218
219 if (rv != CKR_OK)
220 return (rv);
221
222 (void) pthread_mutex_lock(&session_p->session_mutex);
223
224 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
225 /* Copy Initialization Vector (IV) into the context. */
226 if (pMechanism->mechanism == CKM_AES_CMAC) {
227 (void) bzero(soft_aes_ctx->ivec, AES_BLOCK_LEN);
228 /* Allocate a context for AES cipher-block chaining. */
229 soft_aes_ctx->aes_cbc = (void *)aes_cmac_ctx_init(
230 soft_aes_ctx->key_sched,
231 soft_aes_ctx->keysched_len);
232 } else {
233 (void) memcpy(soft_aes_ctx->ivec,
234 pMechanism->pParameter,
235 AES_BLOCK_LEN);
236 /* Allocate a context for AES cipher-block chaining. */
237 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
238 soft_aes_ctx->key_sched,
239 soft_aes_ctx->keysched_len,
240 soft_aes_ctx->ivec);
241 }
242 if (soft_aes_ctx->aes_cbc == NULL) {
243 freezero(soft_aes_ctx->key_sched,
244 soft_aes_ctx->keysched_len);
245 freezero(session_p->encrypt.context,
246 sizeof (soft_aes_ctx_t));
247 session_p->encrypt.context = NULL;
248 rv = CKR_HOST_MEMORY;
249 }
250
251 (void) pthread_mutex_unlock(&session_p->session_mutex);
252
253 return (rv);
254 }
255 case CKM_AES_CTR:
256 {
257 soft_aes_ctx_t *soft_aes_ctx;
258
259 if (key_p->key_type != CKK_AES) {
260 return (CKR_KEY_TYPE_INCONSISTENT);
261 }
262
263 if (pMechanism->pParameter == NULL ||
264 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
265 return (CKR_MECHANISM_PARAM_INVALID);
266 }
267
268 rv = soft_aes_crypt_init_common(session_p, pMechanism,
269 key_p, B_TRUE);
270
271 if (rv != CKR_OK)
272 return (rv);
273
274 (void) pthread_mutex_lock(&session_p->session_mutex);
275
276 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
277 soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
278 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
279 pMechanism->pParameter);
280
281 if (soft_aes_ctx->aes_cbc == NULL) {
282 freezero(soft_aes_ctx->key_sched,
283 soft_aes_ctx->keysched_len);
284 freezero(session_p->encrypt.context,
285 sizeof (soft_aes_ctx_t));
286 session_p->encrypt.context = NULL;
287 rv = CKR_HOST_MEMORY;
288 }
289
290 (void) pthread_mutex_unlock(&session_p->session_mutex);
291
292 return (rv);
293 }
294 case CKM_RC4:
295
296 if (key_p->key_type != CKK_RC4) {
297 return (CKR_KEY_TYPE_INCONSISTENT);
298 }
299
300 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
301 B_TRUE));
302
303 case CKM_RSA_X_509:
304 case CKM_RSA_PKCS:
305
306 if (key_p->key_type != CKK_RSA) {
307 return (CKR_KEY_TYPE_INCONSISTENT);
308 }
309
310 return (soft_rsa_crypt_init_common(session_p, pMechanism,
311 key_p, B_TRUE));
312
313 case CKM_BLOWFISH_CBC:
314 {
315 soft_blowfish_ctx_t *soft_blowfish_ctx;
316
317 if (key_p->key_type != CKK_BLOWFISH)
318 return (CKR_KEY_TYPE_INCONSISTENT);
319
320 if ((pMechanism->pParameter == NULL) ||
321 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
322 return (CKR_MECHANISM_PARAM_INVALID);
323
324 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
325 key_p, B_TRUE);
326
327 if (rv != CKR_OK)
328 return (rv);
329
330 (void) pthread_mutex_lock(&session_p->session_mutex);
331
332 soft_blowfish_ctx =
333 (soft_blowfish_ctx_t *)session_p->encrypt.context;
334 /* Copy Initialization Vector (IV) into the context. */
335 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
336 BLOWFISH_BLOCK_LEN);
337
338 /* Allocate a context for Blowfish cipher-block chaining */
339 soft_blowfish_ctx->blowfish_cbc =
340 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
341 soft_blowfish_ctx->keysched_len,
342 soft_blowfish_ctx->ivec);
343
344 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
345 freezero(soft_blowfish_ctx->key_sched,
346 soft_blowfish_ctx->keysched_len);
347 freezero(session_p->encrypt.context,
348 sizeof (soft_blowfish_ctx_t));
349 session_p->encrypt.context = NULL;
350 rv = CKR_HOST_MEMORY;
351 }
352
353 (void) pthread_mutex_unlock(&session_p->session_mutex);
354
355 return (rv);
356 }
357 default:
358 return (CKR_MECHANISM_INVALID);
359 }
360 }
361
362
363 /*
364 * soft_encrypt_common()
365 *
366 * Arguments:
367 * session_p: pointer to soft_session_t struct
368 * pData: pointer to the input data to be encrypted
369 * ulDataLen: length of the input data
370 * pEncrypted: pointer to the output data after encryption
371 * pulEncryptedLen: pointer to the length of the output data
372 * update: boolean flag indicates caller is soft_encrypt
373 * or soft_encrypt_update
374 *
375 * Description:
376 * This function calls the corresponding encrypt routine based
377 * on the mechanism.
378 *
379 * Returns:
380 * see corresponding encrypt routine.
381 */
382 CK_RV
383 soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
384 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
385 CK_ULONG_PTR pulEncryptedLen, boolean_t update)
386 {
387
388 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
389
390 switch (mechanism) {
391
392 case CKM_DES_ECB:
393 case CKM_DES_CBC:
394 case CKM_DES3_ECB:
395 case CKM_DES3_CBC:
396
397 if (ulDataLen == 0) {
398 *pulEncryptedLen = 0;
399 return (CKR_OK);
400 }
401 /* FALLTHROUGH */
402
403 case CKM_DES_CBC_PAD:
404 case CKM_DES3_CBC_PAD:
405
406 return (soft_des_encrypt_common(session_p, pData,
407 ulDataLen, pEncrypted, pulEncryptedLen, update));
408
409 case CKM_AES_ECB:
410 case CKM_AES_CBC:
411 case CKM_AES_CTR:
412
413 if (ulDataLen == 0) {
414 *pulEncryptedLen = 0;
415 return (CKR_OK);
416 }
417 /* FALLTHROUGH */
418
419 case CKM_AES_CMAC:
420 case CKM_AES_CBC_PAD:
421
422 return (soft_aes_encrypt_common(session_p, pData,
423 ulDataLen, pEncrypted, pulEncryptedLen, update));
424
425 case CKM_BLOWFISH_CBC:
426
427 if (ulDataLen == 0) {
428 *pulEncryptedLen = 0;
429 return (CKR_OK);
430 }
431
432 return (soft_blowfish_encrypt_common(session_p, pData,
433 ulDataLen, pEncrypted, pulEncryptedLen, update));
434
435 case CKM_RC4:
436
437 if (ulDataLen == 0) {
438 *pulEncryptedLen = 0;
439 return (CKR_OK);
440 }
441
442 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
443 ulDataLen, pEncrypted, pulEncryptedLen));
444
445 case CKM_RSA_X_509:
446 case CKM_RSA_PKCS:
447
448 return (soft_rsa_encrypt_common(session_p, pData,
449 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
450
451 default:
452 return (CKR_MECHANISM_INVALID);
453 }
454 }
455
456
457 /*
458 * soft_encrypt()
459 *
460 * Arguments:
461 * session_p: pointer to soft_session_t struct
462 * pData: pointer to the input data to be encrypted
463 * ulDataLen: length of the input data
464 * pEncryptedData: pointer to the output data after encryption
465 * pulEncryptedDataLen: pointer to the length of the output data
466 *
467 * Description:
468 * called by C_Encrypt(). This function calls the soft_encrypt_common
469 * routine.
470 *
471 * Returns:
472 * see soft_encrypt_common().
473 */
474 CK_RV
475 soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
476 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
477 CK_ULONG_PTR pulEncryptedDataLen)
478 {
479
480 return (soft_encrypt_common(session_p, pData, ulDataLen,
481 pEncryptedData, pulEncryptedDataLen, B_FALSE));
482 }
483
484
485 /*
486 * soft_encrypt_update()
487 *
488 * Arguments:
489 * session_p: pointer to soft_session_t struct
490 * pPart: pointer to the input data to be digested
491 * ulPartLen: length of the input data
492 * pEncryptedPart: pointer to the ciphertext
493 * pulEncryptedPartLen: pointer to the length of the ciphertext
494 *
495 * Description:
496 * called by C_EncryptUpdate(). This function calls the
497 * soft_encrypt_common routine (with update flag on).
498 *
499 * Returns:
500 * see soft_encrypt_common().
501 */
502 CK_RV
503 soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
504 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
505 CK_ULONG_PTR pulEncryptedPartLen)
506 {
507
508 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
509
510 switch (mechanism) {
511
512 case CKM_DES_ECB:
513 case CKM_DES_CBC:
514 case CKM_DES_CBC_PAD:
515 case CKM_DES3_ECB:
516 case CKM_DES3_CBC:
517 case CKM_DES3_CBC_PAD:
518 case CKM_AES_ECB:
519 case CKM_AES_CBC:
520 case CKM_AES_CBC_PAD:
521 case CKM_AES_CMAC:
522 case CKM_AES_CTR:
523 case CKM_BLOWFISH_CBC:
524 case CKM_RC4:
525
526 return (soft_encrypt_common(session_p, pPart, ulPartLen,
527 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
528
529 default:
530 /* PKCS11: The mechanism only supports single-part operation. */
531 return (CKR_MECHANISM_INVALID);
532 }
533 }
534
535
536 /*
537 * soft_encrypt_final()
538 *
539 * Arguments:
540 * session_p: pointer to soft_session_t struct
541 * pLastEncryptedPart: pointer to the last encrypted data part
542 * pulLastEncryptedPartLen: pointer to the length of the last
543 * encrypted data part
544 *
545 * Description:
546 * called by C_EncryptFinal().
547 *
548 * Returns:
549 * CKR_OK: success
550 * CKR_FUNCTION_FAILED: encrypt final function failed
551 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
552 */
553 CK_RV
554 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
555 CK_ULONG_PTR pulLastEncryptedPartLen)
556 {
557
558 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
559 CK_ULONG out_len;
560 CK_RV rv = CKR_OK;
561 int rc;
562
563 (void) pthread_mutex_lock(&session_p->session_mutex);
564
565 if (session_p->encrypt.context == NULL) {
566 rv = CKR_OPERATION_NOT_INITIALIZED;
567 *pulLastEncryptedPartLen = 0;
568 goto clean1;
569 }
570 switch (mechanism) {
571
572 case CKM_DES_CBC_PAD:
573 case CKM_DES3_CBC_PAD:
574 {
575 soft_des_ctx_t *soft_des_ctx;
576
577 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
578 /*
579 * For CKM_DES_CBC_PAD, compute output length with
580 * padding. If the remaining buffer has one block
581 * of data, then output length will be two blocksize of
582 * ciphertext. If the remaining buffer has less than
583 * one block of data, then output length will be
584 * one blocksize.
585 */
586 if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
587 out_len = 2 * DES_BLOCK_LEN;
588 else
589 out_len = DES_BLOCK_LEN;
590
591 if (pLastEncryptedPart == NULL) {
592 /*
593 * Application asks for the length of the output
594 * buffer to hold the ciphertext.
595 */
596 *pulLastEncryptedPartLen = out_len;
597 goto clean1;
598 } else {
599 crypto_data_t out;
600
601 /* Copy remaining data to the output buffer. */
602 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
603 soft_des_ctx->remain_len);
604
605 /*
606 * Add padding bytes prior to encrypt final.
607 */
608 soft_add_pkcs7_padding(pLastEncryptedPart +
609 soft_des_ctx->remain_len, DES_BLOCK_LEN,
610 soft_des_ctx->remain_len);
611
612 out.cd_format = CRYPTO_DATA_RAW;
613 out.cd_offset = 0;
614 out.cd_length = out_len;
615 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
616 out.cd_raw.iov_len = out_len;
617
618 /* Encrypt multiple blocks of data. */
619 rc = des_encrypt_contiguous_blocks(
620 (des_ctx_t *)soft_des_ctx->des_cbc,
621 (char *)pLastEncryptedPart, out_len, &out);
622
623 if (rc == 0) {
624 *pulLastEncryptedPartLen = out_len;
625 } else {
626 *pulLastEncryptedPartLen = 0;
627 rv = CKR_FUNCTION_FAILED;
628 }
629
630 /* Cleanup memory space. */
631 free(soft_des_ctx->des_cbc);
632 freezero(soft_des_ctx->key_sched,
633 soft_des_ctx->keysched_len);
634 }
635
636 break;
637 }
638 case CKM_DES_CBC:
639 case CKM_DES_ECB:
640 case CKM_DES3_CBC:
641 case CKM_DES3_ECB:
642 {
643
644 soft_des_ctx_t *soft_des_ctx;
645
646 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
647 /*
648 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
649 * so when the final is called, the remaining buffer
650 * should not contain any more data.
651 */
652 *pulLastEncryptedPartLen = 0;
653 if (soft_des_ctx->remain_len != 0) {
654 rv = CKR_DATA_LEN_RANGE;
655 } else {
656 if (pLastEncryptedPart == NULL)
657 goto clean1;
658 }
659
660 /* Cleanup memory space. */
661 free(soft_des_ctx->des_cbc);
662 freezero(soft_des_ctx->key_sched,
663 soft_des_ctx->keysched_len);
664
665 break;
666 }
667 case CKM_AES_CBC_PAD:
668 {
669 soft_aes_ctx_t *soft_aes_ctx;
670
671 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
672 /*
673 * For CKM_AES_CBC_PAD, compute output length with
674 * padding. If the remaining buffer has one block
675 * of data, then output length will be two blocksize of
676 * ciphertext. If the remaining buffer has less than
677 * one block of data, then output length will be
678 * one blocksize.
679 */
680 if (soft_aes_ctx->remain_len == AES_BLOCK_LEN)
681 out_len = 2 * AES_BLOCK_LEN;
682 else
683 out_len = AES_BLOCK_LEN;
684
685 if (pLastEncryptedPart == NULL) {
686 /*
687 * Application asks for the length of the output
688 * buffer to hold the ciphertext.
689 */
690 *pulLastEncryptedPartLen = out_len;
691 goto clean1;
692 } else {
693 crypto_data_t out;
694
695 /* Copy remaining data to the output buffer. */
696 (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
697 soft_aes_ctx->remain_len);
698
699 /*
700 * Add padding bytes prior to encrypt final.
701 */
702 soft_add_pkcs7_padding(pLastEncryptedPart +
703 soft_aes_ctx->remain_len, AES_BLOCK_LEN,
704 soft_aes_ctx->remain_len);
705
706 out.cd_format = CRYPTO_DATA_RAW;
707 out.cd_offset = 0;
708 out.cd_length = out_len;
709 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
710 out.cd_raw.iov_len = out_len;
711
712 /* Encrypt multiple blocks of data. */
713 rc = aes_encrypt_contiguous_blocks(
714 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
715 (char *)pLastEncryptedPart, out_len, &out);
716
717 if (rc == 0) {
718 *pulLastEncryptedPartLen = out_len;
719 } else {
720 *pulLastEncryptedPartLen = 0;
721 rv = CKR_FUNCTION_FAILED;
722 }
723
724 /* Cleanup memory space. */
725 free(soft_aes_ctx->aes_cbc);
726 freezero(soft_aes_ctx->key_sched,
727 soft_aes_ctx->keysched_len);
728 }
729
730 break;
731 }
732 case CKM_AES_CMAC:
733 {
734 soft_aes_ctx_t *soft_aes_ctx;
735 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
736
737 if (pLastEncryptedPart == NULL) {
738 /*
739 * Application asks for the length of the output
740 * buffer to hold the ciphertext.
741 */
742 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
743 goto clean1;
744 } else {
745 crypto_data_t out;
746
747 out.cd_format = CRYPTO_DATA_RAW;
748 out.cd_offset = 0;
749 out.cd_length = AES_BLOCK_LEN;
750 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
751 out.cd_raw.iov_len = AES_BLOCK_LEN;
752
753 rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out,
754 aes_encrypt_block, aes_xor_block);
755
756 if (rc == 0) {
757 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
758 } else {
759 *pulLastEncryptedPartLen = 0;
760 rv = CKR_FUNCTION_FAILED;
761 }
762
763 /* Cleanup memory space. */
764 free(soft_aes_ctx->aes_cbc);
765 freezero(soft_aes_ctx->key_sched,
766 soft_aes_ctx->keysched_len);
767 }
768
769 break;
770 }
771 case CKM_AES_CBC:
772 case CKM_AES_ECB:
773 {
774 soft_aes_ctx_t *soft_aes_ctx;
775
776 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
777 /*
778 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
779 * so when the final is called, the remaining buffer
780 * should not contain any more data.
781 */
782 *pulLastEncryptedPartLen = 0;
783 if (soft_aes_ctx->remain_len != 0) {
784 rv = CKR_DATA_LEN_RANGE;
785 } else {
786 if (pLastEncryptedPart == NULL)
787 goto clean1;
788 }
789
790 /* Cleanup memory space. */
791 free(soft_aes_ctx->aes_cbc);
792 freezero(soft_aes_ctx->key_sched,
793 soft_aes_ctx->keysched_len);
794
795 break;
796 }
797 case CKM_AES_CTR:
798 {
799 crypto_data_t out;
800 soft_aes_ctx_t *soft_aes_ctx;
801 ctr_ctx_t *ctr_ctx;
802 size_t len;
803
804 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
805 ctr_ctx = soft_aes_ctx->aes_cbc;
806 len = ctr_ctx->ctr_remainder_len;
807
808 if (pLastEncryptedPart == NULL) {
809 *pulLastEncryptedPartLen = len;
810 goto clean1;
811 }
812 if (len > 0) {
813 out.cd_format = CRYPTO_DATA_RAW;
814 out.cd_offset = 0;
815 out.cd_length = len;
816 out.cd_raw.iov_base = (char *)pLastEncryptedPart;
817 out.cd_raw.iov_len = len;
818
819 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
820 }
821 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
822 *pulLastEncryptedPartLen = len;
823 goto clean1;
824 }
825
826 /* Cleanup memory space. */
827 free(ctr_ctx);
828 freezero(soft_aes_ctx->key_sched,
829 soft_aes_ctx->keysched_len);
830
831 break;
832 }
833 case CKM_BLOWFISH_CBC:
834 {
835 soft_blowfish_ctx_t *soft_blowfish_ctx;
836
837 soft_blowfish_ctx =
838 (soft_blowfish_ctx_t *)session_p->encrypt.context;
839 /*
840 * CKM_BLOWFISH_CBC does not do any padding, so when the
841 * final is called, the remaining buffer should not contain
842 * any more data
843 */
844 *pulLastEncryptedPartLen = 0;
845 if (soft_blowfish_ctx->remain_len != 0)
846 rv = CKR_DATA_LEN_RANGE;
847 else {
848 if (pLastEncryptedPart == NULL)
849 goto clean1;
850 }
851
852 free(soft_blowfish_ctx->blowfish_cbc);
853 freezero(soft_blowfish_ctx->key_sched,
854 soft_blowfish_ctx->keysched_len);
855 break;
856 }
857
858 case CKM_RC4:
859 {
860 ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
861 /* Remaining data size is always zero for RC4. */
862 *pulLastEncryptedPartLen = 0;
863 if (pLastEncryptedPart == NULL)
864 goto clean1;
865 explicit_bzero(key, sizeof (*key));
866 break;
867 }
868 default:
869 /* PKCS11: The mechanism only supports single-part operation. */
870 rv = CKR_MECHANISM_INVALID;
871 break;
872 }
873
874 free(session_p->encrypt.context);
875 session_p->encrypt.context = NULL;
876 clean1:
877 (void) pthread_mutex_unlock(&session_p->session_mutex);
878
879 return (rv);
880 }
881
882 /*
883 * This function frees the allocated active crypto context and the
884 * lower level of allocated struct as needed.
885 * This function is called by the 1st tier of encrypt/decrypt routines
886 * or by the 2nd tier of session close routine. Since the 1st tier
887 * caller will always call this function without locking the session
888 * mutex and the 2nd tier caller will call with the lock, we add the
889 * third parameter "lock_held" to distinguish this case.
890 */
891 void
892 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
893 boolean_t lock_held)
894 {
895
896 crypto_active_op_t *active_op;
897 boolean_t lock_true = B_TRUE;
898
899 if (!lock_held)
900 (void) pthread_mutex_lock(&session_p->session_mutex);
901
902 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
903
904 switch (active_op->mech.mechanism) {
905
906 case CKM_DES_CBC_PAD:
907 case CKM_DES3_CBC_PAD:
908 case CKM_DES_CBC:
909 case CKM_DES_ECB:
910 case CKM_DES3_CBC:
911 case CKM_DES3_ECB:
912 {
913
914 soft_des_ctx_t *soft_des_ctx =
915 (soft_des_ctx_t *)active_op->context;
916 des_ctx_t *des_ctx;
917
918 if (soft_des_ctx != NULL) {
919 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
920 if (des_ctx != NULL) {
921 explicit_bzero(des_ctx->dc_keysched,
922 des_ctx->dc_keysched_len);
923 free(soft_des_ctx->des_cbc);
924 }
925 freezero(soft_des_ctx->key_sched,
926 soft_des_ctx->keysched_len);
927 }
928 break;
929 }
930
931 case CKM_AES_CBC_PAD:
932 case CKM_AES_CBC:
933 case CKM_AES_CMAC:
934 case CKM_AES_ECB:
935 {
936 soft_aes_ctx_t *soft_aes_ctx =
937 (soft_aes_ctx_t *)active_op->context;
938 aes_ctx_t *aes_ctx;
939
940 if (soft_aes_ctx != NULL) {
941 aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
942 if (aes_ctx != NULL) {
943 explicit_bzero(aes_ctx->ac_keysched,
944 aes_ctx->ac_keysched_len);
945 free(soft_aes_ctx->aes_cbc);
946 }
947 freezero(soft_aes_ctx->key_sched,
948 soft_aes_ctx->keysched_len);
949 }
950 break;
951 }
952
953 case CKM_BLOWFISH_CBC:
954 {
955 soft_blowfish_ctx_t *soft_blowfish_ctx =
956 (soft_blowfish_ctx_t *)active_op->context;
957 blowfish_ctx_t *blowfish_ctx;
958
959 if (soft_blowfish_ctx != NULL) {
960 blowfish_ctx =
961 (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
962 if (blowfish_ctx != NULL) {
963 explicit_bzero(blowfish_ctx->bc_keysched,
964 blowfish_ctx->bc_keysched_len);
965 free(soft_blowfish_ctx->blowfish_cbc);
966 }
967
968 freezero(soft_blowfish_ctx->key_sched,
969 soft_blowfish_ctx->keysched_len);
970 }
971 break;
972 }
973
974 case CKM_RC4:
975 {
976 ARCFour_key *key = (ARCFour_key *)active_op->context;
977
978 if (key != NULL)
979 explicit_bzero(key, sizeof (*key));
980 break;
981 }
982
983 case CKM_RSA_X_509:
984 case CKM_RSA_PKCS:
985 {
986 soft_rsa_ctx_t *rsa_ctx =
987 (soft_rsa_ctx_t *)active_op->context;
988
989 if (rsa_ctx != NULL)
990 if (rsa_ctx->key != NULL) {
991 soft_cleanup_object(rsa_ctx->key);
992 free(rsa_ctx->key);
993 }
994
995 break;
996 }
997
998 } /* switch */
999
1000 if (active_op->context != NULL) {
1001 free(active_op->context);
1002 active_op->context = NULL;
1003 }
1004
1005 active_op->flags = 0;
1006
1007 if (!lock_held)
1008 SES_REFRELE(session_p, lock_true);
1009 }