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 */
25
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"
39
40 /*
41 * Add padding bytes with the value of length of padding.
42 */
43 void
soft_add_pkcs7_padding(CK_BYTE * buf,int block_size,CK_ULONG data_len)44 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
45 {
46 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
47 }
48
49 /*
50 * Perform encrypt init operation internally for the support of
51 * CKM_DES_MAC and CKM_DES_MAC_GENERAL
52 *
53 * This function is called with the session being held, and without
54 * its mutex taken.
55 */
56 CK_RV
soft_encrypt_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)57 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
58 pMechanism, soft_object_t *key_p)
59 {
60 CK_RV rv;
61
62 (void) pthread_mutex_lock(&session_p->session_mutex);
63
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);
68 }
69
70 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
71
72 (void) pthread_mutex_unlock(&session_p->session_mutex);
73
74 rv = soft_encrypt_init(session_p, pMechanism, key_p);
75
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);
80 }
81
82 return (rv);
83 }
84
85 /*
86 * soft_encrypt_init()
87 *
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
92 *
93 * Description:
94 * called by C_EncryptInit(). This function calls the corresponding
95 * encrypt init routine based on the mechanism.
96 *
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
104 */
105 CK_RV
soft_encrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)106 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
107 soft_object_t *key_p)
108 {
109
110 CK_RV rv;
111
112 switch (pMechanism->mechanism) {
113
114 case CKM_DES_ECB:
115
116 if (key_p->key_type != CKK_DES) {
117 return (CKR_KEY_TYPE_INCONSISTENT);
118 }
119 goto ecb_common;
120
121 case CKM_DES3_ECB:
122
123 if ((key_p->key_type != CKK_DES2) &&
124 (key_p->key_type != CKK_DES3)) {
125 return (CKR_KEY_TYPE_INCONSISTENT);
126 }
127
128 ecb_common:
129 return (soft_des_crypt_init_common(session_p, pMechanism,
130 key_p, B_TRUE));
131
132 case CKM_DES_CBC:
133 case CKM_DES_CBC_PAD:
134
135 if (key_p->key_type != CKK_DES) {
136 return (CKR_KEY_TYPE_INCONSISTENT);
137 }
138
139 goto cbc_common;
140
141 case CKM_DES3_CBC:
142 case CKM_DES3_CBC_PAD:
143 {
144
145 soft_des_ctx_t *soft_des_ctx;
146
147 if ((key_p->key_type != CKK_DES2) &&
148 (key_p->key_type != CKK_DES3)) {
149 return (CKR_KEY_TYPE_INCONSISTENT);
150 }
151
152 cbc_common:
153 if ((pMechanism->pParameter == NULL) ||
154 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
155 return (CKR_MECHANISM_PARAM_INVALID);
156 }
157
158 rv = soft_des_crypt_init_common(session_p, pMechanism,
159 key_p, B_TRUE);
160
161 if (rv != CKR_OK)
162 return (rv);
163
164 (void) pthread_mutex_lock(&session_p->session_mutex);
165
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);
170
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);
175
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;
183 }
184
185 (void) pthread_mutex_unlock(&session_p->session_mutex);
186
187 return (rv);
188 }
189 case CKM_AES_ECB:
190
191 if (key_p->key_type != CKK_AES) {
192 return (CKR_KEY_TYPE_INCONSISTENT);
193 }
194
195 return (soft_aes_crypt_init_common(session_p, pMechanism,
196 key_p, B_TRUE));
197
198 case CKM_AES_CBC:
199 case CKM_AES_CBC_PAD:
200 {
201 soft_aes_ctx_t *soft_aes_ctx;
202
203 if (key_p->key_type != CKK_AES) {
204 return (CKR_KEY_TYPE_INCONSISTENT);
205 }
206
207 if ((pMechanism->pParameter == NULL) ||
208 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
209 return (CKR_MECHANISM_PARAM_INVALID);
210 }
211
212 rv = soft_aes_crypt_init_common(session_p, pMechanism,
213 key_p, B_TRUE);
214
215 if (rv != CKR_OK)
216 return (rv);
217
218 (void) pthread_mutex_lock(&session_p->session_mutex);
219
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);
224
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);
229
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;
237 }
238
239 (void) pthread_mutex_unlock(&session_p->session_mutex);
240
241 return (rv);
242 }
243 case CKM_AES_CTR:
244 {
245 soft_aes_ctx_t *soft_aes_ctx;
246
247 if (key_p->key_type != CKK_AES) {
248 return (CKR_KEY_TYPE_INCONSISTENT);
249 }
250
251 if (pMechanism->pParameter == NULL ||
252 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
253 return (CKR_MECHANISM_PARAM_INVALID);
254 }
255
256 rv = soft_aes_crypt_init_common(session_p, pMechanism,
257 key_p, B_TRUE);
258
259 if (rv != CKR_OK)
260 return (rv);
261
262 (void) pthread_mutex_lock(&session_p->session_mutex);
263
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);
268
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;
276 }
277
278 (void) pthread_mutex_unlock(&session_p->session_mutex);
279
280 return (rv);
281 }
282 case CKM_RC4:
283
284 if (key_p->key_type != CKK_RC4) {
285 return (CKR_KEY_TYPE_INCONSISTENT);
286 }
287
288 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
289 B_TRUE));
290
291 case CKM_RSA_X_509:
292 case CKM_RSA_PKCS:
293
294 if (key_p->key_type != CKK_RSA) {
295 return (CKR_KEY_TYPE_INCONSISTENT);
296 }
297
298 return (soft_rsa_crypt_init_common(session_p, pMechanism,
299 key_p, B_TRUE));
300
301 case CKM_BLOWFISH_CBC:
302 {
303 soft_blowfish_ctx_t *soft_blowfish_ctx;
304
305 if (key_p->key_type != CKK_BLOWFISH)
306 return (CKR_KEY_TYPE_INCONSISTENT);
307
308 if ((pMechanism->pParameter == NULL) ||
309 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
310 return (CKR_MECHANISM_PARAM_INVALID);
311
312 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
313 key_p, B_TRUE);
314
315 if (rv != CKR_OK)
316 return (rv);
317
318 (void) pthread_mutex_lock(&session_p->session_mutex);
319
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);
325
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);
331
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;
339 }
340
341 (void) pthread_mutex_unlock(&session_p->session_mutex);
342
343 return (rv);
344 }
345 default:
346 return (CKR_MECHANISM_INVALID);
347 }
348 }
349
350
351 /*
352 * soft_encrypt_common()
353 *
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
362 *
363 * Description:
364 * This function calls the corresponding encrypt routine based
365 * on the mechanism.
366 *
367 * Returns:
368 * see corresponding encrypt routine.
369 */
370 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)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)
374 {
375
376 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
377
378 switch (mechanism) {
379
380 case CKM_DES_ECB:
381 case CKM_DES_CBC:
382 case CKM_DES3_ECB:
383 case CKM_DES3_CBC:
384
385 if (ulDataLen == 0) {
386 *pulEncryptedLen = 0;
387 return (CKR_OK);
388 }
389 /* FALLTHROUGH */
390
391 case CKM_DES_CBC_PAD:
392 case CKM_DES3_CBC_PAD:
393
394 return (soft_des_encrypt_common(session_p, pData,
395 ulDataLen, pEncrypted, pulEncryptedLen, update));
396
397 case CKM_AES_ECB:
398 case CKM_AES_CBC:
399 case CKM_AES_CTR:
400
401 if (ulDataLen == 0) {
402 *pulEncryptedLen = 0;
403 return (CKR_OK);
404 }
405 /* FALLTHROUGH */
406
407 case CKM_AES_CBC_PAD:
408
409 return (soft_aes_encrypt_common(session_p, pData,
410 ulDataLen, pEncrypted, pulEncryptedLen, update));
411
412 case CKM_BLOWFISH_CBC:
413
414 if (ulDataLen == 0) {
415 *pulEncryptedLen = 0;
416 return (CKR_OK);
417 }
418
419 return (soft_blowfish_encrypt_common(session_p, pData,
420 ulDataLen, pEncrypted, pulEncryptedLen, update));
421
422 case CKM_RC4:
423
424 if (ulDataLen == 0) {
425 *pulEncryptedLen = 0;
426 return (CKR_OK);
427 }
428
429 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
430 ulDataLen, pEncrypted, pulEncryptedLen));
431
432 case CKM_RSA_X_509:
433 case CKM_RSA_PKCS:
434
435 return (soft_rsa_encrypt_common(session_p, pData,
436 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
437
438 default:
439 return (CKR_MECHANISM_INVALID);
440 }
441 }
442
443
444 /*
445 * soft_encrypt()
446 *
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
453 *
454 * Description:
455 * called by C_Encrypt(). This function calls the soft_encrypt_common
456 * routine.
457 *
458 * Returns:
459 * see soft_encrypt_common().
460 */
461 CK_RV
soft_encrypt(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)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)
465 {
466
467 return (soft_encrypt_common(session_p, pData, ulDataLen,
468 pEncryptedData, pulEncryptedDataLen, B_FALSE));
469 }
470
471
472 /*
473 * soft_encrypt_update()
474 *
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
481 *
482 * Description:
483 * called by C_EncryptUpdate(). This function calls the
484 * soft_encrypt_common routine (with update flag on).
485 *
486 * Returns:
487 * see soft_encrypt_common().
488 */
489 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)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)
493 {
494
495 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
496
497 switch (mechanism) {
498
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:
511
512 return (soft_encrypt_common(session_p, pPart, ulPartLen,
513 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
514
515 default:
516 /* PKCS11: The mechanism only supports single-part operation. */
517 return (CKR_MECHANISM_INVALID);
518 }
519 }
520
521
522 /*
523 * soft_encrypt_final()
524 *
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
530 *
531 * Description:
532 * called by C_EncryptFinal().
533 *
534 * Returns:
535 * CKR_OK: success
536 * CKR_FUNCTION_FAILED: encrypt final function failed
537 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
538 */
539 CK_RV
soft_encrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)540 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
541 CK_ULONG_PTR pulLastEncryptedPartLen)
542 {
543
544 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
545 CK_ULONG out_len;
546 CK_RV rv = CKR_OK;
547 int rc;
548
549 (void) pthread_mutex_lock(&session_p->session_mutex);
550
551 if (session_p->encrypt.context == NULL) {
552 rv = CKR_OPERATION_NOT_INITIALIZED;
553 *pulLastEncryptedPartLen = 0;
554 goto clean1;
555 }
556 switch (mechanism) {
557
558 case CKM_DES_CBC_PAD:
559 case CKM_DES3_CBC_PAD:
560 {
561 soft_des_ctx_t *soft_des_ctx;
562
563 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
564 /*
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.
571 */
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;
576
577 if (pLastEncryptedPart == NULL) {
578 /*
579 * Application asks for the length of the output
580 * buffer to hold the ciphertext.
581 */
582 *pulLastEncryptedPartLen = out_len;
583 goto clean1;
584 } else {
585 crypto_data_t out;
586
587 /* Copy remaining data to the output buffer. */
588 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
589 soft_des_ctx->remain_len);
590
591 /*
592 * Add padding bytes prior to encrypt final.
593 */
594 soft_add_pkcs7_padding(pLastEncryptedPart +
595 soft_des_ctx->remain_len, DES_BLOCK_LEN,
596 soft_des_ctx->remain_len);
597
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;
603
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);
608
609 if (rc == 0) {
610 *pulLastEncryptedPartLen = out_len;
611 } else {
612 *pulLastEncryptedPartLen = 0;
613 rv = CKR_FUNCTION_FAILED;
614 }
615
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);
621 }
622
623 break;
624 }
625 case CKM_DES_CBC:
626 case CKM_DES_ECB:
627 case CKM_DES3_CBC:
628 case CKM_DES3_ECB:
629 {
630
631 soft_des_ctx_t *soft_des_ctx;
632
633 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
634 /*
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.
638 */
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;
645 }
646
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);
651
652 break;
653 }
654 case CKM_AES_CBC_PAD:
655 {
656 soft_aes_ctx_t *soft_aes_ctx;
657
658 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
659 /*
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.
666 */
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;
671
672 if (pLastEncryptedPart == NULL) {
673 /*
674 * Application asks for the length of the output
675 * buffer to hold the ciphertext.
676 */
677 *pulLastEncryptedPartLen = out_len;
678 goto clean1;
679 } else {
680 crypto_data_t out;
681
682 /* Copy remaining data to the output buffer. */
683 (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
684 soft_aes_ctx->remain_len);
685
686 /*
687 * Add padding bytes prior to encrypt final.
688 */
689 soft_add_pkcs7_padding(pLastEncryptedPart +
690 soft_aes_ctx->remain_len, AES_BLOCK_LEN,
691 soft_aes_ctx->remain_len);
692
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;
698
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);
703
704 if (rc == 0) {
705 *pulLastEncryptedPartLen = out_len;
706 } else {
707 *pulLastEncryptedPartLen = 0;
708 rv = CKR_FUNCTION_FAILED;
709 }
710
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);
716 }
717
718 break;
719 }
720 case CKM_AES_CBC:
721 case CKM_AES_ECB:
722 {
723 soft_aes_ctx_t *soft_aes_ctx;
724
725 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
726 /*
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.
730 */
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;
737 }
738
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);
743
744 break;
745 }
746 case CKM_AES_CTR:
747 {
748 crypto_data_t out;
749 soft_aes_ctx_t *soft_aes_ctx;
750 ctr_ctx_t *ctr_ctx;
751 size_t len;
752
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;
756
757 if (pLastEncryptedPart == NULL) {
758 *pulLastEncryptedPartLen = len;
759 goto clean1;
760 }
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;
767
768 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
769 }
770 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
771 *pulLastEncryptedPartLen = len;
772 goto clean1;
773 }
774
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);
779
780 break;
781 }
782 case CKM_BLOWFISH_CBC:
783 {
784 soft_blowfish_ctx_t *soft_blowfish_ctx;
785
786 soft_blowfish_ctx =
787 (soft_blowfish_ctx_t *)session_p->encrypt.context;
788 /*
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
792 */
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;
799 }
800
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;
806 }
807
808 case CKM_RC4:
809 {
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;
817 }
818 default:
819 /* PKCS11: The mechanism only supports single-part operation. */
820 rv = CKR_MECHANISM_INVALID;
821 break;
822 }
823
824 free(session_p->encrypt.context);
825 session_p->encrypt.context = NULL;
826 clean1:
827 (void) pthread_mutex_unlock(&session_p->session_mutex);
828
829 return (rv);
830 }
831
832 /*
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.
840 */
841 void
soft_crypt_cleanup(soft_session_t * session_p,boolean_t encrypt,boolean_t lock_held)842 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
843 boolean_t lock_held)
844 {
845
846 crypto_active_op_t *active_op;
847 boolean_t lock_true = B_TRUE;
848
849 if (!lock_held)
850 (void) pthread_mutex_lock(&session_p->session_mutex);
851
852 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
853
854 switch (active_op->mech.mechanism) {
855
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:
862 {
863
864 soft_des_ctx_t *soft_des_ctx =
865 (soft_des_ctx_t *)active_op->context;
866 des_ctx_t *des_ctx;
867
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);
874 }
875 bzero(soft_des_ctx->key_sched,
876 soft_des_ctx->keysched_len);
877 free(soft_des_ctx->key_sched);
878 }
879 break;
880 }
881
882 case CKM_AES_CBC_PAD:
883 case CKM_AES_CBC:
884 case CKM_AES_ECB:
885 {
886 soft_aes_ctx_t *soft_aes_ctx =
887 (soft_aes_ctx_t *)active_op->context;
888 aes_ctx_t *aes_ctx;
889
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);
896 }
897 bzero(soft_aes_ctx->key_sched,
898 soft_aes_ctx->keysched_len);
899 free(soft_aes_ctx->key_sched);
900 }
901 break;
902 }
903
904 case CKM_BLOWFISH_CBC:
905 {
906 soft_blowfish_ctx_t *soft_blowfish_ctx =
907 (soft_blowfish_ctx_t *)active_op->context;
908 blowfish_ctx_t *blowfish_ctx;
909
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);
917 }
918
919 bzero(soft_blowfish_ctx->key_sched,
920 soft_blowfish_ctx->keysched_len);
921 free(soft_blowfish_ctx->key_sched);
922 }
923 break;
924 }
925
926 case CKM_RC4:
927 {
928 ARCFour_key *key = (ARCFour_key *)active_op->context;
929
930 if (key != NULL)
931 bzero(key, sizeof (*key));
932 break;
933 }
934
935 case CKM_RSA_X_509:
936 case CKM_RSA_PKCS:
937 {
938 soft_rsa_ctx_t *rsa_ctx =
939 (soft_rsa_ctx_t *)active_op->context;
940
941 if (rsa_ctx != NULL)
942 if (rsa_ctx->key != NULL) {
943 soft_cleanup_object(rsa_ctx->key);
944 free(rsa_ctx->key);
945 }
946
947 break;
948 }
949
950 } /* switch */
951
952 if (active_op->context != NULL) {
953 free(active_op->context);
954 active_op->context = NULL;
955 }
956
957 active_op->flags = 0;
958
959 if (!lock_held)
960 SES_REFRELE(session_p, lock_true);
961 }
962