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
,
50 if ((rv
= pkcs7_decode(pData
, (&padded_len
))) != CKR_OK
)
51 #else /* !__sparcv9 */
52 if ((rv
= pkcs7_decode(pData
, (size_t *)(&padded_len
))) != CKR_OK
)
53 #endif /* __sparcv9 */
56 *pulDataLen
= padded_len
;
65 * session_p: pointer to soft_session_t struct
66 * pMechanism: pointer to CK_MECHANISM struct provided by application
67 * key_p: pointer to key soft_object_t struct
70 * called by C_DecryptInit(). This function calls the corresponding
71 * decrypt init routine based on the mechanism.
75 * CKR_HOST_MEMORY: run out of system memory
76 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
77 * CKR_MECHANISM_INVALID: invalid mechanism type
78 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
79 * with the specified mechanism
82 soft_decrypt_init(soft_session_t
*session_p
, CK_MECHANISM_PTR pMechanism
,
88 switch (pMechanism
->mechanism
) {
92 if (key_p
->key_type
!= CKK_DES
) {
93 return (CKR_KEY_TYPE_INCONSISTENT
);
100 if ((key_p
->key_type
!= CKK_DES2
) &&
101 (key_p
->key_type
!= CKK_DES3
)) {
102 return (CKR_KEY_TYPE_INCONSISTENT
);
107 return (soft_des_crypt_init_common(session_p
, pMechanism
,
111 case CKM_DES_CBC_PAD
:
113 if (key_p
->key_type
!= CKK_DES
) {
114 return (CKR_KEY_TYPE_INCONSISTENT
);
120 case CKM_DES3_CBC_PAD
:
122 soft_des_ctx_t
*soft_des_ctx
;
124 if ((key_p
->key_type
!= CKK_DES2
) &&
125 (key_p
->key_type
!= CKK_DES3
)) {
126 return (CKR_KEY_TYPE_INCONSISTENT
);
130 if ((pMechanism
->pParameter
== NULL
) ||
131 (pMechanism
->ulParameterLen
!= DES_BLOCK_LEN
)) {
132 return (CKR_MECHANISM_PARAM_INVALID
);
135 rv
= soft_des_crypt_init_common(session_p
, pMechanism
,
141 (void) pthread_mutex_lock(&session_p
->session_mutex
);
143 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
144 /* Save Initialization Vector (IV) in the context. */
145 (void) memcpy(soft_des_ctx
->ivec
, pMechanism
->pParameter
,
148 /* Allocate a context for DES cipher-block chaining. */
149 soft_des_ctx
->des_cbc
= (void *)des_cbc_ctx_init(
150 soft_des_ctx
->key_sched
, soft_des_ctx
->keysched_len
,
151 soft_des_ctx
->ivec
, key_p
->key_type
);
153 if (soft_des_ctx
->des_cbc
== NULL
) {
154 bzero(soft_des_ctx
->key_sched
,
155 soft_des_ctx
->keysched_len
);
156 free(soft_des_ctx
->key_sched
);
157 free(session_p
->decrypt
.context
);
158 session_p
->decrypt
.context
= NULL
;
159 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
160 return (CKR_HOST_MEMORY
);
163 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
169 if (key_p
->key_type
!= CKK_AES
) {
170 return (CKR_KEY_TYPE_INCONSISTENT
);
173 return (soft_aes_crypt_init_common(session_p
, pMechanism
,
177 case CKM_AES_CBC_PAD
:
179 soft_aes_ctx_t
*soft_aes_ctx
;
181 if (key_p
->key_type
!= CKK_AES
) {
182 return (CKR_KEY_TYPE_INCONSISTENT
);
185 if ((pMechanism
->pParameter
== NULL
) ||
186 (pMechanism
->ulParameterLen
!= AES_BLOCK_LEN
)) {
187 return (CKR_MECHANISM_PARAM_INVALID
);
190 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
196 (void) pthread_mutex_lock(&session_p
->session_mutex
);
198 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
200 /* Save Initialization Vector (IV) in the context. */
201 (void) memcpy(soft_aes_ctx
->ivec
, pMechanism
->pParameter
,
204 /* Allocate a context for AES cipher-block chaining. */
205 soft_aes_ctx
->aes_cbc
= (void *)aes_cbc_ctx_init(
206 soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
,
209 if (soft_aes_ctx
->aes_cbc
== NULL
) {
210 bzero(soft_aes_ctx
->key_sched
,
211 soft_aes_ctx
->keysched_len
);
212 free(soft_aes_ctx
->key_sched
);
213 free(session_p
->decrypt
.context
);
214 session_p
->decrypt
.context
= NULL
;
215 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
216 return (CKR_HOST_MEMORY
);
219 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
225 soft_aes_ctx_t
*soft_aes_ctx
;
227 if (key_p
->key_type
!= CKK_AES
) {
228 return (CKR_KEY_TYPE_INCONSISTENT
);
231 if (pMechanism
->pParameter
== NULL
||
232 pMechanism
->ulParameterLen
!= sizeof (CK_AES_CTR_PARAMS
)) {
233 return (CKR_MECHANISM_PARAM_INVALID
);
236 rv
= soft_aes_crypt_init_common(session_p
, pMechanism
,
242 (void) pthread_mutex_lock(&session_p
->session_mutex
);
244 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
245 soft_aes_ctx
->aes_cbc
= aes_ctr_ctx_init(
246 soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
,
247 pMechanism
->pParameter
);
249 if (soft_aes_ctx
->aes_cbc
== NULL
) {
250 bzero(soft_aes_ctx
->key_sched
,
251 soft_aes_ctx
->keysched_len
);
252 free(soft_aes_ctx
->key_sched
);
253 free(session_p
->decrypt
.context
);
254 session_p
->decrypt
.context
= NULL
;
255 rv
= CKR_HOST_MEMORY
;
258 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
262 case CKM_BLOWFISH_CBC
:
264 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
266 if (key_p
->key_type
!= CKK_BLOWFISH
)
267 return (CKR_KEY_TYPE_INCONSISTENT
);
269 if ((pMechanism
->pParameter
== NULL
) ||
270 (pMechanism
->ulParameterLen
!= BLOWFISH_BLOCK_LEN
))
271 return (CKR_MECHANISM_PARAM_INVALID
);
273 rv
= soft_blowfish_crypt_init_common(session_p
, pMechanism
,
279 (void) pthread_mutex_lock(&session_p
->session_mutex
);
282 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
284 /* Save Initialization Vector in the context. */
285 (void) memcpy(soft_blowfish_ctx
->ivec
, pMechanism
->pParameter
,
288 /* Allocate a context for CBC */
289 soft_blowfish_ctx
->blowfish_cbc
=
290 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx
->key_sched
,
291 soft_blowfish_ctx
->keysched_len
,
292 soft_blowfish_ctx
->ivec
);
294 if (soft_blowfish_ctx
->blowfish_cbc
== NULL
) {
295 bzero(soft_blowfish_ctx
->key_sched
,
296 soft_blowfish_ctx
->keysched_len
);
297 free(soft_blowfish_ctx
->key_sched
);
298 free(session_p
->decrypt
.context
= NULL
);
299 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
300 return (CKR_HOST_MEMORY
);
303 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
309 if (key_p
->key_type
!= CKK_RC4
) {
310 return (CKR_KEY_TYPE_INCONSISTENT
);
313 return (soft_arcfour_crypt_init(session_p
, pMechanism
, key_p
,
319 if (key_p
->key_type
!= CKK_RSA
) {
320 return (CKR_KEY_TYPE_INCONSISTENT
);
323 return (soft_rsa_crypt_init_common(session_p
, pMechanism
,
327 return (CKR_MECHANISM_INVALID
);
333 * soft_decrypt_common()
336 * session_p: pointer to soft_session_t struct
337 * pEncrypted: pointer to the encrypted data as input
338 * ulEncryptedLen: length of the input data
339 * pData: pointer to the output data contains plaintext
340 * pulDataLen: pointer to the length of the output data
341 * Update: boolean flag indicates caller is soft_decrypt
342 * or soft_decrypt_update
345 * This function calls the corresponding decrypt routine based
349 * see soft_decrypt_common().
352 soft_decrypt_common(soft_session_t
*session_p
, CK_BYTE_PTR pEncrypted
,
353 CK_ULONG ulEncryptedLen
, CK_BYTE_PTR pData
,
354 CK_ULONG_PTR pulDataLen
, boolean_t Update
)
357 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
366 if (ulEncryptedLen
== 0) {
372 case CKM_DES_CBC_PAD
:
373 case CKM_DES3_CBC_PAD
:
375 return (soft_des_decrypt_common(session_p
, pEncrypted
,
376 ulEncryptedLen
, pData
, pulDataLen
, Update
));
382 if (ulEncryptedLen
== 0) {
388 case CKM_AES_CBC_PAD
:
390 return (soft_aes_decrypt_common(session_p
, pEncrypted
,
391 ulEncryptedLen
, pData
, pulDataLen
, Update
));
393 case CKM_BLOWFISH_CBC
:
395 if (ulEncryptedLen
== 0) {
400 return (soft_blowfish_decrypt_common(session_p
, pEncrypted
,
401 ulEncryptedLen
, pData
, pulDataLen
, Update
));
405 if (ulEncryptedLen
== 0) {
411 return (soft_arcfour_crypt(&(session_p
->decrypt
), pEncrypted
,
412 ulEncryptedLen
, pData
, pulDataLen
));
417 return (soft_rsa_decrypt_common(session_p
, pEncrypted
,
418 ulEncryptedLen
, pData
, pulDataLen
, mechanism
));
421 return (CKR_MECHANISM_INVALID
);
431 * session_p: pointer to soft_session_t struct
432 * pEncryptedData: pointer to the encrypted data as input
433 * ulEncryptedDataLen: length of the input data
434 * pData: pointer to the output data contains plaintext
435 * pulDataLen: pointer to the length of the output data
438 * called by C_Decrypt(). This function calls the soft_decrypt_common
442 * see soft_decrypt_common().
445 soft_decrypt(soft_session_t
*session_p
, CK_BYTE_PTR pEncryptedData
,
446 CK_ULONG ulEncryptedDataLen
, CK_BYTE_PTR pData
,
447 CK_ULONG_PTR pulDataLen
)
450 return (soft_decrypt_common(session_p
, pEncryptedData
,
451 ulEncryptedDataLen
, pData
, pulDataLen
, B_FALSE
));
456 * soft_decrypt_update()
459 * session_p: pointer to soft_session_t struct
460 * pEncryptedPart: pointer to the encrypted data as input
461 * ulEncryptedPartLen: length of the input data
462 * pPart: pointer to the output data contains plaintext
463 * pulPartLen: pointer to the length of the output data
466 * called by C_DecryptUpdate(). This function calls the
467 * soft_decrypt_common routine (with update flag on).
470 * see soft_decrypt_common().
473 soft_decrypt_update(soft_session_t
*session_p
, CK_BYTE_PTR pEncryptedPart
,
474 CK_ULONG ulEncryptedPartLen
, CK_BYTE_PTR pPart
,
475 CK_ULONG_PTR pulPartLen
)
477 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
483 case CKM_DES_CBC_PAD
:
486 case CKM_DES3_CBC_PAD
:
489 case CKM_AES_CBC_PAD
:
491 case CKM_BLOWFISH_CBC
:
494 return (soft_decrypt_common(session_p
, pEncryptedPart
,
495 ulEncryptedPartLen
, pPart
, pulPartLen
, B_TRUE
));
498 /* PKCS11: The mechanism only supports single-part operation. */
499 return (CKR_MECHANISM_INVALID
);
506 * soft_decrypt_final()
509 * session_p: pointer to soft_session_t struct
510 * pLastPart: pointer to the last recovered data part
511 * pulLastPartLen: pointer to the length of the last recovered data part
514 * called by C_DecryptFinal().
518 * CKR_FUNCTION_FAILED: decrypt final function failed
519 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
522 soft_decrypt_final(soft_session_t
*session_p
, CK_BYTE_PTR pLastPart
,
523 CK_ULONG_PTR pulLastPartLen
)
526 CK_MECHANISM_TYPE mechanism
= session_p
->decrypt
.mech
.mechanism
;
531 (void) pthread_mutex_lock(&session_p
->session_mutex
);
533 if (session_p
->decrypt
.context
== NULL
) {
534 rv
= CKR_OPERATION_NOT_INITIALIZED
;
540 case CKM_DES_CBC_PAD
:
541 case CKM_DES3_CBC_PAD
:
544 soft_des_ctx_t
*soft_des_ctx
;
546 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
549 * We should have only one block of data left in the
552 if (soft_des_ctx
->remain_len
!= DES_BLOCK_LEN
) {
554 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
555 /* Cleanup memory space. */
556 free(soft_des_ctx
->des_cbc
);
557 bzero(soft_des_ctx
->key_sched
,
558 soft_des_ctx
->keysched_len
);
559 free(soft_des_ctx
->key_sched
);
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 bzero(soft_des_ctx
->key_sched
,
612 soft_des_ctx
->keysched_len
);
613 free(soft_des_ctx
->key_sched
);
626 soft_des_ctx_t
*soft_des_ctx
;
628 soft_des_ctx
= (soft_des_ctx_t
*)session_p
->decrypt
.context
;
630 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
631 * so when the final is called, the remaining buffer
632 * should not contain any more data.
635 if (soft_des_ctx
->remain_len
!= 0) {
636 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
638 if (pLastPart
== NULL
)
642 /* Cleanup memory space. */
643 free(soft_des_ctx
->des_cbc
);
644 bzero(soft_des_ctx
->key_sched
, soft_des_ctx
->keysched_len
);
645 free(soft_des_ctx
->key_sched
);
650 case CKM_AES_CBC_PAD
:
653 soft_aes_ctx_t
*soft_aes_ctx
;
655 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
658 * We should have only one block of data left in the
661 if (soft_aes_ctx
->remain_len
!= AES_BLOCK_LEN
) {
663 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
664 /* Cleanup memory space. */
665 free(soft_aes_ctx
->aes_cbc
);
666 bzero(soft_aes_ctx
->key_sched
,
667 soft_aes_ctx
->keysched_len
);
668 free(soft_aes_ctx
->key_sched
);
673 out_len
= AES_BLOCK_LEN
;
676 * If application asks for the length of the output buffer
677 * to hold the plaintext?
679 if (pLastPart
== NULL
) {
680 *pulLastPartLen
= out_len
;
686 /* Copy remaining data to the output buffer. */
687 (void) memcpy(pLastPart
, soft_aes_ctx
->data
,
690 out
.cd_format
= CRYPTO_DATA_RAW
;
692 out
.cd_length
= AES_BLOCK_LEN
;
693 out
.cd_raw
.iov_base
= (char *)pLastPart
;
694 out
.cd_raw
.iov_len
= AES_BLOCK_LEN
;
696 /* Decrypt final block of data. */
697 rc
= aes_decrypt_contiguous_blocks(
698 (aes_ctx_t
*)soft_aes_ctx
->aes_cbc
,
699 (char *)pLastPart
, AES_BLOCK_LEN
, &out
);
703 * Remove padding bytes after decryption of
704 * ciphertext block to produce the original
707 rv
= soft_remove_pkcs7_padding(pLastPart
,
708 AES_BLOCK_LEN
, &out_len
);
712 *pulLastPartLen
= out_len
;
715 rv
= CKR_FUNCTION_FAILED
;
718 /* Cleanup memory space. */
719 free(soft_aes_ctx
->aes_cbc
);
720 bzero(soft_aes_ctx
->key_sched
,
721 soft_aes_ctx
->keysched_len
);
722 free(soft_aes_ctx
->key_sched
);
732 soft_aes_ctx_t
*soft_aes_ctx
;
734 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
736 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
737 * so when the final is called, the remaining buffer
738 * should not contain any more data.
741 if (soft_aes_ctx
->remain_len
!= 0) {
742 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
744 if (pLastPart
== NULL
)
748 /* Cleanup memory space. */
749 free(soft_aes_ctx
->aes_cbc
);
750 bzero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
751 free(soft_aes_ctx
->key_sched
);
758 soft_aes_ctx_t
*soft_aes_ctx
;
762 soft_aes_ctx
= (soft_aes_ctx_t
*)session_p
->decrypt
.context
;
763 ctr_ctx
= soft_aes_ctx
->aes_cbc
;
764 len
= ctr_ctx
->ctr_remainder_len
;
765 if (pLastPart
== NULL
) {
766 *pulLastPartLen
= len
;
770 out
.cd_format
= CRYPTO_DATA_RAW
;
773 out
.cd_raw
.iov_base
= (char *)pLastPart
;
774 out
.cd_raw
.iov_len
= len
;
776 rv
= ctr_mode_final(ctr_ctx
, &out
, aes_encrypt_block
);
777 if (rv
== CRYPTO_DATA_LEN_RANGE
)
778 rv
= CRYPTO_ENCRYPTED_DATA_LEN_RANGE
;
780 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
781 *pulLastPartLen
= len
;
785 /* Cleanup memory space. */
787 bzero(soft_aes_ctx
->key_sched
, soft_aes_ctx
->keysched_len
);
788 free(soft_aes_ctx
->key_sched
);
792 case CKM_BLOWFISH_CBC
:
794 soft_blowfish_ctx_t
*soft_blowfish_ctx
;
797 (soft_blowfish_ctx_t
*)session_p
->decrypt
.context
;
800 if (soft_blowfish_ctx
->remain_len
!= 0)
801 rv
= CKR_ENCRYPTED_DATA_LEN_RANGE
;
803 if (pLastPart
== NULL
)
807 free(soft_blowfish_ctx
->blowfish_cbc
);
808 bzero(soft_blowfish_ctx
->key_sched
,
809 soft_blowfish_ctx
->keysched_len
);
810 free(soft_blowfish_ctx
->key_sched
);
817 ARCFour_key
*key
= (ARCFour_key
*)session_p
->decrypt
.context
;
818 bzero(key
, sizeof (*key
));
824 /* PKCS11: The mechanism only supports single-part operation. */
825 rv
= CKR_MECHANISM_INVALID
;
830 free(session_p
->decrypt
.context
);
831 session_p
->decrypt
.context
= NULL
;
834 (void) pthread_mutex_unlock(&session_p
->session_mutex
);