2 * Copyright (c) 2015-2016, Secure Endpoints Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 /* PKCS#11 provider */
48 #define RTLD_NODELETE 0
51 #error PKCS11 support requires dlfcn.h
57 #include <evp-hcrypto.h>
58 #include <evp-pkcs11.h>
60 #include <ref/pkcs11.h>
62 #if __sun && !defined(PKCS11_MODULE_PATH)
64 # define PKCS11_MODULE_PATH "/usr/lib/64/libpkcs11.so"
66 # define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so"
68 #elif defined(__linux__)
70 * XXX We should have an autoconf check for OpenCryptoki and such
71 * things. However, there's no AC_CHECK_OBJECT(), and we'd have to
72 * write one. Today I'm feeling lazy. Another possibility would be to
73 * have a symlink from the libdir we'll install into, and then we could
74 * dlopen() that on all platforms.
76 * XXX Also, we should pick an appropriate shared object based on 32- vs
79 # define PKCS11_MODULE_PATH "/usr/lib/pkcs11/PKCS11_API.so"
82 static CK_FUNCTION_LIST_PTR p11_module
;
85 p11_cleanup(EVP_CIPHER_CTX
*ctx
);
87 struct pkcs11_cipher_ctx
{
88 CK_SESSION_HANDLE hSession
;
89 CK_OBJECT_HANDLE hSecret
;
93 struct pkcs11_md_ctx
{
94 CK_SESSION_HANDLE hSession
;
97 static void *pkcs11_module_handle
;
99 p11_module_init_once(void *context
)
102 CK_FUNCTION_LIST_PTR module
;
103 CK_RV (*C_GetFunctionList_fn
)(CK_FUNCTION_LIST_PTR_PTR
);
104 char *pkcs11ModulePath
= secure_getenv("PKCS11_MODULE_PATH");
106 if (pkcs11ModulePath
!= NULL
) {
107 pkcs11_module_handle
=
108 dlopen(pkcs11ModulePath
,
109 RTLD_LAZY
| RTLD_LOCAL
| RTLD_GROUP
| RTLD_NODELETE
);
110 if (pkcs11_module_handle
== NULL
)
111 fprintf(stderr
, "p11_module_init(%s): %s\n", pkcs11ModulePath
, dlerror());
113 #ifdef PKCS11_MODULE_PATH
114 if (pkcs11_module_handle
== NULL
) {
115 pkcs11_module_handle
=
116 dlopen(PKCS11_MODULE_PATH
,
117 RTLD_LAZY
| RTLD_LOCAL
| RTLD_GROUP
| RTLD_NODELETE
);
118 if (pkcs11_module_handle
== NULL
)
119 fprintf(stderr
, "p11_module_init(%s): %s\n", PKCS11_MODULE_PATH
, dlerror());
122 if (pkcs11_module_handle
== NULL
)
125 C_GetFunctionList_fn
= (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR
))
126 dlsym(pkcs11_module_handle
, "C_GetFunctionList");
127 if (C_GetFunctionList_fn
== NULL
)
130 rv
= C_GetFunctionList_fn(&module
);
134 rv
= module
->C_Initialize(NULL
);
135 if (rv
== CKR_CRYPTOKI_ALREADY_INITIALIZED
)
138 *((CK_FUNCTION_LIST_PTR_PTR
)context
) = module
;
141 if (pkcs11_module_handle
!= NULL
&& p11_module
== NULL
) {
142 dlclose(pkcs11_module_handle
);
143 pkcs11_module_handle
= NULL
;
145 /* else leak pkcs11_module_handle */
149 p11_module_init(void)
151 static heim_base_once_t init_module
= HEIM_BASE_ONCE_INIT
;
153 heim_base_once_f(&init_module
, &p11_module
, p11_module_init_once
);
155 return p11_module
!= NULL
? CKR_OK
: CKR_LIBRARY_LOAD_FAILED
;
159 p11_session_init(CK_MECHANISM_TYPE mechanismType
, CK_SESSION_HANDLE_PTR phSession
)
162 CK_ULONG i
, ulSlotCount
= 0;
163 CK_SLOT_ID_PTR pSlotList
= NULL
;
164 CK_MECHANISM_INFO info
;
166 if (phSession
!= NULL
)
167 *phSession
= CK_INVALID_HANDLE
;
169 rv
= p11_module_init();
173 assert(p11_module
!= NULL
);
175 rv
= p11_module
->C_GetSlotList(CK_FALSE
, NULL
, &ulSlotCount
);
179 pSlotList
= (CK_SLOT_ID_PTR
)calloc(ulSlotCount
, sizeof(CK_SLOT_ID
));
180 if (pSlotList
== NULL
) {
181 rv
= CKR_HOST_MEMORY
;
185 rv
= p11_module
->C_GetSlotList(CK_FALSE
, pSlotList
, &ulSlotCount
);
190 * Note that this approach of using the first slot that supports the desired
191 * mechanism may not always be what the user wants (for example it may prefer
192 * software to hardware crypto). We're going to assume that this code will be
193 * principally used on Solaris (which has a meta-slot provider that sorts by
194 * hardware first) or in situations where the user can configure the slots in
195 * order of provider preference. In the future we should make this configurable.
197 for (i
= 0; i
< ulSlotCount
; i
++) {
198 rv
= p11_module
->C_GetMechanismInfo(pSlotList
[i
], mechanismType
, &info
);
203 if (i
== ulSlotCount
) {
204 rv
= CKR_MECHANISM_INVALID
;
208 if (phSession
!= NULL
) {
209 rv
= p11_module
->C_OpenSession(pSlotList
[i
], CKF_SERIAL_SESSION
, NULL
, NULL
, phSession
);
221 p11_mech_available_p(CK_MECHANISM_TYPE mechanismType
)
223 return p11_session_init(mechanismType
, NULL
) == CKR_OK
;
227 p11_key_type_for_mech(CK_MECHANISM_TYPE mechanismType
)
229 CK_KEY_TYPE keyType
= 0;
231 switch (mechanismType
) {
248 case CKM_CAMELLIA_CBC
:
249 keyType
= CKK_CAMELLIA
;
252 assert(0 && "Unknown PKCS#11 mechanism type");
260 p11_key_init(EVP_CIPHER_CTX
*ctx
,
261 const unsigned char *key
,
262 const unsigned char *iv
,
266 CK_BBOOL bFalse
= CK_FALSE
;
267 CK_BBOOL bTrue
= CK_TRUE
;
268 CK_MECHANISM_TYPE mechanismType
= (CK_MECHANISM_TYPE
)ctx
->cipher
->app_data
;
269 CK_KEY_TYPE keyType
= p11_key_type_for_mech(mechanismType
);
270 CK_OBJECT_CLASS objectClass
= CKO_SECRET_KEY
;
271 CK_ATTRIBUTE_TYPE op
= encp
? CKA_ENCRYPT
: CKA_DECRYPT
;
272 CK_ATTRIBUTE attributes
[] = {
273 { CKA_EXTRACTABLE
, &bFalse
, sizeof(bFalse
) },
274 { CKA_CLASS
, &objectClass
, sizeof(objectClass
) },
275 { CKA_KEY_TYPE
, &keyType
, sizeof(keyType
) },
276 { CKA_TOKEN
, &bFalse
, sizeof(bFalse
) },
277 { CKA_PRIVATE
, &bFalse
, sizeof(bFalse
) },
278 { CKA_SENSITIVE
, &bTrue
, sizeof(bTrue
) },
279 { CKA_VALUE
, (void *)key
, ctx
->key_len
},
280 { op
, &bTrue
, sizeof(bTrue
) }
282 struct pkcs11_cipher_ctx
*p11ctx
= (struct pkcs11_cipher_ctx
*)ctx
->cipher_data
;
283 p11ctx
->cipher_init_done
= 0;
285 rv
= p11_session_init(mechanismType
, &p11ctx
->hSession
);
289 assert(p11_module
!= NULL
);
291 rv
= p11_module
->C_CreateObject(p11ctx
->hSession
, attributes
,
292 sizeof(attributes
) / sizeof(attributes
[0]),
305 p11_do_cipher(EVP_CIPHER_CTX
*ctx
,
307 const unsigned char *in
,
310 struct pkcs11_cipher_ctx
*p11ctx
= (struct pkcs11_cipher_ctx
*)ctx
->cipher_data
;
312 CK_ULONG ulCipherTextLen
= size
;
313 CK_MECHANISM_TYPE mechanismType
= (CK_MECHANISM_TYPE
)ctx
->cipher
->app_data
;
314 CK_MECHANISM mechanism
= {
316 ctx
->cipher
->iv_len
? ctx
->iv
: NULL
,
320 assert(p11_module
!= NULL
);
321 /* The EVP layer only ever calls us with complete cipher blocks */
322 assert(EVP_CIPHER_CTX_mode(ctx
) == EVP_CIPH_STREAM_CIPHER
||
323 (size
% ctx
->cipher
->block_size
) == 0);
326 if (!p11ctx
->cipher_init_done
) {
327 rv
= p11_module
->C_EncryptInit(p11ctx
->hSession
, &mechanism
, p11ctx
->hSecret
);
329 p11ctx
->cipher_init_done
= 1;
332 rv
= p11_module
->C_EncryptUpdate(p11ctx
->hSession
, (unsigned char *)in
, size
, out
, &ulCipherTextLen
);
334 if (!p11ctx
->cipher_init_done
) {
335 rv
= p11_module
->C_DecryptInit(p11ctx
->hSession
, &mechanism
, p11ctx
->hSecret
);
337 p11ctx
->cipher_init_done
= 1;
340 rv
= p11_module
->C_DecryptUpdate(p11ctx
->hSession
, (unsigned char *)in
, size
, out
, &ulCipherTextLen
);
347 p11_cleanup(EVP_CIPHER_CTX
*ctx
)
349 struct pkcs11_cipher_ctx
*p11ctx
= (struct pkcs11_cipher_ctx
*)ctx
->cipher_data
;
351 assert(p11_module
!= NULL
);
353 if (p11ctx
->hSecret
!= CK_INVALID_HANDLE
) {
354 p11_module
->C_DestroyObject(p11ctx
->hSession
, p11ctx
->hSecret
);
355 p11ctx
->hSecret
= CK_INVALID_HANDLE
;
357 if (p11ctx
->hSession
!= CK_INVALID_HANDLE
) {
358 p11_module
->C_CloseSession(p11ctx
->hSession
);
359 p11ctx
->hSession
= CK_INVALID_HANDLE
;
366 p11_md_hash_init(CK_MECHANISM_TYPE mechanismType
, EVP_MD_CTX
*ctx
)
368 struct pkcs11_md_ctx
*p11ctx
= (struct pkcs11_md_ctx
*)ctx
;
371 rv
= p11_session_init(mechanismType
, &p11ctx
->hSession
);
373 CK_MECHANISM mechanism
= { mechanismType
, NULL
, 0 };
375 assert(p11_module
!= NULL
);
377 rv
= p11_module
->C_DigestInit(p11ctx
->hSession
, &mechanism
);
384 p11_md_update(EVP_MD_CTX
*ctx
, const void *data
, size_t length
)
386 struct pkcs11_md_ctx
*p11ctx
= (struct pkcs11_md_ctx
*)ctx
;
389 assert(p11_module
!= NULL
);
391 rv
= p11_module
->C_DigestUpdate(p11ctx
->hSession
, (unsigned char *)data
, length
);
397 p11_md_final(void *digest
, EVP_MD_CTX
*ctx
)
399 struct pkcs11_md_ctx
*p11ctx
= (struct pkcs11_md_ctx
*)ctx
;
401 CK_ULONG digestLen
= 0;
403 assert(p11_module
!= NULL
);
405 rv
= p11_module
->C_DigestFinal(p11ctx
->hSession
, NULL
, &digestLen
);
407 rv
= p11_module
->C_DigestFinal(p11ctx
->hSession
, digest
, &digestLen
);
413 p11_md_cleanup(EVP_MD_CTX
*ctx
)
415 struct pkcs11_md_ctx
*p11ctx
= (struct pkcs11_md_ctx
*)ctx
;
418 assert(p11_module
!= NULL
);
420 rv
= p11_module
->C_CloseSession(p11ctx
->hSession
);
422 p11ctx
->hSession
= CK_INVALID_HANDLE
;
427 #define PKCS11_CIPHER_ALGORITHM(name, mechanismType, block_size, \
428 key_len, iv_len, flags) \
440 sizeof(struct pkcs11_cipher_ctx), \
444 (void *)mechanismType \
448 hc_EVP_pkcs11_##name(void) \
450 if (p11_mech_available_p(mechanismType)) \
451 return &pkcs11_##name; \
457 pkcs11_hcrypto_##name##_init_once(void *context) \
459 const EVP_CIPHER *cipher; \
461 cipher = hc_EVP_pkcs11_ ##name(); \
462 if (cipher == NULL && HCRYPTO_FALLBACK) \
463 cipher = hc_EVP_hcrypto_ ##name(); \
465 *((const EVP_CIPHER **)context) = cipher; \
469 hc_EVP_pkcs11_hcrypto_##name(void) \
471 static const EVP_CIPHER *__cipher; \
472 static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \
474 heim_base_once_f(&__init, &__cipher, \
475 pkcs11_hcrypto_##name##_init_once); \
480 #define PKCS11_MD_ALGORITHM(name, mechanismType, hash_size, block_size) \
482 static int p11_##name##_init(EVP_MD_CTX *ctx) \
484 return p11_md_hash_init(mechanismType, ctx); \
488 hc_EVP_pkcs11_##name(void) \
490 static struct hc_evp_md name = { \
493 sizeof(struct pkcs11_md_ctx), \
500 if (p11_mech_available_p(mechanismType)) \
507 pkcs11_hcrypto_##name##_init_once(void *context) \
511 md = hc_EVP_pkcs11_ ##name(); \
512 if (md == NULL && HCRYPTO_FALLBACK) \
513 md = hc_EVP_hcrypto_ ##name(); \
515 *((const EVP_MD **)context) = md; \
519 hc_EVP_pkcs11_hcrypto_##name(void) \
521 static const EVP_MD *__md; \
522 static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \
524 heim_base_once_f(&__init, &__md, \
525 pkcs11_hcrypto_##name##_init_once); \
530 #define PKCS11_MD_ALGORITHM_UNAVAILABLE(name) \
533 hc_EVP_pkcs11_##name(void) \
539 hc_EVP_pkcs11_hcrypto_##name(void) \
541 return hc_EVP_hcrypto_ ##name(); \
545 * The triple DES cipher type (PKCS#11 provider)
547 * @return the DES-EDE3-CBC EVP_CIPHER pointer.
549 * @ingroup hcrypto_evp
552 PKCS11_CIPHER_ALGORITHM(des_ede3_cbc
,
560 * The DES cipher type (PKCS#11 provider)
562 * @return the DES-CBC EVP_CIPHER pointer.
564 * @ingroup hcrypto_evp
567 PKCS11_CIPHER_ALGORITHM(des_cbc
,
575 * The AES-128 cipher type (PKCS#11 provider)
577 * @return the AES-128-CBC EVP_CIPHER pointer.
579 * @ingroup hcrypto_evp
582 PKCS11_CIPHER_ALGORITHM(aes_128_cbc
,
590 * The AES-192 cipher type (PKCS#11 provider)
592 * @return the AES-192-CBC EVP_CIPHER pointer.
594 * @ingroup hcrypto_evp
597 PKCS11_CIPHER_ALGORITHM(aes_192_cbc
,
605 * The AES-256 cipher type (PKCS#11 provider)
607 * @return the AES-256-CBC EVP_CIPHER pointer.
609 * @ingroup hcrypto_evp
612 PKCS11_CIPHER_ALGORITHM(aes_256_cbc
,
620 * The AES-128 CFB8 cipher type (PKCS#11 provider)
622 * @return the AES-128-CFB8 EVP_CIPHER pointer.
624 * @ingroup hcrypto_evp
627 PKCS11_CIPHER_ALGORITHM(aes_128_cfb8
,
635 * The AES-192 CFB8 cipher type (PKCS#11 provider)
637 * @return the AES-192-CFB8 EVP_CIPHER pointer.
639 * @ingroup hcrypto_evp
642 PKCS11_CIPHER_ALGORITHM(aes_192_cfb8
,
650 * The AES-256 CFB8 cipher type (PKCS#11 provider)
652 * @return the AES-256-CFB8 EVP_CIPHER pointer.
654 * @ingroup hcrypto_evp
657 PKCS11_CIPHER_ALGORITHM(aes_256_cfb8
,
665 * The RC2 cipher type - PKCS#11
667 * @return the RC2 EVP_CIPHER pointer.
669 * @ingroup hcrypto_evp
672 PKCS11_CIPHER_ALGORITHM(rc2_cbc
,
677 EVP_CIPH_CBC_MODE
| EVP_CIPH_VARIABLE_LENGTH
)
680 * The RC2-40 cipher type - PKCS#11
682 * @return the RC2-40 EVP_CIPHER pointer.
684 * @ingroup hcrypto_evp
687 PKCS11_CIPHER_ALGORITHM(rc2_40_cbc
,
695 * The RC2-64 cipher type - PKCS#11
697 * @return the RC2-64 EVP_CIPHER pointer.
699 * @ingroup hcrypto_evp
702 PKCS11_CIPHER_ALGORITHM(rc2_64_cbc
,
710 * The Camellia-128 cipher type - PKCS#11
712 * @return the Camellia-128 EVP_CIPHER pointer.
714 * @ingroup hcrypto_evp
717 PKCS11_CIPHER_ALGORITHM(camellia_128_cbc
,
725 * The Camellia-198 cipher type - PKCS#11
727 * @return the Camellia-198 EVP_CIPHER pointer.
729 * @ingroup hcrypto_evp
732 PKCS11_CIPHER_ALGORITHM(camellia_192_cbc
,
740 * The Camellia-256 cipher type - PKCS#11
742 * @return the Camellia-256 EVP_CIPHER pointer.
744 * @ingroup hcrypto_evp
747 PKCS11_CIPHER_ALGORITHM(camellia_256_cbc
,
755 * The RC4 cipher type (PKCS#11 provider)
757 * @return the RC4 EVP_CIPHER pointer.
759 * @ingroup hcrypto_evp
762 PKCS11_CIPHER_ALGORITHM(rc4
,
767 EVP_CIPH_STREAM_CIPHER
| EVP_CIPH_VARIABLE_LENGTH
)
770 * The RC4-40 cipher type (PKCS#11 provider)
772 * @return the RC4 EVP_CIPHER pointer.
774 * @ingroup hcrypto_evp
777 PKCS11_CIPHER_ALGORITHM(rc4_40
,
782 EVP_CIPH_STREAM_CIPHER
| EVP_CIPH_VARIABLE_LENGTH
)
784 PKCS11_MD_ALGORITHM(md2
, CKM_MD2
, 16, 16)
785 #ifdef CKM_MD4 /* non-standard extension */
786 PKCS11_MD_ALGORITHM(md4
, CKM_MD4
, 16, 64)
788 PKCS11_MD_ALGORITHM_UNAVAILABLE(md4
)
790 PKCS11_MD_ALGORITHM(md5
, CKM_MD5
, 16, 64)
791 PKCS11_MD_ALGORITHM(sha1
, CKM_SHA_1
, 20, 64)
792 PKCS11_MD_ALGORITHM(sha256
, CKM_SHA256
, 32, 64)
793 PKCS11_MD_ALGORITHM(sha384
, CKM_SHA384
, 48, 128)
794 PKCS11_MD_ALGORITHM(sha512
, CKM_SHA512
, 64, 128)