Fixes https://github.com/heimdal/heimdal/issues/294
[heimdal.git] / lib / hcrypto / evp-pkcs11.c
blob3bfec76b6fec8c388179695c0f7b2079a5bfaad5
1 /*
2 * Copyright (c) 2015-2016, Secure Endpoints Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
15 * distribution.
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 */
33 #include <config.h>
34 #include <roken.h>
35 #include <assert.h>
36 #ifdef HAVE_DLFCN_H
37 #include <dlfcn.h>
38 #ifndef RTLD_LAZY
39 #define RTLD_LAZY 0
40 #endif
41 #ifndef RTLD_LOCAL
42 #define RTLD_LOCAL 0
43 #endif
44 #ifndef RTLD_GROUP
45 #define RTLD_GROUP 0
46 #endif
47 #ifndef RTLD_NODELETE
48 #define RTLD_NODELETE 0
49 #endif
50 #else
51 #error PKCS11 support requires dlfcn.h
52 #endif
54 #include <heimbase.h>
56 #include <evp.h>
57 #include <evp-hcrypto.h>
58 #include <evp-pkcs11.h>
60 #include <ref/pkcs11.h>
62 #if __sun && !defined(PKCS11_MODULE_PATH)
63 # if _LP64
64 # define PKCS11_MODULE_PATH "/usr/lib/64/libpkcs11.so"
65 # else
66 # define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so"
67 # endif
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
77 * 64-bits.
79 # define PKCS11_MODULE_PATH "/usr/lib/pkcs11/PKCS11_API.so"
80 #endif
82 static CK_FUNCTION_LIST_PTR p11_module;
84 static int
85 p11_cleanup(EVP_CIPHER_CTX *ctx);
87 struct pkcs11_cipher_ctx {
88 CK_SESSION_HANDLE hSession;
89 CK_OBJECT_HANDLE hSecret;
90 int cipher_init_done;
93 struct pkcs11_md_ctx {
94 CK_SESSION_HANDLE hSession;
97 static void *pkcs11_module_handle;
98 static void
99 p11_module_init_once(void *context)
101 CK_RV rv;
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());
121 #endif
122 if (pkcs11_module_handle == NULL)
123 goto cleanup;
125 C_GetFunctionList_fn = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
126 dlsym(pkcs11_module_handle, "C_GetFunctionList");
127 if (C_GetFunctionList_fn == NULL)
128 goto cleanup;
130 rv = C_GetFunctionList_fn(&module);
131 if (rv != CKR_OK)
132 goto cleanup;
134 rv = module->C_Initialize(NULL);
135 if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
136 rv = CKR_OK;
137 if (rv == CKR_OK)
138 *((CK_FUNCTION_LIST_PTR_PTR)context) = module;
140 cleanup:
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 */
148 static CK_RV
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;
158 static CK_RV
159 p11_session_init(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE_PTR phSession)
161 CK_RV rv;
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();
170 if (rv != CKR_OK)
171 goto cleanup;
173 assert(p11_module != NULL);
175 rv = p11_module->C_GetSlotList(CK_FALSE, NULL, &ulSlotCount);
176 if (rv != CKR_OK)
177 goto cleanup;
179 pSlotList = (CK_SLOT_ID_PTR)calloc(ulSlotCount, sizeof(CK_SLOT_ID));
180 if (pSlotList == NULL) {
181 rv = CKR_HOST_MEMORY;
182 goto cleanup;
185 rv = p11_module->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
186 if (rv != CKR_OK)
187 goto cleanup;
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);
199 if (rv == CKR_OK)
200 break;
203 if (i == ulSlotCount) {
204 rv = CKR_MECHANISM_INVALID;
205 goto cleanup;
208 if (phSession != NULL) {
209 rv = p11_module->C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, NULL, NULL, phSession);
210 if (rv != CKR_OK)
211 goto cleanup;
214 cleanup:
215 free(pSlotList);
217 return rv;
220 static int
221 p11_mech_available_p(CK_MECHANISM_TYPE mechanismType)
223 return p11_session_init(mechanismType, NULL) == CKR_OK;
226 static CK_KEY_TYPE
227 p11_key_type_for_mech(CK_MECHANISM_TYPE mechanismType)
229 CK_KEY_TYPE keyType = 0;
231 switch (mechanismType) {
232 case CKM_RC2_CBC:
233 keyType = CKK_RC2;
234 break;
235 case CKM_RC4:
236 keyType = CKK_RC4;
237 break;
238 case CKM_DES_CBC:
239 keyType = CKK_DES;
240 break;
241 case CKM_DES3_CBC:
242 keyType = CKK_DES3;
243 break;
244 case CKM_AES_CBC:
245 case CKM_AES_CFB8:
246 keyType = CKK_AES;
247 break;
248 case CKM_CAMELLIA_CBC:
249 keyType = CKK_CAMELLIA;
250 break;
251 default:
252 assert(0 && "Unknown PKCS#11 mechanism type");
253 break;
256 return keyType;
259 static int
260 p11_key_init(EVP_CIPHER_CTX *ctx,
261 const unsigned char *key,
262 const unsigned char *iv,
263 int encp)
265 CK_RV rv;
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);
286 if (rv != CKR_OK)
287 goto cleanup;
289 assert(p11_module != NULL);
291 rv = p11_module->C_CreateObject(p11ctx->hSession, attributes,
292 sizeof(attributes) / sizeof(attributes[0]),
293 &p11ctx->hSecret);
294 if (rv != CKR_OK)
295 goto cleanup;
297 cleanup:
298 if (rv != CKR_OK)
299 p11_cleanup(ctx);
301 return rv == CKR_OK;
304 static int
305 p11_do_cipher(EVP_CIPHER_CTX *ctx,
306 unsigned char *out,
307 const unsigned char *in,
308 unsigned int size)
310 struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
311 CK_RV rv = CKR_OK;
312 CK_ULONG ulCipherTextLen = size;
313 CK_MECHANISM_TYPE mechanismType = (CK_MECHANISM_TYPE)ctx->cipher->app_data;
314 CK_MECHANISM mechanism = {
315 mechanismType,
316 ctx->cipher->iv_len ? ctx->iv : NULL,
317 ctx->cipher->iv_len
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);
325 if (ctx->encrypt) {
326 if (!p11ctx->cipher_init_done) {
327 rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
328 if (rv == CKR_OK)
329 p11ctx->cipher_init_done = 1;
331 if (rv == CKR_OK)
332 rv = p11_module->C_EncryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
333 } else {
334 if (!p11ctx->cipher_init_done) {
335 rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
336 if (rv == CKR_OK)
337 p11ctx->cipher_init_done = 1;
339 if (rv == CKR_OK)
340 rv = p11_module->C_DecryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
343 return rv == CKR_OK;
346 static int
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;
362 return 1;
365 static int
366 p11_md_hash_init(CK_MECHANISM_TYPE mechanismType, EVP_MD_CTX *ctx)
368 struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
369 CK_RV rv;
371 rv = p11_session_init(mechanismType, &p11ctx->hSession);
372 if (rv == CKR_OK) {
373 CK_MECHANISM mechanism = { mechanismType, NULL, 0 };
375 assert(p11_module != NULL);
377 rv = p11_module->C_DigestInit(p11ctx->hSession, &mechanism);
380 return rv == CKR_OK;
383 static int
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;
387 CK_RV rv;
389 assert(p11_module != NULL);
391 rv = p11_module->C_DigestUpdate(p11ctx->hSession, (unsigned char *)data, length);
393 return rv == CKR_OK;
396 static int
397 p11_md_final(void *digest, EVP_MD_CTX *ctx)
399 struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
400 CK_RV rv;
401 CK_ULONG digestLen = 0;
403 assert(p11_module != NULL);
405 rv = p11_module->C_DigestFinal(p11ctx->hSession, NULL, &digestLen);
406 if (rv == CKR_OK)
407 rv = p11_module->C_DigestFinal(p11ctx->hSession, digest, &digestLen);
409 return rv == CKR_OK;
412 static int
413 p11_md_cleanup(EVP_MD_CTX *ctx)
415 struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
416 CK_RV rv;
418 assert(p11_module != NULL);
420 rv = p11_module->C_CloseSession(p11ctx->hSession);
421 if (rv == CKR_OK)
422 p11ctx->hSession = CK_INVALID_HANDLE;
424 return rv == CKR_OK;
427 #define PKCS11_CIPHER_ALGORITHM(name, mechanismType, block_size, \
428 key_len, iv_len, flags) \
430 static EVP_CIPHER \
431 pkcs11_##name = { \
432 0, \
433 block_size, \
434 key_len, \
435 iv_len, \
436 flags, \
437 p11_key_init, \
438 p11_do_cipher, \
439 p11_cleanup, \
440 sizeof(struct pkcs11_cipher_ctx), \
441 NULL, \
442 NULL, \
443 NULL, \
444 (void *)mechanismType \
445 }; \
447 const EVP_CIPHER * \
448 hc_EVP_pkcs11_##name(void) \
450 if (p11_mech_available_p(mechanismType)) \
451 return &pkcs11_##name; \
452 else \
453 return NULL; \
456 static void \
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; \
468 const EVP_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); \
477 return __cipher; \
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); \
487 const EVP_MD * \
488 hc_EVP_pkcs11_##name(void) \
490 static struct hc_evp_md name = { \
491 hash_size, \
492 block_size, \
493 sizeof(struct pkcs11_md_ctx), \
494 p11_##name##_init, \
495 p11_md_update, \
496 p11_md_final, \
497 p11_md_cleanup \
498 }; \
500 if (p11_mech_available_p(mechanismType)) \
501 return &name; \
502 else \
503 return NULL; \
506 static void \
507 pkcs11_hcrypto_##name##_init_once(void *context) \
509 const EVP_MD *md; \
511 md = hc_EVP_pkcs11_ ##name(); \
512 if (md == NULL && HCRYPTO_FALLBACK) \
513 md = hc_EVP_hcrypto_ ##name(); \
515 *((const EVP_MD **)context) = md; \
518 const EVP_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); \
527 return __md; \
530 #define PKCS11_MD_ALGORITHM_UNAVAILABLE(name) \
532 const EVP_MD * \
533 hc_EVP_pkcs11_##name(void) \
535 return NULL; \
538 const EVP_MD * \
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,
553 CKM_DES3_CBC,
557 EVP_CIPH_CBC_MODE)
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,
568 CKM_DES_CBC,
572 EVP_CIPH_CBC_MODE)
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,
583 CKM_AES_CBC,
587 EVP_CIPH_CBC_MODE)
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,
598 CKM_AES_CBC,
602 EVP_CIPH_CBC_MODE)
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,
613 CKM_AES_CBC,
617 EVP_CIPH_CBC_MODE)
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,
628 CKM_AES_CFB8,
632 EVP_CIPH_CFB8_MODE)
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,
643 CKM_AES_CFB8,
647 EVP_CIPH_CFB8_MODE)
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,
658 CKM_AES_CFB8,
662 EVP_CIPH_CFB8_MODE)
665 * The RC2 cipher type - PKCS#11
667 * @return the RC2 EVP_CIPHER pointer.
669 * @ingroup hcrypto_evp
672 PKCS11_CIPHER_ALGORITHM(rc2_cbc,
673 CKM_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,
688 CKM_RC2_CBC,
692 EVP_CIPH_CBC_MODE)
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,
703 CKM_RC2_CBC,
707 EVP_CIPH_CBC_MODE)
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,
718 CKM_CAMELLIA_CBC,
722 EVP_CIPH_CBC_MODE)
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,
733 CKM_CAMELLIA_CBC,
737 EVP_CIPH_CBC_MODE)
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,
748 CKM_CAMELLIA_CBC,
752 EVP_CIPH_CBC_MODE)
755 * The RC4 cipher type (PKCS#11 provider)
757 * @return the RC4 EVP_CIPHER pointer.
759 * @ingroup hcrypto_evp
762 PKCS11_CIPHER_ALGORITHM(rc4,
763 CKM_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,
778 CKM_RC4,
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)
787 #else
788 PKCS11_MD_ALGORITHM_UNAVAILABLE(md4)
789 #endif
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)