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 (c) 2018, Joyent, Inc.
31 #include <sys/types.h>
32 #include <security/cryptoki.h>
33 #include <modes/modes.h>
35 #include "softSession.h"
36 #include "softObject.h"
38 #include "softCrypt.h"
42 * Remove padding bytes.
45 soft_remove_pkcs7_padding(CK_BYTE
*pData
, CK_ULONG padded_len
,
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 */
57 *pulDataLen
= padded_len
;
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
71 * called by C_DecryptInit(). This function calls the corresponding
72 * decrypt init routine based on the mechanism.
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
83 soft_decrypt_init(soft_session_t
*session_p
, CK_MECHANISM_PTR pMechanism
,
89 switch (pMechanism
->mechanism
) {
93 if (key_p
->key_type
!= CKK_DES
) {
94 return (CKR_KEY_TYPE_INCONSISTENT
);
101 if ((key_p
->key_type
!= CKK_DES2
) &&
102 (key_p
->key_type
!= CKK_DES3
)) {
103 return (CKR_KEY_TYPE_INCONSISTENT
);
108 return (soft_des_crypt_init_common(session_p
, pMechanism
,
112 case CKM_DES_CBC_PAD
:
114 if (key_p
->key_type
!= CKK_DES
) {
115 return (CKR_KEY_TYPE_INCONSISTENT
);
121 case CKM_DES3_CBC_PAD
:
123 soft_des_ctx_t
*soft_des_ctx
;
125 if ((key_p
->key_type
!= CKK_DES2
) &&
126 (key_p
->key_type
!= CKK_DES3
)) {
127 return (CKR_KEY_TYPE_INCONSISTENT
);
131 if ((pMechanism
->pParameter
== NULL
) ||
132 (pMechanism
->ulParameterLen
!= DES_BLOCK_LEN
)) {
133 return (CKR_MECHANISM_PARAM_INVALID
);
136 rv
= soft_des_crypt_init_common(session_p
, pMechanism
,
142 (void) pthread_mutex_lock(&session_p
->session_mutex
);
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
,
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
);
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
);
164 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
170 if (key_p
->key_type
!= CKK_AES
) {
171 return (CKR_KEY_TYPE_INCONSISTENT
);
174 return (soft_aes_crypt_init_common(session_p
, pMechanism
,
178 case CKM_AES_CBC_PAD
:
180 soft_aes_ctx_t
*soft_aes_ctx
;
182 if (key_p
->key_type
!= CKK_AES
) {
183 return (CKR_KEY_TYPE_INCONSISTENT
);
186 if ((pMechanism
->pParameter
== NULL
) ||
187 (pMechanism
->ulParameterLen
!= AES_BLOCK_LEN
)) {
188 return (CKR_MECHANISM_PARAM_INVALID
);
191 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
197 (void) pthread_mutex_lock(&session_p
->session_mutex
);
199 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
201 /* Save Initialization Vector (IV) in the context. */
202 (void) memcpy(soft_aes_ctx
->ivec
, pMechanism
->pParameter
,
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
,
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
);
220 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
226 soft_aes_ctx_t
*soft_aes_ctx
;
228 if (key_p
->key_type
!= CKK_AES
) {
229 return (CKR_KEY_TYPE_INCONSISTENT
);
232 if (pMechanism
->pParameter
== NULL
||
233 pMechanism
->ulParameterLen
!= sizeof (CK_AES_CTR_PARAMS
)) {
234 return (CKR_MECHANISM_PARAM_INVALID
);
237 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
243 (void) pthread_mutex_lock(&session_p
->session_mutex
);
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
);
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
;
259 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
263 case CKM_BLOWFISH_CBC
:
265 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
267 if (key_p
->key_type
!= CKK_BLOWFISH
)
268 return (CKR_KEY_TYPE_INCONSISTENT
);
270 if ((pMechanism
->pParameter
== NULL
) ||
271 (pMechanism
->ulParameterLen
!= BLOWFISH_BLOCK_LEN
))
272 return (CKR_MECHANISM_PARAM_INVALID
);
274 rv
= soft_blowfish_crypt_init_common(session_p
, pMechanism
,
280 (void) pthread_mutex_lock(&session_p
->session_mutex
);
283 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
285 /* Save Initialization Vector in the context. */
286 (void) memcpy(soft_blowfish_ctx
->ivec
, pMechanism
->pParameter
,
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
);
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
);
305 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
311 if (key_p
->key_type
!= CKK_RC4
) {
312 return (CKR_KEY_TYPE_INCONSISTENT
);
315 return (soft_arcfour_crypt_init(session_p
, pMechanism
, key_p
,
321 if (key_p
->key_type
!= CKK_RSA
) {
322 return (CKR_KEY_TYPE_INCONSISTENT
);
325 return (soft_rsa_crypt_init_common(session_p
, pMechanism
,
329 return (CKR_MECHANISM_INVALID
);
335 * soft_decrypt_common()
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
347 * This function calls the corresponding decrypt routine based
351 * see soft_decrypt_common().
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
)
359 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
368 if (ulEncryptedLen
== 0) {
374 case CKM_DES_CBC_PAD
:
375 case CKM_DES3_CBC_PAD
:
377 return (soft_des_decrypt_common(session_p
, pEncrypted
,
378 ulEncryptedLen
, pData
, pulDataLen
, Update
));
384 if (ulEncryptedLen
== 0) {
390 case CKM_AES_CBC_PAD
:
392 return (soft_aes_decrypt_common(session_p
, pEncrypted
,
393 ulEncryptedLen
, pData
, pulDataLen
, Update
));
395 case CKM_BLOWFISH_CBC
:
397 if (ulEncryptedLen
== 0) {
402 return (soft_blowfish_decrypt_common(session_p
, pEncrypted
,
403 ulEncryptedLen
, pData
, pulDataLen
, Update
));
407 if (ulEncryptedLen
== 0) {
413 return (soft_arcfour_crypt(&(session_p
->decrypt
), pEncrypted
,
414 ulEncryptedLen
, pData
, pulDataLen
));
419 return (soft_rsa_decrypt_common(session_p
, pEncrypted
,
420 ulEncryptedLen
, pData
, pulDataLen
, mechanism
));
423 return (CKR_MECHANISM_INVALID
);
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
440 * called by C_Decrypt(). This function calls the soft_decrypt_common
444 * see soft_decrypt_common().
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
)
452 return (soft_decrypt_common(session_p
, pEncryptedData
,
453 ulEncryptedDataLen
, pData
, pulDataLen
, B_FALSE
));
458 * soft_decrypt_update()
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
468 * called by C_DecryptUpdate(). This function calls the
469 * soft_decrypt_common routine (with update flag on).
472 * see soft_decrypt_common().
475 soft_decrypt_update(soft_session_t
*session_p
, CK_BYTE_PTR pEncryptedPart
,
476 CK_ULONG ulEncryptedPartLen
, CK_BYTE_PTR pPart
, CK_ULONG_PTR pulPartLen
)
478 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
484 case CKM_DES_CBC_PAD
:
487 case CKM_DES3_CBC_PAD
:
490 case CKM_AES_CBC_PAD
:
492 case CKM_BLOWFISH_CBC
:
495 return (soft_decrypt_common(session_p
, pEncryptedPart
,
496 ulEncryptedPartLen
, pPart
, pulPartLen
, B_TRUE
));
499 /* PKCS11: The mechanism only supports single-part operation. */
500 return (CKR_MECHANISM_INVALID
);
507 * soft_decrypt_final()
510 * session_p: pointer to soft_session_t struct
511 * pLastPart: pointer to the last recovered data part
512 * pulLastPartLen: pointer to the length of the last recovered data part
515 * called by C_DecryptFinal().
519 * CKR_FUNCTION_FAILED: decrypt final function failed
520 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
523 soft_decrypt_final(soft_session_t
*session_p
, CK_BYTE_PTR pLastPart
,
524 CK_ULONG_PTR pulLastPartLen
)
527 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
532 (void) pthread_mutex_lock(&session_p
->session_mutex
);
534 if (session_p
->decrypt
.context
== NULL
) {
535 rv
= CKR_OPERATION_NOT_INITIALIZED
;
541 case CKM_DES_CBC_PAD
:
542 case CKM_DES3_CBC_PAD
:
545 soft_des_ctx_t
*soft_des_ctx
;
547 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
550 * We should have only one block of data left in the
553 if (soft_des_ctx
->remain_len
!= DES_BLOCK_LEN
) {
555 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
556 /* Cleanup memory space. */
557 free(soft_des_ctx
->des_cbc
);
558 freezero(soft_des_ctx
->key_sched
,
559 soft_des_ctx
->keysched_len
);
564 out_len
= DES_BLOCK_LEN
;
567 * If application asks for the length of the output buffer
568 * to hold the plaintext?
570 if (pLastPart
== NULL
) {
571 *pulLastPartLen
= out_len
;
577 /* Copy remaining data to the output buffer. */
578 (void) memcpy(pLastPart
, soft_des_ctx
->data
,
581 out
.cd_format
= CRYPTO_DATA_RAW
;
583 out
.cd_length
= DES_BLOCK_LEN
;
584 out
.cd_raw
.iov_base
= (char *)pLastPart
;
585 out
.cd_raw
.iov_len
= DES_BLOCK_LEN
;
587 /* Decrypt final block of data. */
588 rc
= des_decrypt_contiguous_blocks(
589 (des_ctx_t
*)soft_des_ctx
->des_cbc
,
590 (char *)pLastPart
, DES_BLOCK_LEN
, &out
);
594 * Remove padding bytes after decryption of
595 * ciphertext block to produce the original
598 rv
= soft_remove_pkcs7_padding(pLastPart
,
599 DES_BLOCK_LEN
, &out_len
);
603 *pulLastPartLen
= out_len
;
606 rv
= CKR_FUNCTION_FAILED
;
609 /* Cleanup memory space. */
610 free(soft_des_ctx
->des_cbc
);
611 freezero(soft_des_ctx
->key_sched
,
612 soft_des_ctx
->keysched_len
);
625 soft_des_ctx_t
*soft_des_ctx
;
627 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
629 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
630 * so when the final is called, the remaining buffer
631 * should not contain any more data.
634 if (soft_des_ctx
->remain_len
!= 0) {
635 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
637 if (pLastPart
== NULL
)
641 /* Cleanup memory space. */
642 free(soft_des_ctx
->des_cbc
);
643 freezero(soft_des_ctx
->key_sched
,
644 soft_des_ctx
->keysched_len
);
649 case CKM_AES_CBC_PAD
:
652 soft_aes_ctx_t
*soft_aes_ctx
;
654 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
657 * We should have only one block of data left in the
660 if (soft_aes_ctx
->remain_len
!= AES_BLOCK_LEN
) {
662 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
663 /* Cleanup memory space. */
664 free(soft_aes_ctx
->aes_cbc
);
665 freezero(soft_aes_ctx
->key_sched
,
666 soft_aes_ctx
->keysched_len
);
671 out_len
= AES_BLOCK_LEN
;
674 * If application asks for the length of the output buffer
675 * to hold the plaintext?
677 if (pLastPart
== NULL
) {
678 *pulLastPartLen
= out_len
;
684 /* Copy remaining data to the output buffer. */
685 (void) memcpy(pLastPart
, soft_aes_ctx
->data
,
688 out
.cd_format
= CRYPTO_DATA_RAW
;
690 out
.cd_length
= AES_BLOCK_LEN
;
691 out
.cd_raw
.iov_base
= (char *)pLastPart
;
692 out
.cd_raw
.iov_len
= AES_BLOCK_LEN
;
694 /* Decrypt final block of data. */
695 rc
= aes_decrypt_contiguous_blocks(
696 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
697 (char *)pLastPart
, AES_BLOCK_LEN
, &out
);
701 * Remove padding bytes after decryption of
702 * ciphertext block to produce the original
705 rv
= soft_remove_pkcs7_padding(pLastPart
,
706 AES_BLOCK_LEN
, &out_len
);
710 *pulLastPartLen
= out_len
;
713 rv
= CKR_FUNCTION_FAILED
;
716 /* Cleanup memory space. */
717 free(soft_aes_ctx
->aes_cbc
);
718 freezero(soft_aes_ctx
->key_sched
,
719 soft_aes_ctx
->keysched_len
);
729 soft_aes_ctx_t
*soft_aes_ctx
;
731 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
733 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
734 * so when the final is called, the remaining buffer
735 * should not contain any more data.
738 if (soft_aes_ctx
->remain_len
!= 0) {
739 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
741 if (pLastPart
== NULL
)
745 /* Cleanup memory space. */
746 free(soft_aes_ctx
->aes_cbc
);
747 freezero(soft_aes_ctx
->key_sched
,
748 soft_aes_ctx
->keysched_len
);
755 soft_aes_ctx_t
*soft_aes_ctx
;
759 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
760 ctr_ctx
= soft_aes_ctx
->aes_cbc
;
761 len
= ctr_ctx
->ctr_remainder_len
;
762 if (pLastPart
== NULL
) {
763 *pulLastPartLen
= len
;
767 out
.cd_format
= CRYPTO_DATA_RAW
;
770 out
.cd_raw
.iov_base
= (char *)pLastPart
;
771 out
.cd_raw
.iov_len
= len
;
773 rv
= ctr_mode_final(ctr_ctx
, &out
, aes_encrypt_block
);
774 if (rv
== CRYPTO_DATA_LEN_RANGE
)
775 rv
= CRYPTO_ENCRYPTED_DATA_LEN_RANGE
;
777 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
778 *pulLastPartLen
= len
;
782 /* Cleanup memory space. */
784 freezero(soft_aes_ctx
->key_sched
,
785 soft_aes_ctx
->keysched_len
);
789 case CKM_BLOWFISH_CBC
:
791 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
794 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
797 if (soft_blowfish_ctx
->remain_len
!= 0)
798 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
800 if (pLastPart
== NULL
)
804 free(soft_blowfish_ctx
->blowfish_cbc
);
805 freezero(soft_blowfish_ctx
->key_sched
,
806 soft_blowfish_ctx
->keysched_len
);
813 ARCFour_key
*key
= (ARCFour_key
*)session_p
->decrypt
.context
;
814 explicit_bzero(key
, sizeof (*key
));
820 /* PKCS11: The mechanism only supports single-part operation. */
821 rv
= CKR_MECHANISM_INVALID
;
826 free(session_p
->decrypt
.context
);
827 session_p
->decrypt
.context
= NULL
;
830 (void) pthread_mutex_unlock(&session_p
->session_mutex
);