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.
30 #include <sys/types.h>
31 #include <security/cryptoki.h>
32 #include <modes/modes.h>
34 #include "softSession.h"
35 #include "softObject.h"
37 #include "softCrypt.h"
41 * Remove padding bytes.
44 soft_remove_pkcs7_padding(CK_BYTE
*pData
, CK_ULONG padded_len
,
49 if ((rv
= pkcs7_decode(pData
, (size_t *)(&padded_len
))) != CKR_OK
)
52 *pulDataLen
= padded_len
;
61 * session_p: pointer to soft_session_t struct
62 * pMechanism: pointer to CK_MECHANISM struct provided by application
63 * key_p: pointer to key soft_object_t struct
66 * called by C_DecryptInit(). This function calls the corresponding
67 * decrypt init routine based on the mechanism.
71 * CKR_HOST_MEMORY: run out of system memory
72 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
73 * CKR_MECHANISM_INVALID: invalid mechanism type
74 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
75 * with the specified mechanism
78 soft_decrypt_init(soft_session_t
*session_p
, CK_MECHANISM_PTR pMechanism
,
84 switch (pMechanism
->mechanism
) {
88 if (key_p
->key_type
!= CKK_DES
) {
89 return (CKR_KEY_TYPE_INCONSISTENT
);
96 if ((key_p
->key_type
!= CKK_DES2
) &&
97 (key_p
->key_type
!= CKK_DES3
)) {
98 return (CKR_KEY_TYPE_INCONSISTENT
);
103 return (soft_des_crypt_init_common(session_p
, pMechanism
,
107 case CKM_DES_CBC_PAD
:
109 if (key_p
->key_type
!= CKK_DES
) {
110 return (CKR_KEY_TYPE_INCONSISTENT
);
116 case CKM_DES3_CBC_PAD
:
118 soft_des_ctx_t
*soft_des_ctx
;
120 if ((key_p
->key_type
!= CKK_DES2
) &&
121 (key_p
->key_type
!= CKK_DES3
)) {
122 return (CKR_KEY_TYPE_INCONSISTENT
);
126 if ((pMechanism
->pParameter
== NULL
) ||
127 (pMechanism
->ulParameterLen
!= DES_BLOCK_LEN
)) {
128 return (CKR_MECHANISM_PARAM_INVALID
);
131 rv
= soft_des_crypt_init_common(session_p
, pMechanism
,
137 (void) pthread_mutex_lock(&session_p
->session_mutex
);
139 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
140 /* Save Initialization Vector (IV) in the context. */
141 (void) memcpy(soft_des_ctx
->ivec
, pMechanism
->pParameter
,
144 /* Allocate a context for DES cipher-block chaining. */
145 soft_des_ctx
->des_cbc
= (void *)des_cbc_ctx_init(
146 soft_des_ctx
->key_sched
, soft_des_ctx
->keysched_len
,
147 soft_des_ctx
->ivec
, key_p
->key_type
);
149 if (soft_des_ctx
->des_cbc
== NULL
) {
150 bzero(soft_des_ctx
->key_sched
,
151 soft_des_ctx
->keysched_len
);
152 free(soft_des_ctx
->key_sched
);
153 free(session_p
->decrypt
.context
);
154 session_p
->decrypt
.context
= NULL
;
155 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
156 return (CKR_HOST_MEMORY
);
159 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
165 if (key_p
->key_type
!= CKK_AES
) {
166 return (CKR_KEY_TYPE_INCONSISTENT
);
169 return (soft_aes_crypt_init_common(session_p
, pMechanism
,
173 case CKM_AES_CBC_PAD
:
175 soft_aes_ctx_t
*soft_aes_ctx
;
177 if (key_p
->key_type
!= CKK_AES
) {
178 return (CKR_KEY_TYPE_INCONSISTENT
);
181 if ((pMechanism
->pParameter
== NULL
) ||
182 (pMechanism
->ulParameterLen
!= AES_BLOCK_LEN
)) {
183 return (CKR_MECHANISM_PARAM_INVALID
);
186 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
192 (void) pthread_mutex_lock(&session_p
->session_mutex
);
194 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
196 /* Save Initialization Vector (IV) in the context. */
197 (void) memcpy(soft_aes_ctx
->ivec
, pMechanism
->pParameter
,
200 /* Allocate a context for AES cipher-block chaining. */
201 soft_aes_ctx
->aes_cbc
= (void *)aes_cbc_ctx_init(
202 soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
,
205 if (soft_aes_ctx
->aes_cbc
== NULL
) {
206 bzero(soft_aes_ctx
->key_sched
,
207 soft_aes_ctx
->keysched_len
);
208 free(soft_aes_ctx
->key_sched
);
209 free(session_p
->decrypt
.context
);
210 session_p
->decrypt
.context
= NULL
;
211 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
212 return (CKR_HOST_MEMORY
);
215 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
221 soft_aes_ctx_t
*soft_aes_ctx
;
223 if (key_p
->key_type
!= CKK_AES
) {
224 return (CKR_KEY_TYPE_INCONSISTENT
);
227 if (pMechanism
->pParameter
== NULL
||
228 pMechanism
->ulParameterLen
!= sizeof (CK_AES_CTR_PARAMS
)) {
229 return (CKR_MECHANISM_PARAM_INVALID
);
232 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
238 (void) pthread_mutex_lock(&session_p
->session_mutex
);
240 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
241 soft_aes_ctx
->aes_cbc
= aes_ctr_ctx_init(
242 soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
,
243 pMechanism
->pParameter
);
245 if (soft_aes_ctx
->aes_cbc
== NULL
) {
246 bzero(soft_aes_ctx
->key_sched
,
247 soft_aes_ctx
->keysched_len
);
248 free(soft_aes_ctx
->key_sched
);
249 free(session_p
->decrypt
.context
);
250 session_p
->decrypt
.context
= NULL
;
251 rv
= CKR_HOST_MEMORY
;
254 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
258 case CKM_BLOWFISH_CBC
:
260 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
262 if (key_p
->key_type
!= CKK_BLOWFISH
)
263 return (CKR_KEY_TYPE_INCONSISTENT
);
265 if ((pMechanism
->pParameter
== NULL
) ||
266 (pMechanism
->ulParameterLen
!= BLOWFISH_BLOCK_LEN
))
267 return (CKR_MECHANISM_PARAM_INVALID
);
269 rv
= soft_blowfish_crypt_init_common(session_p
, pMechanism
,
275 (void) pthread_mutex_lock(&session_p
->session_mutex
);
278 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
280 /* Save Initialization Vector in the context. */
281 (void) memcpy(soft_blowfish_ctx
->ivec
, pMechanism
->pParameter
,
284 /* Allocate a context for CBC */
285 soft_blowfish_ctx
->blowfish_cbc
=
286 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx
->key_sched
,
287 soft_blowfish_ctx
->keysched_len
,
288 soft_blowfish_ctx
->ivec
);
290 if (soft_blowfish_ctx
->blowfish_cbc
== NULL
) {
291 bzero(soft_blowfish_ctx
->key_sched
,
292 soft_blowfish_ctx
->keysched_len
);
293 free(soft_blowfish_ctx
->key_sched
);
294 free(session_p
->decrypt
.context
= NULL
);
295 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
296 return (CKR_HOST_MEMORY
);
299 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
305 if (key_p
->key_type
!= CKK_RC4
) {
306 return (CKR_KEY_TYPE_INCONSISTENT
);
309 return (soft_arcfour_crypt_init(session_p
, pMechanism
, key_p
,
315 if (key_p
->key_type
!= CKK_RSA
) {
316 return (CKR_KEY_TYPE_INCONSISTENT
);
319 return (soft_rsa_crypt_init_common(session_p
, pMechanism
,
323 return (CKR_MECHANISM_INVALID
);
329 * soft_decrypt_common()
332 * session_p: pointer to soft_session_t struct
333 * pEncrypted: pointer to the encrypted data as input
334 * ulEncryptedLen: length of the input data
335 * pData: pointer to the output data contains plaintext
336 * pulDataLen: pointer to the length of the output data
337 * Update: boolean flag indicates caller is soft_decrypt
338 * or soft_decrypt_update
341 * This function calls the corresponding decrypt routine based
345 * see soft_decrypt_common().
348 soft_decrypt_common(soft_session_t
*session_p
, CK_BYTE_PTR pEncrypted
,
349 CK_ULONG ulEncryptedLen
, CK_BYTE_PTR pData
,
350 CK_ULONG_PTR pulDataLen
, boolean_t Update
)
353 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
362 if (ulEncryptedLen
== 0) {
368 case CKM_DES_CBC_PAD
:
369 case CKM_DES3_CBC_PAD
:
371 return (soft_des_decrypt_common(session_p
, pEncrypted
,
372 ulEncryptedLen
, pData
, pulDataLen
, Update
));
378 if (ulEncryptedLen
== 0) {
384 case CKM_AES_CBC_PAD
:
386 return (soft_aes_decrypt_common(session_p
, pEncrypted
,
387 ulEncryptedLen
, pData
, pulDataLen
, Update
));
389 case CKM_BLOWFISH_CBC
:
391 if (ulEncryptedLen
== 0) {
396 return (soft_blowfish_decrypt_common(session_p
, pEncrypted
,
397 ulEncryptedLen
, pData
, pulDataLen
, Update
));
401 if (ulEncryptedLen
== 0) {
407 return (soft_arcfour_crypt(&(session_p
->decrypt
), pEncrypted
,
408 ulEncryptedLen
, pData
, pulDataLen
));
413 return (soft_rsa_decrypt_common(session_p
, pEncrypted
,
414 ulEncryptedLen
, pData
, pulDataLen
, mechanism
));
417 return (CKR_MECHANISM_INVALID
);
427 * session_p: pointer to soft_session_t struct
428 * pEncryptedData: pointer to the encrypted data as input
429 * ulEncryptedDataLen: length of the input data
430 * pData: pointer to the output data contains plaintext
431 * pulDataLen: pointer to the length of the output data
434 * called by C_Decrypt(). This function calls the soft_decrypt_common
438 * see soft_decrypt_common().
441 soft_decrypt(soft_session_t
*session_p
, CK_BYTE_PTR pEncryptedData
,
442 CK_ULONG ulEncryptedDataLen
, CK_BYTE_PTR pData
,
443 CK_ULONG_PTR pulDataLen
)
446 return (soft_decrypt_common(session_p
, pEncryptedData
,
447 ulEncryptedDataLen
, pData
, pulDataLen
, B_FALSE
));
452 * soft_decrypt_update()
455 * session_p: pointer to soft_session_t struct
456 * pEncryptedPart: pointer to the encrypted data as input
457 * ulEncryptedPartLen: length of the input data
458 * pPart: pointer to the output data contains plaintext
459 * pulPartLen: pointer to the length of the output data
462 * called by C_DecryptUpdate(). This function calls the
463 * soft_decrypt_common routine (with update flag on).
466 * see soft_decrypt_common().
469 soft_decrypt_update(soft_session_t
*session_p
, CK_BYTE_PTR pEncryptedPart
,
470 CK_ULONG ulEncryptedPartLen
, CK_BYTE_PTR pPart
,
471 CK_ULONG_PTR pulPartLen
)
473 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
479 case CKM_DES_CBC_PAD
:
482 case CKM_DES3_CBC_PAD
:
485 case CKM_AES_CBC_PAD
:
487 case CKM_BLOWFISH_CBC
:
490 return (soft_decrypt_common(session_p
, pEncryptedPart
,
491 ulEncryptedPartLen
, pPart
, pulPartLen
, B_TRUE
));
494 /* PKCS11: The mechanism only supports single-part operation. */
495 return (CKR_MECHANISM_INVALID
);
502 * soft_decrypt_final()
505 * session_p: pointer to soft_session_t struct
506 * pLastPart: pointer to the last recovered data part
507 * pulLastPartLen: pointer to the length of the last recovered data part
510 * called by C_DecryptFinal().
514 * CKR_FUNCTION_FAILED: decrypt final function failed
515 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
518 soft_decrypt_final(soft_session_t
*session_p
, CK_BYTE_PTR pLastPart
,
519 CK_ULONG_PTR pulLastPartLen
)
522 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
527 (void) pthread_mutex_lock(&session_p
->session_mutex
);
529 if (session_p
->decrypt
.context
== NULL
) {
530 rv
= CKR_OPERATION_NOT_INITIALIZED
;
536 case CKM_DES_CBC_PAD
:
537 case CKM_DES3_CBC_PAD
:
540 soft_des_ctx_t
*soft_des_ctx
;
542 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
545 * We should have only one block of data left in the
548 if (soft_des_ctx
->remain_len
!= DES_BLOCK_LEN
) {
550 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
551 /* Cleanup memory space. */
552 free(soft_des_ctx
->des_cbc
);
553 bzero(soft_des_ctx
->key_sched
,
554 soft_des_ctx
->keysched_len
);
555 free(soft_des_ctx
->key_sched
);
560 out_len
= DES_BLOCK_LEN
;
563 * If application asks for the length of the output buffer
564 * to hold the plaintext?
566 if (pLastPart
== NULL
) {
567 *pulLastPartLen
= out_len
;
573 /* Copy remaining data to the output buffer. */
574 (void) memcpy(pLastPart
, soft_des_ctx
->data
,
577 out
.cd_format
= CRYPTO_DATA_RAW
;
579 out
.cd_length
= DES_BLOCK_LEN
;
580 out
.cd_raw
.iov_base
= (char *)pLastPart
;
581 out
.cd_raw
.iov_len
= DES_BLOCK_LEN
;
583 /* Decrypt final block of data. */
584 rc
= des_decrypt_contiguous_blocks(
585 (des_ctx_t
*)soft_des_ctx
->des_cbc
,
586 (char *)pLastPart
, DES_BLOCK_LEN
, &out
);
590 * Remove padding bytes after decryption of
591 * ciphertext block to produce the original
594 rv
= soft_remove_pkcs7_padding(pLastPart
,
595 DES_BLOCK_LEN
, &out_len
);
599 *pulLastPartLen
= out_len
;
602 rv
= CKR_FUNCTION_FAILED
;
605 /* Cleanup memory space. */
606 free(soft_des_ctx
->des_cbc
);
607 bzero(soft_des_ctx
->key_sched
,
608 soft_des_ctx
->keysched_len
);
609 free(soft_des_ctx
->key_sched
);
622 soft_des_ctx_t
*soft_des_ctx
;
624 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
626 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
627 * so when the final is called, the remaining buffer
628 * should not contain any more data.
631 if (soft_des_ctx
->remain_len
!= 0) {
632 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
634 if (pLastPart
== NULL
)
638 /* Cleanup memory space. */
639 free(soft_des_ctx
->des_cbc
);
640 bzero(soft_des_ctx
->key_sched
, soft_des_ctx
->keysched_len
);
641 free(soft_des_ctx
->key_sched
);
646 case CKM_AES_CBC_PAD
:
649 soft_aes_ctx_t
*soft_aes_ctx
;
651 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
654 * We should have only one block of data left in the
657 if (soft_aes_ctx
->remain_len
!= AES_BLOCK_LEN
) {
659 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
660 /* Cleanup memory space. */
661 free(soft_aes_ctx
->aes_cbc
);
662 bzero(soft_aes_ctx
->key_sched
,
663 soft_aes_ctx
->keysched_len
);
664 free(soft_aes_ctx
->key_sched
);
669 out_len
= AES_BLOCK_LEN
;
672 * If application asks for the length of the output buffer
673 * to hold the plaintext?
675 if (pLastPart
== NULL
) {
676 *pulLastPartLen
= out_len
;
682 /* Copy remaining data to the output buffer. */
683 (void) memcpy(pLastPart
, soft_aes_ctx
->data
,
686 out
.cd_format
= CRYPTO_DATA_RAW
;
688 out
.cd_length
= AES_BLOCK_LEN
;
689 out
.cd_raw
.iov_base
= (char *)pLastPart
;
690 out
.cd_raw
.iov_len
= AES_BLOCK_LEN
;
692 /* Decrypt final block of data. */
693 rc
= aes_decrypt_contiguous_blocks(
694 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
695 (char *)pLastPart
, AES_BLOCK_LEN
, &out
);
699 * Remove padding bytes after decryption of
700 * ciphertext block to produce the original
703 rv
= soft_remove_pkcs7_padding(pLastPart
,
704 AES_BLOCK_LEN
, &out_len
);
708 *pulLastPartLen
= out_len
;
711 rv
= CKR_FUNCTION_FAILED
;
714 /* Cleanup memory space. */
715 free(soft_aes_ctx
->aes_cbc
);
716 bzero(soft_aes_ctx
->key_sched
,
717 soft_aes_ctx
->keysched_len
);
718 free(soft_aes_ctx
->key_sched
);
728 soft_aes_ctx_t
*soft_aes_ctx
;
730 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
732 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
733 * so when the final is called, the remaining buffer
734 * should not contain any more data.
737 if (soft_aes_ctx
->remain_len
!= 0) {
738 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
740 if (pLastPart
== NULL
)
744 /* Cleanup memory space. */
745 free(soft_aes_ctx
->aes_cbc
);
746 bzero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
747 free(soft_aes_ctx
->key_sched
);
754 soft_aes_ctx_t
*soft_aes_ctx
;
758 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
759 ctr_ctx
= soft_aes_ctx
->aes_cbc
;
760 len
= ctr_ctx
->ctr_remainder_len
;
761 if (pLastPart
== NULL
) {
762 *pulLastPartLen
= len
;
766 out
.cd_format
= CRYPTO_DATA_RAW
;
769 out
.cd_raw
.iov_base
= (char *)pLastPart
;
770 out
.cd_raw
.iov_len
= len
;
772 rv
= ctr_mode_final(ctr_ctx
, &out
, aes_encrypt_block
);
773 if (rv
== CRYPTO_DATA_LEN_RANGE
)
774 rv
= CRYPTO_ENCRYPTED_DATA_LEN_RANGE
;
776 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
777 *pulLastPartLen
= len
;
781 /* Cleanup memory space. */
783 bzero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
784 free(soft_aes_ctx
->key_sched
);
788 case CKM_BLOWFISH_CBC
:
790 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
793 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
796 if (soft_blowfish_ctx
->remain_len
!= 0)
797 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
799 if (pLastPart
== NULL
)
803 free(soft_blowfish_ctx
->blowfish_cbc
);
804 bzero(soft_blowfish_ctx
->key_sched
,
805 soft_blowfish_ctx
->keysched_len
);
806 free(soft_blowfish_ctx
->key_sched
);
813 ARCFour_key
*key
= (ARCFour_key
*)session_p
->decrypt
.context
;
814 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
);