diff options
Diffstat (limited to 'third_party/heimdal/lib/hcrypto/evp-pkcs11.c')
-rw-r--r-- | third_party/heimdal/lib/hcrypto/evp-pkcs11.c | 832 |
1 files changed, 832 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/hcrypto/evp-pkcs11.c b/third_party/heimdal/lib/hcrypto/evp-pkcs11.c new file mode 100644 index 00000000000..b44871fa4c4 --- /dev/null +++ b/third_party/heimdal/lib/hcrypto/evp-pkcs11.c @@ -0,0 +1,832 @@ +/* + * Copyright (c) 2015-2016, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* PKCS#11 provider */ + +#include <config.h> +#include <roken.h> +#include <assert.h> + +#ifndef HAVE_DLFCN_H +#error PKCS11 support requires dlfcn.h +#endif + +#include <heimbase.h> + +#include <evp.h> +#include <evp-hcrypto.h> +#include <evp-pkcs11.h> + +#include <ref/pkcs11.h> + +#if __sun && !defined(PKCS11_MODULE_PATH) +# ifdef _LP64 +# define PKCS11_MODULE_PATH "/usr/lib/64/libpkcs11.so" +# else +# define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so" +# endif +#elif defined(__linux__) +/* + * XXX We should have an autoconf check for OpenCryptoki and such + * things. However, there's no AC_CHECK_OBJECT(), and we'd have to + * write one. Today I'm feeling lazy. Another possibility would be to + * have a symlink from the libdir we'll install into, and then we could + * dlopen() that on all platforms. + * + * XXX Also, we should pick an appropriate shared object based on 32- vs + * 64-bits. + */ +# define PKCS11_MODULE_PATH "/usr/lib/pkcs11/PKCS11_API.so" +#endif + +static CK_FUNCTION_LIST_PTR p11_module; + +static int +p11_cleanup(EVP_CIPHER_CTX *ctx); + +struct pkcs11_cipher_ctx { + CK_SESSION_HANDLE hSession; + CK_OBJECT_HANDLE hSecret; +}; + +struct pkcs11_md_ctx { + CK_SESSION_HANDLE hSession; +}; + +static void *pkcs11_module_handle; + +static CK_RV +p11_module_load(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) +{ + CK_RV rv; + CK_RV (*C_GetFunctionList_fn)(CK_FUNCTION_LIST_PTR_PTR); + char *pkcs11ModulePath = secure_getenv("PKCS11_MODULE_PATH"); + + *ppFunctionList = NULL; + + if (pkcs11ModulePath != NULL) { + pkcs11_module_handle = + dlopen(pkcs11ModulePath, + RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP | RTLD_NODELETE); + if (pkcs11_module_handle == NULL) + fprintf(stderr, "p11_module_load(%s): %s\n", pkcs11ModulePath, dlerror()); + } +#ifdef PKCS11_MODULE_PATH + if (pkcs11_module_handle == NULL) { + pkcs11_module_handle = + dlopen(PKCS11_MODULE_PATH, + RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP | RTLD_NODELETE); + if (pkcs11_module_handle == NULL) + fprintf(stderr, "p11_module_load(%s): %s\n", PKCS11_MODULE_PATH, dlerror()); + } +#endif + if (pkcs11_module_handle == NULL) + return CKR_LIBRARY_LOAD_FAILED; + + C_GetFunctionList_fn = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) + dlsym(pkcs11_module_handle, "C_GetFunctionList"); + if (C_GetFunctionList_fn == NULL) { + dlclose(pkcs11_module_handle); + return CKR_LIBRARY_LOAD_FAILED; + } + + rv = C_GetFunctionList_fn(ppFunctionList); + if (rv != CKR_OK) { + dlclose(pkcs11_module_handle); + return rv; + } + + return CKR_OK; +} + +static void +p11_module_load_once(void *context) +{ + p11_module_load((CK_FUNCTION_LIST_PTR_PTR)context); +} + +static CK_RV +p11_module_init(void) +{ + static heim_base_once_t once = HEIM_BASE_ONCE_INIT; + CK_RV rv; + + heim_base_once_f(&once, &p11_module, p11_module_load_once); + + if (p11_module == NULL) + return CKR_LIBRARY_LOAD_FAILED; + + /* + * Call C_Initialize() on every call, because it will be invalid after fork(). + * Caching the initialization status using a once control and invalidating it + * on fork provided no measurable performance benefit on Solaris 11. Other + * approaches would not be thread-safe or would involve more intrusive code + * changes, such as exposing heimbase's atomics. + */ + rv = p11_module->C_Initialize(NULL); + if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) + rv = CKR_OK; + + return rv; +} + +static CK_RV +p11_session_init(CK_MECHANISM_TYPE mechanismType, + CK_SESSION_HANDLE_PTR phSession, + CK_FLAGS *pFlags) +{ + CK_RV rv; + CK_ULONG i, ulSlotCount = 0; + CK_SLOT_ID_PTR pSlotList = NULL; + CK_MECHANISM_INFO info; + + if (phSession != NULL) + *phSession = CK_INVALID_HANDLE; + + *pFlags = 0; + + rv = p11_module_init(); + if (rv != CKR_OK) + goto cleanup; + + assert(p11_module != NULL); + + rv = p11_module->C_GetSlotList(CK_FALSE, NULL, &ulSlotCount); + if (rv != CKR_OK) + goto cleanup; + + pSlotList = (CK_SLOT_ID_PTR)calloc(ulSlotCount, sizeof(CK_SLOT_ID)); + if (pSlotList == NULL) { + rv = CKR_HOST_MEMORY; + goto cleanup; + } + + rv = p11_module->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount); + if (rv != CKR_OK) + goto cleanup; + + /* + * Note that this approach of using the first slot that supports the desired + * mechanism may not always be what the user wants (for example it may prefer + * software to hardware crypto). We're going to assume that this code will be + * principally used on Solaris (which has a meta-slot provider that sorts by + * hardware first) or in situations where the user can configure the slots in + * order of provider preference. In the future we should make this configurable. + */ + for (i = 0; i < ulSlotCount; i++) { + rv = p11_module->C_GetMechanismInfo(pSlotList[i], mechanismType, &info); + if (rv == CKR_OK) { + *pFlags = info.flags; + break; + } + } + + if (i == ulSlotCount) { + rv = CKR_MECHANISM_INVALID; + goto cleanup; + } + + if (phSession != NULL) { + rv = p11_module->C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, NULL, NULL, phSession); + if (rv != CKR_OK) + goto cleanup; + } + +cleanup: + free(pSlotList); + + return rv; +} + +static int +p11_mech_available_p(CK_MECHANISM_TYPE mechanismType, CK_FLAGS reqFlags) +{ + CK_RV rv; + CK_FLAGS flags; + + rv = p11_session_init(mechanismType, NULL, &flags); + if (rv != CKR_OK) + return 0; + + return (flags & reqFlags) == reqFlags; +} + +static CK_KEY_TYPE +p11_key_type_for_mech(CK_MECHANISM_TYPE mechanismType) +{ + CK_KEY_TYPE keyType = 0; + + switch (mechanismType) { + case CKM_RC2_CBC: + keyType = CKK_RC2; + break; + case CKM_RC4: + keyType = CKK_RC4; + break; + case CKM_DES_CBC: + keyType = CKK_DES; + break; + case CKM_DES3_CBC: + keyType = CKK_DES3; + break; + case CKM_AES_CBC: + case CKM_AES_CFB8: + keyType = CKK_AES; + break; + case CKM_CAMELLIA_CBC: + keyType = CKK_CAMELLIA; + break; + default: + assert(0 && "Unknown PKCS#11 mechanism type"); + break; + } + + return keyType; +} + +static int +p11_key_init(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int encp) +{ + CK_RV rv; + CK_BBOOL bFalse = CK_FALSE; + CK_BBOOL bTrue = CK_TRUE; + CK_MECHANISM_TYPE mechanismType = (CK_MECHANISM_TYPE)ctx->cipher->app_data; + CK_KEY_TYPE keyType = p11_key_type_for_mech(mechanismType); + CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY; + CK_ATTRIBUTE_TYPE op = encp ? CKA_ENCRYPT : CKA_DECRYPT; + CK_ATTRIBUTE attributes[] = { + { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) }, + { CKA_CLASS, &objectClass, sizeof(objectClass) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_TOKEN, &bFalse, sizeof(bFalse) }, + { CKA_PRIVATE, &bFalse, sizeof(bFalse) }, + { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, + { CKA_VALUE, (void *)key, ctx->key_len }, + { op, &bTrue, sizeof(bTrue) } + }; + CK_MECHANISM mechanism = { + mechanismType, + ctx->cipher->iv_len ? ctx->iv : NULL, + ctx->cipher->iv_len + }; + struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data; + CK_FLAGS flags; + + rv = CKR_OK; + + if (p11ctx->hSession != CK_INVALID_HANDLE && key != NULL) + p11_cleanup(ctx); /* refresh session with new key */ + + if (p11ctx->hSession == CK_INVALID_HANDLE) { + rv = p11_session_init(mechanismType, &p11ctx->hSession, &flags); + if (rv != CKR_OK) + goto cleanup; + + if ((flags & (CKF_ENCRYPT|CKF_DECRYPT)) != (CKF_ENCRYPT|CKF_DECRYPT)) { + rv = CKR_MECHANISM_INVALID; + goto cleanup; + } + } + + if (key != NULL) { + assert(p11_module != NULL); + assert(p11ctx->hSecret == CK_INVALID_HANDLE); + + rv = p11_module->C_CreateObject(p11ctx->hSession, attributes, + sizeof(attributes) / sizeof(attributes[0]), + &p11ctx->hSecret); + if (rv != CKR_OK) + goto cleanup; + } + + if (p11ctx->hSecret != CK_INVALID_HANDLE) { + if (op == CKA_ENCRYPT) + rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret); + else + rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret); + if (rv != CKR_OK) + goto cleanup; + } + +cleanup: + if (rv != CKR_OK) + p11_cleanup(ctx); + + return rv == CKR_OK; +} + +static int +p11_do_cipher(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + unsigned int size) +{ + struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data; + CK_RV rv; + CK_ULONG ulCipherTextLen = size; + + assert(p11_module != NULL); + assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER || + (size % ctx->cipher->block_size) == 0); + + if (ctx->encrypt) + rv = p11_module->C_EncryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen); + else + rv = p11_module->C_DecryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen); + + return rv == CKR_OK; +} + +static int +p11_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data; + + if (p11ctx->hSecret != CK_INVALID_HANDLE) { + p11_module->C_DestroyObject(p11ctx->hSession, p11ctx->hSecret); + p11ctx->hSecret = CK_INVALID_HANDLE; + } + if (p11ctx->hSession != CK_INVALID_HANDLE) { + p11_module->C_CloseSession(p11ctx->hSession); + p11ctx->hSession = CK_INVALID_HANDLE; + } + + return 1; +} + +static int +p11_md_cleanup(EVP_MD_CTX *ctx); + +static int +p11_md_hash_init(CK_MECHANISM_TYPE mechanismType, EVP_MD_CTX *ctx) +{ + struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx; + CK_RV rv; + CK_FLAGS flags; + CK_MECHANISM mechanism = { mechanismType, NULL, 0 }; + + if (p11ctx->hSession != CK_INVALID_HANDLE) + p11_md_cleanup(ctx); + + rv = p11_session_init(mechanismType, &p11ctx->hSession, &flags); + if (rv != CKR_OK) + goto cleanup; + + if ((flags & CKF_DIGEST) != CKF_DIGEST) { + rv = CKR_MECHANISM_INVALID; + goto cleanup; + } + + assert(p11_module != NULL); + + rv = p11_module->C_DigestInit(p11ctx->hSession, &mechanism); + + cleanup: + return rv == CKR_OK; +} + +static int +p11_md_update(EVP_MD_CTX *ctx, const void *data, size_t length) +{ + struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx; + CK_RV rv; + + assert(p11_module != NULL); + assert(data != NULL || length == 0); + + rv = p11_module->C_DigestUpdate(p11ctx->hSession, + data ? (CK_BYTE_PTR)data : (CK_BYTE_PTR)"", + length); + + return rv == CKR_OK; +} + +static int +p11_md_final(void *digest, EVP_MD_CTX *ctx) +{ + struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx; + CK_RV rv; + CK_ULONG digestLen = 0; + + assert(p11_module != NULL); + + rv = p11_module->C_DigestFinal(p11ctx->hSession, NULL, &digestLen); + if (rv == CKR_OK) + rv = p11_module->C_DigestFinal(p11ctx->hSession, digest, &digestLen); + + return rv == CKR_OK; +} + +static int +p11_md_cleanup(EVP_MD_CTX *ctx) +{ + struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx; + CK_RV rv; + + assert(p11_module != NULL); + + rv = p11_module->C_CloseSession(p11ctx->hSession); + if (rv == CKR_OK) + p11ctx->hSession = CK_INVALID_HANDLE; + + return rv == CKR_OK; +} + +#define PKCS11_CIPHER_ALGORITHM(name, mechanismType, block_size, \ + key_len, iv_len, flags) \ + \ + static EVP_CIPHER \ + pkcs11_##name = { \ + 0, \ + block_size, \ + key_len, \ + iv_len, \ + (flags) | EVP_CIPH_ALWAYS_CALL_INIT, \ + p11_key_init, \ + p11_do_cipher, \ + p11_cleanup, \ + sizeof(struct pkcs11_cipher_ctx), \ + NULL, \ + NULL, \ + NULL, \ + (void *)mechanismType \ + }; \ + \ + const EVP_CIPHER * \ + hc_EVP_pkcs11_##name(void) \ + { \ + if (p11_mech_available_p(mechanismType, CKF_ENCRYPT|CKF_DECRYPT)) \ + return &pkcs11_##name; \ + else \ + return NULL; \ + } \ + \ + static void \ + pkcs11_hcrypto_##name##_init_once(void *context) \ + { \ + const EVP_CIPHER *cipher; \ + \ + cipher = hc_EVP_pkcs11_ ##name(); \ + if (cipher == NULL && HCRYPTO_FALLBACK) \ + cipher = hc_EVP_hcrypto_ ##name(); \ + \ + *((const EVP_CIPHER **)context) = cipher; \ + } \ + \ + const EVP_CIPHER * \ + hc_EVP_pkcs11_hcrypto_##name(void) \ + { \ + static const EVP_CIPHER *__cipher; \ + static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \ + \ + heim_base_once_f(&__init, &__cipher, \ + pkcs11_hcrypto_##name##_init_once); \ + \ + return __cipher; \ + } + +#define PKCS11_MD_ALGORITHM(name, mechanismType, hash_size, block_size) \ + \ + static int p11_##name##_init(EVP_MD_CTX *ctx) \ + { \ + return p11_md_hash_init(mechanismType, ctx); \ + } \ + \ + const EVP_MD * \ + hc_EVP_pkcs11_##name(void) \ + { \ + static struct hc_evp_md name = { \ + hash_size, \ + block_size, \ + sizeof(struct pkcs11_md_ctx), \ + p11_##name##_init, \ + p11_md_update, \ + p11_md_final, \ + p11_md_cleanup \ + }; \ + \ + if (p11_mech_available_p(mechanismType, CKF_DIGEST)) \ + return &name; \ + else \ + return NULL; \ + } \ + \ + static void \ + pkcs11_hcrypto_##name##_init_once(void *context) \ + { \ + const EVP_MD *md; \ + \ + md = hc_EVP_pkcs11_ ##name(); \ + if (md == NULL && HCRYPTO_FALLBACK) \ + md = hc_EVP_hcrypto_ ##name(); \ + \ + *((const EVP_MD **)context) = md; \ + } \ + \ + const EVP_MD * \ + hc_EVP_pkcs11_hcrypto_##name(void) \ + { \ + static const EVP_MD *__md; \ + static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \ + \ + heim_base_once_f(&__init, &__md, \ + pkcs11_hcrypto_##name##_init_once); \ + \ + return __md; \ + } + +#define PKCS11_MD_ALGORITHM_UNAVAILABLE(name) \ + \ + const EVP_MD * \ + hc_EVP_pkcs11_##name(void) \ + { \ + return NULL; \ + } \ + \ + const EVP_MD * \ + hc_EVP_pkcs11_hcrypto_##name(void) \ + { \ + return hc_EVP_hcrypto_ ##name(); \ + } + +/** + * The triple DES cipher type (PKCS#11 provider) + * + * @return the DES-EDE3-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(des_ede3_cbc, + CKM_DES3_CBC, + 8, + 24, + 8, + EVP_CIPH_CBC_MODE) + +/** + * The DES cipher type (PKCS#11 provider) + * + * @return the DES-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(des_cbc, + CKM_DES_CBC, + 8, + 8, + 8, + EVP_CIPH_CBC_MODE) + +/** + * The AES-128 cipher type (PKCS#11 provider) + * + * @return the AES-128-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_128_cbc, + CKM_AES_CBC, + 16, + 16, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The AES-192 cipher type (PKCS#11 provider) + * + * @return the AES-192-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_192_cbc, + CKM_AES_CBC, + 16, + 24, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The AES-256 cipher type (PKCS#11 provider) + * + * @return the AES-256-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_256_cbc, + CKM_AES_CBC, + 16, + 32, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The AES-128 CFB8 cipher type (PKCS#11 provider) + * + * @return the AES-128-CFB8 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_128_cfb8, + CKM_AES_CFB8, + 16, + 16, + 16, + EVP_CIPH_CFB8_MODE) + +/** + * The AES-192 CFB8 cipher type (PKCS#11 provider) + * + * @return the AES-192-CFB8 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_192_cfb8, + CKM_AES_CFB8, + 16, + 24, + 16, + EVP_CIPH_CFB8_MODE) + +/** + * The AES-256 CFB8 cipher type (PKCS#11 provider) + * + * @return the AES-256-CFB8 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(aes_256_cfb8, + CKM_AES_CFB8, + 16, + 32, + 16, + EVP_CIPH_CFB8_MODE) + +/** + * The RC2 cipher type - PKCS#11 + * + * @return the RC2 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(rc2_cbc, + CKM_RC2_CBC, + 8, + 16, + 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH) + +/** + * The RC2-40 cipher type - PKCS#11 + * + * @return the RC2-40 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(rc2_40_cbc, + CKM_RC2_CBC, + 8, + 5, + 8, + EVP_CIPH_CBC_MODE) + +/** + * The RC2-64 cipher type - PKCS#11 + * + * @return the RC2-64 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(rc2_64_cbc, + CKM_RC2_CBC, + 8, + 8, + 8, + EVP_CIPH_CBC_MODE) + +/** + * The Camellia-128 cipher type - PKCS#11 + * + * @return the Camellia-128 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(camellia_128_cbc, + CKM_CAMELLIA_CBC, + 16, + 16, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The Camellia-198 cipher type - PKCS#11 + * + * @return the Camellia-198 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(camellia_192_cbc, + CKM_CAMELLIA_CBC, + 16, + 24, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The Camellia-256 cipher type - PKCS#11 + * + * @return the Camellia-256 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(camellia_256_cbc, + CKM_CAMELLIA_CBC, + 16, + 32, + 16, + EVP_CIPH_CBC_MODE) + +/** + * The RC4 cipher type (PKCS#11 provider) + * + * @return the RC4 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(rc4, + CKM_RC4, + 1, + 16, + 0, + EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH) + +/** + * The RC4-40 cipher type (PKCS#11 provider) + * + * @return the RC4 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +PKCS11_CIPHER_ALGORITHM(rc4_40, + CKM_RC4, + 1, + 5, + 0, + EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH) + +PKCS11_MD_ALGORITHM(md2, CKM_MD2, 16, 16) +#ifdef CKM_MD4 /* non-standard extension */ +PKCS11_MD_ALGORITHM(md4, CKM_MD4, 16, 64) +#else +PKCS11_MD_ALGORITHM_UNAVAILABLE(md4) +#endif +PKCS11_MD_ALGORITHM(md5, CKM_MD5, 16, 64) +PKCS11_MD_ALGORITHM(sha1, CKM_SHA_1, 20, 64) +PKCS11_MD_ALGORITHM(sha256, CKM_SHA256, 32, 64) +PKCS11_MD_ALGORITHM(sha384, CKM_SHA384, 48, 128) +PKCS11_MD_ALGORITHM(sha512, CKM_SHA512, 64, 128) |