4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
32 #include <sys/types.h>
33 #include <security/cryptoki.h>
35 #include "softSession.h"
36 #include "softObject.h"
37 #include "softCrypt.h"
41 * Allocate context for the active encryption or decryption operation, and
42 * generate AES key schedule to speed up the operation.
45 soft_aes_crypt_init_common(soft_session_t
*session_p
,
46 CK_MECHANISM_PTR pMechanism
, soft_object_t
*key_p
,
50 soft_aes_ctx_t
*soft_aes_ctx
;
52 soft_aes_ctx
= calloc(1, sizeof (soft_aes_ctx_t
));
53 if (soft_aes_ctx
== NULL
) {
54 return (CKR_HOST_MEMORY
);
57 soft_aes_ctx
->key_sched
= aes_alloc_keysched(&size
, 0);
59 if (soft_aes_ctx
->key_sched
== NULL
) {
61 return (CKR_HOST_MEMORY
);
64 soft_aes_ctx
->keysched_len
= size
;
66 (void) pthread_mutex_lock(&session_p
->session_mutex
);
68 /* Called by C_EncryptInit. */
69 session_p
->encrypt
.context
= soft_aes_ctx
;
70 session_p
->encrypt
.mech
.mechanism
= pMechanism
->mechanism
;
72 /* Called by C_DecryptInit. */
73 session_p
->decrypt
.context
= soft_aes_ctx
;
74 session_p
->decrypt
.mech
.mechanism
= pMechanism
->mechanism
;
76 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
79 * If this is a non-sensitive key and it does NOT have
80 * a key schedule yet, then allocate one and expand it.
81 * Otherwise, if it's a non-sensitive key, and it DOES have
82 * a key schedule already attached to it, just copy the
83 * pre-expanded schedule to the context and avoid the
84 * extra key schedule expansion operation.
86 if (!(key_p
->bool_attr_mask
& SENSITIVE_BOOL_ON
)) {
87 if (OBJ_KEY_SCHED(key_p
) == NULL
) {
90 (void) pthread_mutex_lock(&key_p
->object_mutex
);
91 if (OBJ_KEY_SCHED(key_p
) == NULL
) {
92 ks
= aes_alloc_keysched(&size
, 0);
94 (void) pthread_mutex_unlock(
95 &key_p
->object_mutex
);
97 return (CKR_HOST_MEMORY
);
101 aes_init_keysched(OBJ_SEC_VALUE(key_p
), (uint_t
)
102 (OBJ_SEC_VALUE_LEN(key_p
) * 8), ks
);
103 #else /* !__sparcv9 */
104 aes_init_keysched(OBJ_SEC_VALUE(key_p
),
105 (OBJ_SEC_VALUE_LEN(key_p
) * 8), ks
);
106 #endif /* __sparcv9 */
107 OBJ_KEY_SCHED_LEN(key_p
) = size
;
108 OBJ_KEY_SCHED(key_p
) = ks
;
110 (void) pthread_mutex_unlock(&key_p
->object_mutex
);
112 (void) memcpy(soft_aes_ctx
->key_sched
, OBJ_KEY_SCHED(key_p
),
113 OBJ_KEY_SCHED_LEN(key_p
));
114 soft_aes_ctx
->keysched_len
= OBJ_KEY_SCHED_LEN(key_p
);
117 * Initialize key schedule for AES. aes_init_keysched()
118 * requires key length in bits.
122 aes_init_keysched(OBJ_SEC_VALUE(key_p
), (uint_t
)
123 (OBJ_SEC_VALUE_LEN(key_p
) * 8), soft_aes_ctx
->key_sched
);
124 #else /* !__sparcv9 */
125 aes_init_keysched(OBJ_SEC_VALUE(key_p
),
126 (OBJ_SEC_VALUE_LEN(key_p
) * 8), soft_aes_ctx
->key_sched
);
127 #endif /* __sparcv9 */
134 * soft_aes_encrypt_common()
137 * session_p: pointer to soft_session_t struct
138 * pData: pointer to the input data to be encrypted
139 * ulDataLen: length of the input data
140 * pEncrypted: pointer to the output data after encryption
141 * pulEncryptedLen: pointer to the length of the output data
142 * update: boolean flag indicates caller is soft_encrypt
143 * or soft_encrypt_update
146 * This function calls the corresponding encrypt routine based
151 * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
153 * CKR_FUNCTION_FAILED: encrypt function failed
154 * CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize
157 soft_aes_encrypt_common(soft_session_t
*session_p
, CK_BYTE_PTR pData
,
158 CK_ULONG ulDataLen
, CK_BYTE_PTR pEncrypted
,
159 CK_ULONG_PTR pulEncryptedLen
, boolean_t update
)
164 soft_aes_ctx_t
*soft_aes_ctx
=
165 (soft_aes_ctx_t
*)session_p
->encrypt
.context
;
167 CK_MECHANISM_TYPE mechanism
= session_p
->encrypt
.mech
.mechanism
;
168 CK_BYTE
*in_buf
= NULL
;
169 CK_BYTE
*out_buf
= NULL
;
174 if (mechanism
== CKM_AES_CTR
)
178 * AES only takes input length that is a multiple of blocksize
179 * for C_Encrypt function with the mechanism CKM_AES_ECB or
182 * AES allows any input length for C_Encrypt function with the
183 * mechanism CKM_AES_CBC_PAD and for C_EncryptUpdate function.
185 if ((!update
) && (mechanism
!= CKM_AES_CBC_PAD
) &&
186 (mechanism
!= CKM_AES_CMAC
)) {
187 if ((ulDataLen
% AES_BLOCK_LEN
) != 0) {
188 rv
= CKR_DATA_LEN_RANGE
;
195 * Called by C_Encrypt
197 if (mechanism
== CKM_AES_CBC_PAD
) {
199 * For CKM_AES_CBC_PAD, compute output length to
200 * count for the padding. If the length of input
201 * data is a multiple of blocksize, then make output
202 * length to be the sum of the input length and
203 * one blocksize. Otherwise, output length will
204 * be rounded up to the next multiple of blocksize.
206 out_len
= AES_BLOCK_LEN
*
207 (ulDataLen
/ AES_BLOCK_LEN
+ 1);
208 } else if (mechanism
== CKM_AES_CMAC
) {
209 out_len
= AES_BLOCK_LEN
;
212 * For non-padding mode, the output length will
213 * be same as the input length.
219 * If application asks for the length of the output buffer
220 * to hold the ciphertext?
222 if (pEncrypted
== NULL
) {
223 *pulEncryptedLen
= out_len
;
227 /* Is the application-supplied buffer large enough? */
228 if (*pulEncryptedLen
< out_len
) {
229 *pulEncryptedLen
= out_len
;
230 return (CKR_BUFFER_TOO_SMALL
);
233 /* Encrypt pad bytes in a separate operation */
234 if (mechanism
== CKM_AES_CBC_PAD
) {
235 out_len
-= AES_BLOCK_LEN
;
239 out_buf
= pEncrypted
;
242 * Called by C_EncryptUpdate
244 * Add the lengths of last remaining data and current
245 * plaintext together to get the total input length.
247 total_len
= soft_aes_ctx
->remain_len
+ ulDataLen
;
250 * If the total input length is less than one blocksize,
251 * or if the total input length is just one blocksize and
252 * the mechanism is CKM_AES_CBC_PAD, we will need to delay
253 * encryption until when more data comes in next
254 * C_EncryptUpdate or when C_EncryptFinal is called.
256 out_buf
= pEncrypted
;
259 * We prefer to let the underlying implementation of CMAC handle
260 * the storing of extra bytes, and no data is output until
261 * *_final, so skip that part of the following validation.
263 if (mechanism
== CKM_AES_CMAC
) {
264 if (pEncrypted
== NULL
) {
265 *pulEncryptedLen
= ulDataLen
;
274 if ((total_len
< AES_BLOCK_LEN
) ||
275 ((mechanism
== CKM_AES_CBC_PAD
) &&
276 (total_len
== AES_BLOCK_LEN
))) {
277 if (pEncrypted
!= NULL
) {
279 * Save input data and its length in
280 * the remaining buffer of AES context.
282 (void) memcpy(soft_aes_ctx
->data
+
283 soft_aes_ctx
->remain_len
, pData
, ulDataLen
);
284 soft_aes_ctx
->remain_len
+= ulDataLen
;
287 /* Set encrypted data length to 0. */
288 *pulEncryptedLen
= 0;
292 /* Compute the length of remaing data. */
293 remain
= total_len
% AES_BLOCK_LEN
;
296 * Make sure that the output length is a multiple of
299 out_len
= total_len
- remain
;
302 * If application asks for the length of the output buffer
303 * to hold the ciphertext?
305 if (pEncrypted
== NULL
) {
306 *pulEncryptedLen
= out_len
;
310 /* Is the application-supplied buffer large enough? */
311 if (*pulEncryptedLen
< out_len
) {
312 *pulEncryptedLen
= out_len
;
313 return (CKR_BUFFER_TOO_SMALL
);
316 if (soft_aes_ctx
->remain_len
!= 0) {
318 * Copy last remaining data and current input data
319 * to the output buffer.
321 (void) memmove(pEncrypted
+ soft_aes_ctx
->remain_len
,
322 pData
, out_len
- soft_aes_ctx
->remain_len
);
323 (void) memcpy(pEncrypted
, soft_aes_ctx
->data
,
324 soft_aes_ctx
->remain_len
);
325 bzero(soft_aes_ctx
->data
, soft_aes_ctx
->remain_len
);
335 * Begin Encryption now.
346 for (i
= 0; i
< out_len
; i
+= AES_BLOCK_LEN
) {
347 tmp_inbuf
= &in_buf
[i
];
348 tmp_outbuf
= &out_buf
[i
];
349 /* Crunch one block of data for AES. */
350 (void) aes_encrypt_block(soft_aes_ctx
->key_sched
,
351 tmp_inbuf
, tmp_outbuf
);
356 * For encrypt update, if there is a remaining
357 * data, save it and its length in the context.
360 (void) memcpy(soft_aes_ctx
->data
, pData
+
361 (ulDataLen
- remain
), remain
);
362 soft_aes_ctx
->remain_len
= remain
;
365 *pulEncryptedLen
= out_len
;
374 case CKM_AES_CBC_PAD
:
378 out
.cd_format
= CRYPTO_DATA_RAW
;
380 out
.cd_length
= out_len
;
381 out
.cd_raw
.iov_base
= (char *)out_buf
;
382 out
.cd_raw
.iov_len
= out_len
;
384 /* Encrypt multiple blocks of data. */
385 rc
= aes_encrypt_contiguous_blocks(
386 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
387 (char *)in_buf
, out_len
, &out
);
394 * For encrypt update, if there is remaining data,
395 * save it and its length in the context.
398 (void) memcpy(soft_aes_ctx
->data
, pData
+
399 (ulDataLen
- remain
), remain
);
400 soft_aes_ctx
->remain_len
= remain
;
401 } else if (mechanism
== CKM_AES_CBC_PAD
) {
403 * Save the remainder of the input
404 * block in a temporary block because
405 * we dont want to overrun the buffer
406 * by tacking on pad bytes.
408 CK_BYTE tmpblock
[AES_BLOCK_LEN
];
409 (void) memcpy(tmpblock
, in_buf
+ out_len
,
410 ulDataLen
- out_len
);
411 soft_add_pkcs7_padding(tmpblock
+
412 (ulDataLen
- out_len
),
413 AES_BLOCK_LEN
, ulDataLen
- out_len
);
415 out
.cd_offset
= out_len
;
416 out
.cd_length
= AES_BLOCK_LEN
;
417 out
.cd_raw
.iov_base
= (char *)out_buf
;
418 out
.cd_raw
.iov_len
= out_len
+ AES_BLOCK_LEN
;
420 /* Encrypt last block containing pad bytes. */
421 rc
= aes_encrypt_contiguous_blocks(
422 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
423 (char *)tmpblock
, AES_BLOCK_LEN
, &out
);
425 out_len
+= AES_BLOCK_LEN
;
426 } else if (mechanism
== CKM_AES_CMAC
) {
427 out
.cd_length
= AES_BLOCK_LEN
;
428 out
.cd_raw
.iov_base
= (char *)out_buf
;
429 out
.cd_raw
.iov_len
= AES_BLOCK_LEN
;
431 rc
= cmac_mode_final(soft_aes_ctx
->aes_cbc
, &out
,
432 aes_encrypt_block
, aes_xor_block
);
436 *pulEncryptedLen
= out_len
;
440 *pulEncryptedLen
= 0;
441 rv
= CKR_FUNCTION_FAILED
;
448 out
.cd_format
= CRYPTO_DATA_RAW
;
450 out
.cd_length
= *pulEncryptedLen
;
451 out
.cd_raw
.iov_base
= (char *)pEncrypted
;
452 out
.cd_raw
.iov_len
= *pulEncryptedLen
;
454 rc
= aes_encrypt_contiguous_blocks(soft_aes_ctx
->aes_cbc
,
455 (char *)pData
, ulDataLen
, &out
);
458 *pulEncryptedLen
= 0;
459 rv
= CKR_FUNCTION_FAILED
;
463 * Since AES counter mode is a stream cipher, we call
464 * aes_counter_final() to pick up any remaining bytes.
465 * It is an internal function that does not destroy
466 * the context like *normal* final routines.
468 if (((aes_ctx_t
*)soft_aes_ctx
->aes_cbc
)->ac_remainder_len
> 0)
469 rc
= ctr_mode_final(soft_aes_ctx
->aes_cbc
, &out
,
473 * Even though success means we've encrypted all of the input,
474 * we should still behave like the other functions and return
475 * the encrypted length in pulEncryptedLen
477 *pulEncryptedLen
= ulDataLen
;
485 * The following code will be executed if the caller is
486 * soft_encrypt() or an error occurred. The encryption
487 * operation will be terminated so we need to do some cleanup.
490 (void) pthread_mutex_lock(&session_p
->session_mutex
);
491 aes_ctx
= (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
;
494 freezero(aes_ctx
, sizeof (ecb_ctx_t
));
498 case CKM_AES_CBC_PAD
:
499 freezero(aes_ctx
, sizeof (cbc_ctx_t
));
502 freezero(aes_ctx
, sizeof (ctr_ctx_t
));
505 freezero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
506 freezero(session_p
->encrypt
.context
, sizeof (soft_aes_ctx_t
));
507 session_p
->encrypt
.context
= NULL
;
508 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
515 * soft_aes_decrypt_common()
518 * session_p: pointer to soft_session_t struct
519 * pEncrypted: pointer to the input data to be decrypted
520 * ulEncryptedLen: length of the input data
521 * pData: pointer to the output data
522 * pulDataLen: pointer to the length of the output data
523 * Update: boolean flag indicates caller is soft_decrypt
524 * or soft_decrypt_update
527 * This function calls the corresponding decrypt routine based
532 * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
534 * CKR_ENCRYPTED_DATA_LEN_RANGE: the input data is not a multiple
536 * CKR_FUNCTION_FAILED: decrypt function failed
539 soft_aes_decrypt_common(soft_session_t
*session_p
, CK_BYTE_PTR pEncrypted
,
540 CK_ULONG ulEncryptedLen
, CK_BYTE_PTR pData
,
541 CK_ULONG_PTR pulDataLen
, boolean_t update
)
546 soft_aes_ctx_t
*soft_aes_ctx
=
547 (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
549 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
550 CK_BYTE
*in_buf
= NULL
;
551 CK_BYTE
*out_buf
= NULL
;
556 if (mechanism
== CKM_AES_CTR
)
560 * AES only takes input length that is a multiple of 16 bytes
561 * for C_Decrypt function with the mechanism CKM_AES_ECB,
562 * CKM_AES_CBC or CKM_AES_CBC_PAD.
564 * AES allows any input length for C_DecryptUpdate function.
568 * Called by C_Decrypt
570 if ((ulEncryptedLen
% AES_BLOCK_LEN
) != 0) {
571 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
576 * If application asks for the length of the output buffer
577 * to hold the plaintext?
580 *pulDataLen
= ulEncryptedLen
;
584 /* Is the application-supplied buffer large enough? */
585 if (mechanism
!= CKM_AES_CBC_PAD
) {
586 if (*pulDataLen
< ulEncryptedLen
) {
587 *pulDataLen
= ulEncryptedLen
;
588 return (CKR_BUFFER_TOO_SMALL
);
590 out_len
= ulEncryptedLen
;
593 * For CKM_AES_CBC_PAD, we don't know how
594 * many bytes for padding at this time, so
595 * we'd assume one block was padded.
597 if (*pulDataLen
< (ulEncryptedLen
- AES_BLOCK_LEN
)) {
598 *pulDataLen
= ulEncryptedLen
- AES_BLOCK_LEN
;
599 return (CKR_BUFFER_TOO_SMALL
);
601 out_len
= ulEncryptedLen
- AES_BLOCK_LEN
;
607 * Called by C_DecryptUpdate
609 * Add the lengths of last remaining data and current
610 * input data together to get the total input length.
612 total_len
= soft_aes_ctx
->remain_len
+ ulEncryptedLen
;
615 * If the total input length is less than one blocksize,
616 * or if the total input length is just one blocksize and
617 * the mechanism is CKM_AES_CBC_PAD, we will need to delay
618 * decryption until when more data comes in next
619 * C_DecryptUpdate or when C_DecryptFinal is called.
621 if ((total_len
< AES_BLOCK_LEN
) ||
622 ((mechanism
== CKM_AES_CBC_PAD
) &&
623 (total_len
== AES_BLOCK_LEN
))) {
626 * Save input data and its length in
627 * the remaining buffer of AES context.
629 (void) memcpy(soft_aes_ctx
->data
+
630 soft_aes_ctx
->remain_len
,
631 pEncrypted
, ulEncryptedLen
);
632 soft_aes_ctx
->remain_len
+= ulEncryptedLen
;
635 /* Set output data length to 0. */
640 /* Compute the length of remaing data. */
641 remain
= total_len
% AES_BLOCK_LEN
;
644 * Make sure that the output length is a multiple of
647 out_len
= total_len
- remain
;
649 if (mechanism
== CKM_AES_CBC_PAD
) {
651 * If the input data length is a multiple of
652 * blocksize, then save the last block of input
653 * data in the remaining buffer. C_DecryptFinal
654 * will handle this last block of data.
657 remain
= AES_BLOCK_LEN
;
658 out_len
-= AES_BLOCK_LEN
;
663 * If application asks for the length of the output buffer
664 * to hold the plaintext?
667 *pulDataLen
= out_len
;
672 * Is the application-supplied buffer large enough?
674 if (*pulDataLen
< out_len
) {
675 *pulDataLen
= out_len
;
676 return (CKR_BUFFER_TOO_SMALL
);
679 if (soft_aes_ctx
->remain_len
!= 0) {
681 * Copy last remaining data and current input data
682 * to the output buffer.
684 (void) memmove(pData
+ soft_aes_ctx
->remain_len
,
685 pEncrypted
, out_len
- soft_aes_ctx
->remain_len
);
686 (void) memcpy(pData
, soft_aes_ctx
->data
,
687 soft_aes_ctx
->remain_len
);
688 bzero(soft_aes_ctx
->data
, soft_aes_ctx
->remain_len
);
710 for (i
= 0; i
< out_len
; i
+= AES_BLOCK_LEN
) {
711 tmp_inbuf
= &in_buf
[i
];
712 tmp_outbuf
= &out_buf
[i
];
713 /* Crunch one block of data for AES. */
714 (void) aes_decrypt_block(soft_aes_ctx
->key_sched
,
715 tmp_inbuf
, tmp_outbuf
);
720 * For decrypt update, if there is a remaining
721 * data, save it and its length in the context.
724 (void) memcpy(soft_aes_ctx
->data
, pEncrypted
+
725 (ulEncryptedLen
- remain
), remain
);
726 soft_aes_ctx
->remain_len
= remain
;
729 *pulDataLen
= out_len
;
735 case CKM_AES_CBC_PAD
:
739 uint8_t last_block
[AES_BLOCK_LEN
];
741 out
.cd_format
= CRYPTO_DATA_RAW
;
743 out
.cd_length
= out_len
;
744 out
.cd_raw
.iov_base
= (char *)out_buf
;
745 out
.cd_raw
.iov_len
= out_len
;
747 /* Decrypt multiple blocks of data. */
748 rc
= aes_decrypt_contiguous_blocks(
749 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
750 (char *)in_buf
, out_len
, &out
);
755 if ((mechanism
== CKM_AES_CBC_PAD
) && (!update
)) {
756 /* Decrypt last block containing pad bytes. */
758 out
.cd_length
= AES_BLOCK_LEN
;
759 out
.cd_raw
.iov_base
= (char *)last_block
;
760 out
.cd_raw
.iov_len
= AES_BLOCK_LEN
;
762 /* Decrypt last block containing pad bytes. */
763 rc
= aes_decrypt_contiguous_blocks(
764 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
765 (char *)in_buf
+ out_len
, AES_BLOCK_LEN
, &out
);
771 * Remove padding bytes after decryption of
772 * ciphertext block to produce the original
775 rv
= soft_remove_pkcs7_padding(last_block
,
776 AES_BLOCK_LEN
, &rem_len
);
779 (void) memcpy(out_buf
+ out_len
,
780 last_block
, rem_len
);
781 *pulDataLen
= out_len
+ rem_len
;
787 *pulDataLen
= out_len
;
792 * For decrypt update, if there is remaining data,
793 * save it and its length in the context.
796 (void) memcpy(soft_aes_ctx
->data
, pEncrypted
+
797 (ulEncryptedLen
- remain
), remain
);
798 soft_aes_ctx
->remain_len
= remain
;
805 rv
= CKR_FUNCTION_FAILED
;
812 out
.cd_format
= CRYPTO_DATA_RAW
;
814 out
.cd_length
= *pulDataLen
;
815 out
.cd_raw
.iov_base
= (char *)pData
;
816 out
.cd_raw
.iov_len
= *pulDataLen
;
818 rc
= aes_decrypt_contiguous_blocks(soft_aes_ctx
->aes_cbc
,
819 (char *)pEncrypted
, ulEncryptedLen
, &out
);
823 rv
= CKR_FUNCTION_FAILED
;
828 * Since AES counter mode is a stream cipher, we call
829 * aes_counter_final() to pick up any remaining bytes.
830 * It is an internal function that does not destroy
831 * the context like *normal* final routines.
833 if (((aes_ctx_t
*)soft_aes_ctx
->aes_cbc
)->ac_remainder_len
835 rc
= ctr_mode_final(soft_aes_ctx
->aes_cbc
, &out
,
837 if (rc
== CRYPTO_DATA_LEN_RANGE
)
838 rc
= CRYPTO_ENCRYPTED_DATA_LEN_RANGE
;
842 * Even though success means we've decrypted all of the input,
843 * we should still behave like the other functions and return
844 * the decrypted length in pulDataLen
846 *pulDataLen
= ulEncryptedLen
;
855 * The following code will be executed if the caller is
856 * soft_decrypt() or an error occurred. The decryption
857 * operation will be terminated so we need to do some cleanup.
860 (void) pthread_mutex_lock(&session_p
->session_mutex
);
861 aes_ctx
= (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
;
863 freezero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
864 freezero(session_p
->decrypt
.context
, sizeof (soft_aes_ctx_t
));
865 session_p
->decrypt
.context
= NULL
;
866 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
873 * Allocate and initialize a context for AES CBC mode of operation.
876 aes_cbc_ctx_init(void *key_sched
, size_t size
, uint8_t *ivec
)
881 if ((cbc_ctx
= calloc(1, sizeof (cbc_ctx_t
))) == NULL
)
884 cbc_ctx
->cbc_keysched
= key_sched
;
885 cbc_ctx
->cbc_keysched_len
= size
;
887 (void) memcpy(&cbc_ctx
->cbc_iv
[0], ivec
, AES_BLOCK_LEN
);
889 cbc_ctx
->cbc_lastp
= (uint8_t *)cbc_ctx
->cbc_iv
;
890 cbc_ctx
->cbc_flags
|= CBC_MODE
;
891 cbc_ctx
->max_remain
= AES_BLOCK_LEN
;
897 aes_cmac_ctx_init(void *key_sched
, size_t size
)
902 if ((cbc_ctx
= calloc(1, sizeof (cbc_ctx_t
))) == NULL
)
905 cbc_ctx
->cbc_keysched
= key_sched
;
906 cbc_ctx
->cbc_keysched_len
= size
;
908 cbc_ctx
->cbc_lastp
= (uint8_t *)cbc_ctx
->cbc_iv
;
909 cbc_ctx
->cbc_flags
|= CMAC_MODE
;
910 cbc_ctx
->max_remain
= AES_BLOCK_LEN
+ 1;
916 * Allocate and initialize a context for AES CTR mode of operation.
919 aes_ctr_ctx_init(void *key_sched
, size_t size
, uint8_t *param
)
923 CK_AES_CTR_PARAMS
*pp
;
925 /* LINTED: pointer alignment */
926 pp
= (CK_AES_CTR_PARAMS
*)param
;
928 if ((ctr_ctx
= calloc(1, sizeof (ctr_ctx_t
))) == NULL
)
931 ctr_ctx
->ctr_keysched
= key_sched
;
932 ctr_ctx
->ctr_keysched_len
= size
;
934 if (ctr_init_ctx(ctr_ctx
, pp
->ulCounterBits
, pp
->cb
, aes_copy_block
)
944 * Allocate and initialize AES contexts for both signing and encrypting,
945 * saving both context pointers in the session struct. For general-length AES
946 * MAC, check the length in the parameter to see if it is in the right range.
949 soft_aes_sign_verify_init_common(soft_session_t
*session_p
,
950 CK_MECHANISM_PTR pMechanism
, soft_object_t
*key_p
, boolean_t sign_op
)
952 soft_aes_ctx_t
*soft_aes_ctx
;
953 CK_MECHANISM encrypt_mech
;
956 if (key_p
->key_type
!= CKK_AES
) {
957 return (CKR_KEY_TYPE_INCONSISTENT
);
960 /* allocate memory for the sign/verify context */
961 soft_aes_ctx
= malloc(sizeof (soft_aes_ctx_t
));
962 if (soft_aes_ctx
== NULL
) {
963 return (CKR_HOST_MEMORY
);
966 /* initialization vector is zero for AES CMAC */
967 bzero(soft_aes_ctx
->ivec
, AES_BLOCK_LEN
);
969 switch (pMechanism
->mechanism
) {
971 case CKM_AES_CMAC_GENERAL
:
973 if (pMechanism
->ulParameterLen
!=
974 sizeof (CK_MAC_GENERAL_PARAMS
)) {
976 return (CKR_MECHANISM_PARAM_INVALID
);
979 if (*(CK_MAC_GENERAL_PARAMS
*)pMechanism
->pParameter
>
982 return (CKR_MECHANISM_PARAM_INVALID
);
985 soft_aes_ctx
->mac_len
= *((CK_MAC_GENERAL_PARAMS_PTR
)
986 pMechanism
->pParameter
);
992 * For non-general AES MAC, output is always block size
994 if (pMechanism
->mechanism
== CKM_AES_CMAC
) {
995 soft_aes_ctx
->mac_len
= AES_BLOCK_LEN
;
998 /* allocate a context for AES encryption */
999 encrypt_mech
.mechanism
= CKM_AES_CMAC
;
1000 encrypt_mech
.pParameter
= (void *)soft_aes_ctx
->ivec
;
1001 encrypt_mech
.ulParameterLen
= AES_BLOCK_LEN
;
1002 rv
= soft_encrypt_init_internal(session_p
, &encrypt_mech
,
1009 (void) pthread_mutex_lock(&session_p
->session_mutex
);
1012 session_p
->sign
.context
= soft_aes_ctx
;
1013 session_p
->sign
.mech
.mechanism
= pMechanism
->mechanism
;
1015 session_p
->verify
.context
= soft_aes_ctx
;
1016 session_p
->verify
.mech
.mechanism
=
1017 pMechanism
->mechanism
;
1020 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
1028 * Called by soft_sign(), soft_sign_final(), soft_verify() or
1029 * soft_verify_final().
1032 soft_aes_sign_verify_common(soft_session_t
*session_p
, CK_BYTE_PTR pData
,
1033 CK_ULONG ulDataLen
, CK_BYTE_PTR pSigned
, CK_ULONG_PTR pulSignedLen
,
1034 boolean_t sign_op
, boolean_t Final
)
1036 soft_aes_ctx_t
*soft_aes_ctx_sign_verify
;
1038 CK_BYTE
*pEncrypted
= NULL
;
1039 CK_ULONG ulEncryptedLen
= AES_BLOCK_LEN
;
1040 CK_BYTE last_block
[AES_BLOCK_LEN
];
1043 soft_aes_ctx_sign_verify
=
1044 (soft_aes_ctx_t
*)session_p
->sign
.context
;
1046 if (soft_aes_ctx_sign_verify
->mac_len
== 0) {
1051 /* Application asks for the length of the output buffer. */
1052 if (pSigned
== NULL
) {
1053 *pulSignedLen
= soft_aes_ctx_sign_verify
->mac_len
;
1057 /* Is the application-supplied buffer large enough? */
1058 if (*pulSignedLen
< soft_aes_ctx_sign_verify
->mac_len
) {
1059 *pulSignedLen
= soft_aes_ctx_sign_verify
->mac_len
;
1060 return (CKR_BUFFER_TOO_SMALL
);
1063 soft_aes_ctx_sign_verify
=
1064 (soft_aes_ctx_t
*)session_p
->verify
.context
;
1068 rv
= soft_encrypt_final(session_p
, last_block
,
1071 rv
= soft_encrypt(session_p
, pData
, ulDataLen
,
1072 last_block
, &ulEncryptedLen
);
1076 *pulSignedLen
= soft_aes_ctx_sign_verify
->mac_len
;
1078 /* the leftmost mac_len bytes of last_block is our MAC */
1079 (void) memcpy(pSigned
, last_block
, *pulSignedLen
);
1084 (void) pthread_mutex_lock(&session_p
->session_mutex
);
1086 /* soft_encrypt_common() has freed the encrypt context */
1088 free(session_p
->sign
.context
);
1089 session_p
->sign
.context
= NULL
;
1091 free(session_p
->verify
.context
);
1092 session_p
->verify
.context
= NULL
;
1094 session_p
->encrypt
.flags
= 0;
1096 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
1106 * Called by soft_sign_update()
1109 soft_aes_mac_sign_verify_update(soft_session_t
*session_p
, CK_BYTE_PTR pPart
,
1112 CK_BYTE buf
[AES_BLOCK_LEN
];
1113 CK_ULONG ulEncryptedLen
= AES_BLOCK_LEN
;
1116 rv
= soft_encrypt_update(session_p
, pPart
, ulPartLen
,
1117 buf
, &ulEncryptedLen
);