hcrypto: PKCS#11 backend
implement a PKCS#11 backend for hcrypto. tested with Solaris 11 and SoftHSM, this is now the default when building on Solaris.
This commit is contained in:
11
cf/crypto.m4
11
cf/crypto.m4
@@ -135,6 +135,17 @@ if test "$crypto_lib" = "unknown"; then
|
||||
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(pkcs11-module,
|
||||
AS_HELP_STRING([--with-pkcs11-module=path],
|
||||
[use PKCS11 module in path]),
|
||||
[pkcs11_module="$withval"],
|
||||
[])
|
||||
|
||||
if test "$pkcs11_module" != ""; then
|
||||
AC_DEFINE_UNQUOTED(PKCS11_MODULE_PATH, "$pkcs11_module", [path to PKCS11 module])
|
||||
openssl=no
|
||||
fi
|
||||
|
||||
if test "$openssl" = "yes"; then
|
||||
AC_DEFINE([HAVE_OPENSSL], 1, [define to use openssl's libcrypto])
|
||||
fi
|
||||
|
@@ -2,7 +2,8 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
AM_CPPFLAGS += -I$(srcdir)/libtommath -DUSE_HCRYPTO_LTM=1
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/lib/hx509 \
|
||||
-I$(srcdir)/libtommath -DUSE_HCRYPTO_LTM=1
|
||||
|
||||
lib_LTLIBRARIES = libhcrypto.la
|
||||
check_LTLIBRARIES = libhctest.la
|
||||
@@ -11,6 +12,7 @@ libhcrypto_la_LDFLAGS = -version-info 5:0:1
|
||||
libhcrypto_la_LIBADD = \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_dlopen) \
|
||||
$(LIB_heimbase) \
|
||||
$(LIBADD_roken)
|
||||
|
||||
hcryptoincludedir = $(includedir)/hcrypto
|
||||
@@ -29,6 +31,7 @@ hcryptoinclude_HEADERS = \
|
||||
evp.h \
|
||||
evp-hcrypto.h \
|
||||
evp-cc.h \
|
||||
evp-pkcs11.h \
|
||||
hmac.h \
|
||||
md2.h \
|
||||
md4.h \
|
||||
@@ -114,6 +117,7 @@ libhcrypto_la_SOURCES = \
|
||||
evp.h \
|
||||
evp-hcrypto.c \
|
||||
evp-cc.c \
|
||||
evp-pkcs11.c \
|
||||
engine.c \
|
||||
engine.h \
|
||||
hash.h \
|
||||
|
@@ -33,10 +33,17 @@ SUBDIRS=libtommath
|
||||
|
||||
RELDIR=lib\hcrypto
|
||||
|
||||
intcflags=-DKRB5 -DASN1_LIB -I$(HCRYPTOINCLUDEDIR) -DUSE_HCRYPTO_LTM=1
|
||||
|
||||
!include ../../windows/NTMakefile.w32
|
||||
|
||||
HCRYPTOINCLUDEDIR = $(INCDIR)\hcrypto
|
||||
|
||||
HEIMBASEDIR = $(SRC)\lib\base
|
||||
|
||||
HX509DIR = $(SRC)\lib\hx509
|
||||
|
||||
intcflags=-DKRB5 -DASN1_LIB -I$(HCRYPTOINCLUDEDIR) -DUSE_HCRYPTO_LTM=1 \
|
||||
-I$(HX509DIR)
|
||||
|
||||
# Do dependencies first
|
||||
|
||||
all:: subdirs
|
||||
@@ -47,8 +54,6 @@ test:: test-subdirs
|
||||
|
||||
# Include files
|
||||
|
||||
HCRYPTOINCLUDEDIR=$(INCDIR)\hcrypto
|
||||
|
||||
INCFILES= \
|
||||
$(HCRYPTOINCLUDEDIR)\aes.h \
|
||||
$(HCRYPTOINCLUDEDIR)\bn.h \
|
||||
@@ -62,6 +67,7 @@ INCFILES= \
|
||||
$(HCRYPTOINCLUDEDIR)\evp.h \
|
||||
$(HCRYPTOINCLUDEDIR)\evp-hcrypto.h \
|
||||
$(HCRYPTOINCLUDEDIR)\evp-cc.h \
|
||||
$(HCRYPTOINCLUDEDIR)\evp-pkcs11.h \
|
||||
$(HCRYPTOINCLUDEDIR)\evp-wincng.h \
|
||||
$(HCRYPTOINCLUDEDIR)\evp-w32.h \
|
||||
$(HCRYPTOINCLUDEDIR)\hmac.h \
|
||||
@@ -105,6 +111,7 @@ libhcrypto_OBJs = \
|
||||
$(OBJ)\evp.obj \
|
||||
$(OBJ)\evp-hcrypto.obj \
|
||||
$(OBJ)\evp-cc.obj \
|
||||
$(OBJ)\evp-pkcs11.obj \
|
||||
$(OBJ)\evp-wincng.obj \
|
||||
$(OBJ)\evp-w32.obj \
|
||||
$(OBJ)\engine.obj \
|
||||
@@ -165,63 +172,63 @@ test-binaries: \
|
||||
$(OBJ)\test_rand.exe \
|
||||
$(OBJ)\test_crypto.sh
|
||||
|
||||
$(OBJ)\destest.exe: $(OBJ)\destest.obj $(TESTLIB) $(LIBROKEN)
|
||||
$(OBJ)\destest.exe: $(OBJ)\destest.obj $(TESTLIB) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\example_evp_cipher.exe: $(OBJ)\example_evp_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\example_evp_cipher.exe: $(OBJ)\example_evp_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\mdtest.exe: $(OBJ)\mdtest.obj $(LIBHEIMDAL) $(LIBROKEN) $(OBJ)\sha512.obj
|
||||
$(OBJ)\mdtest.exe: $(OBJ)\mdtest.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(OBJ)\sha512.obj
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\rc2test.exe: $(OBJ)\rc2test.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\rc2test.exe: $(OBJ)\rc2test.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\rctest.exe: $(OBJ)\rctest.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\rctest.exe: $(OBJ)\rctest.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_bn.exe: $(OBJ)\test_bn.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\test_bn.exe: $(OBJ)\test_bn.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_bulk.exe: $(OBJ)\test_bulk.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_bulk.exe: $(OBJ)\test_bulk.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_cipher.exe: $(OBJ)\test_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_cipher.exe: $(OBJ)\test_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_engine_dso.exe: $(OBJ)\test_engine_dso.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_engine_dso.exe: $(OBJ)\test_engine_dso.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_hmac.exe: $(OBJ)\test_hmac.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\test_hmac.exe: $(OBJ)\test_hmac.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_pkcs5.exe: $(OBJ)\test_pkcs5.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\test_pkcs5.exe: $(OBJ)\test_pkcs5.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_pkcs12.exe: $(OBJ)\test_pkcs12.obj $(LIBHEIMDAL) $(LIBROKEN)
|
||||
$(OBJ)\test_pkcs12.exe: $(OBJ)\test_pkcs12.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_rsa.exe: $(OBJ)\test_rsa.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_rsa.exe: $(OBJ)\test_rsa.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_dh.exe: $(OBJ)\test_dh.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_dh.exe: $(OBJ)\test_dh.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_rand.exe: $(OBJ)\test_rand.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
|
||||
$(OBJ)\test_rand.exe: $(OBJ)\test_rand.obj $(LIBHEIMDAL) $(LIBROKEN) $(LIBHEIMBASE) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
|
775
lib/hcrypto/evp-pkcs11.c
Normal file
775
lib/hcrypto/evp-pkcs11.c
Normal file
@@ -0,0 +1,775 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 <assert.h>
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#ifndef RTLD_LAZY
|
||||
#define RTLD_LAZY 0
|
||||
#endif
|
||||
#ifndef RTLD_LOCAL
|
||||
#define RTLD_LOCAL 0
|
||||
#endif
|
||||
#ifndef RTLD_GROUP
|
||||
#define RTLD_GROUP 0
|
||||
#endif
|
||||
#ifndef RTLD_NODELETE
|
||||
#define RTLD_NODELETE 0
|
||||
#endif
|
||||
#else
|
||||
#error PKCS11 support requires dlfcn.h
|
||||
#endif
|
||||
|
||||
#include <roken.h>
|
||||
#include <heimbase.h>
|
||||
|
||||
#include <evp.h>
|
||||
#include <evp-hcrypto.h>
|
||||
#include <evp-pkcs11.h>
|
||||
|
||||
#include <ref/pkcs11.h>
|
||||
|
||||
#if __sun && !defined(PKCS11_MODULE_PATH)
|
||||
# if _LP64
|
||||
# define PKCS11_MODULE_PATH "/usr/lib/64/libpkcs11.so"
|
||||
# else
|
||||
# define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so"
|
||||
# endif
|
||||
#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
|
||||
p11_module_init_once(void *context)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_FUNCTION_LIST_PTR module;
|
||||
CK_RV (*C_GetFunctionList_fn)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
void *handle = NULL;
|
||||
|
||||
if (!issuid()) {
|
||||
char *pkcs11ModulePath = getenv("PKCS11_MODULE_PATH");
|
||||
if (pkcs11ModulePath != NULL) {
|
||||
handle = dlopen(pkcs11ModulePath, RTLD_LAZY | RTLD_LOCAL |
|
||||
RTLD_GROUP | RTLD_NODELETE);
|
||||
if (handle == NULL)
|
||||
fprintf(stderr, "p11_module_init(%s): %s\n", pkcs11ModulePath, dlerror());
|
||||
}
|
||||
}
|
||||
#ifdef PKCS11_MODULE_PATH
|
||||
if (handle == NULL) {
|
||||
handle = dlopen(PKCS11_MODULE_PATH, RTLD_LAZY | RTLD_LOCAL |
|
||||
RTLD_GROUP | RTLD_NODELETE);
|
||||
if (handle == NULL)
|
||||
fprintf(stderr, "p11_module_init(%s): %s\n", PKCS11_MODULE_PATH, dlerror());
|
||||
}
|
||||
#endif
|
||||
if (handle == NULL) {
|
||||
rv = CKR_LIBRARY_LOAD_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
C_GetFunctionList_fn = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
|
||||
dlsym(handle, "C_GetFunctionList");
|
||||
if (C_GetFunctionList_fn == NULL) {
|
||||
rv = CKR_LIBRARY_LOAD_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = C_GetFunctionList_fn(&module);
|
||||
if (rv != CKR_OK)
|
||||
goto cleanup;
|
||||
|
||||
rv = module->C_Initialize(NULL);
|
||||
if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
|
||||
rv = CKR_OK;
|
||||
if (rv == CKR_OK)
|
||||
*((CK_FUNCTION_LIST_PTR_PTR)context) = module;
|
||||
|
||||
cleanup:
|
||||
if (handle != NULL && p11_module == NULL)
|
||||
dlclose(handle);
|
||||
/* else leak handle */
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
p11_module_init(void)
|
||||
{
|
||||
static heim_base_once_t init_module = HEIM_BASE_ONCE_INIT;
|
||||
|
||||
heim_base_once_f(&init_module, &p11_module, p11_module_init_once);
|
||||
|
||||
return p11_module != NULL ? CKR_OK : CKR_LIBRARY_LOAD_FAILED;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
p11_session_init(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE_PTR phSession)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
return p11_session_init(mechanismType, NULL) == CKR_OK;
|
||||
}
|
||||
|
||||
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) }
|
||||
};
|
||||
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
||||
|
||||
rv = p11_session_init(mechanismType, &p11ctx->hSession);
|
||||
if (rv != CKR_OK)
|
||||
goto cleanup;
|
||||
|
||||
assert(p11_module != NULL);
|
||||
|
||||
rv = p11_module->C_CreateObject(p11ctx->hSession, attributes,
|
||||
sizeof(attributes) / sizeof(attributes[0]),
|
||||
&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;
|
||||
CK_MECHANISM_TYPE mechanismType = (CK_MECHANISM_TYPE)ctx->cipher->app_data;
|
||||
CK_MECHANISM mechanism = {
|
||||
mechanismType,
|
||||
ctx->cipher->iv_len ? ctx->iv : NULL,
|
||||
ctx->cipher->iv_len
|
||||
};
|
||||
|
||||
assert(p11_module != NULL);
|
||||
assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER ||
|
||||
(size % ctx->cipher->block_size) == 0);
|
||||
|
||||
/* We cannot use C_EncryptUpdate() as it may buffer the output. */
|
||||
if (ctx->encrypt) {
|
||||
rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
||||
if (rv == CKR_OK)
|
||||
rv = p11_module->C_Encrypt(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
|
||||
} else {
|
||||
rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
||||
if (rv == CKR_OK)
|
||||
rv = p11_module->C_Decrypt(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;
|
||||
|
||||
assert(p11_module != NULL);
|
||||
|
||||
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_hash_init(CK_MECHANISM_TYPE mechanismType, EVP_MD_CTX *ctx)
|
||||
{
|
||||
struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
|
||||
CK_RV rv;
|
||||
|
||||
rv = p11_session_init(mechanismType, &p11ctx->hSession);
|
||||
if (rv == CKR_OK) {
|
||||
CK_MECHANISM mechanism = { mechanismType, NULL, 0 };
|
||||
|
||||
assert(p11_module != NULL);
|
||||
|
||||
rv = p11_module->C_DigestInit(p11ctx->hSession, &mechanism);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
rv = p11_module->C_DigestUpdate(p11ctx->hSession, (unsigned char *)data, 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, \
|
||||
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)) \
|
||||
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) \
|
||||
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)) \
|
||||
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) \
|
||||
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)
|
||||
|
||||
/**
|
||||
* 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, 16)
|
||||
#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)
|
157
lib/hcrypto/evp-pkcs11.h
Normal file
157
lib/hcrypto/evp-pkcs11.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef HEIM_EVP_PKCS11_H
|
||||
#define HEIM_EVP_PKCS11_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
|
||||
#define EVP_pkcs11_md2() hc_EVP_pkcs11_md2()
|
||||
#define EVP_pkcs11_md4() hc_EVP_pkcs11_md4()
|
||||
#define EVP_pkcs11_md5() hc_EVP_pkcs11_md5()
|
||||
#define EVP_pkcs11_sha1() hc_EVP_pkcs11_sha1()
|
||||
#define EVP_pkcs11_sha256() hc_EVP_pkcs11_sha256()
|
||||
#define EVP_pkcs11_sha384() hc_EVP_pkcs11_sha384()
|
||||
#define EVP_pkcs11_sha512() hc_EVP_pkcs11_sha512()
|
||||
#define EVP_pkcs11_des_cbc() hc_EVP_pkcs11_des_cbc()
|
||||
#define EVP_pkcs11_des_ede3_cbc() hc_EVP_pkcs11_des_ede3_cbc()
|
||||
#define EVP_pkcs11_aes_128_cbc() hc_EVP_pkcs11_aes_128_cbc()
|
||||
#define EVP_pkcs11_aes_192_cbc() hc_EVP_pkcs11_aes_192_cbc()
|
||||
#define EVP_pkcs11_aes_256_cbc() hc_EVP_pkcs11_aes_256_cbc()
|
||||
#define EVP_pkcs11_aes_128_cfb8() hc_EVP_pkcs11_aes_128_cfb8()
|
||||
#define EVP_pkcs11_aes_192_cfb8() hc_EVP_pkcs11_aes_192_cfb8()
|
||||
#define EVP_pkcs11_aes_256_cfb8() hc_EVP_pkcs11_aes_256_cfb8()
|
||||
#define EVP_pkcs11_rc4() hc_EVP_pkcs11_rc4()
|
||||
#define EVP_pkcs11_rc4_40() hc_EVP_pkcs11_rc4_40()
|
||||
#define EVP_pkcs11_rc2_40_cbc() hc_EVP_pkcs11_rc2_40_cbc()
|
||||
#define EVP_pkcs11_rc2_64_cbc() hc_EVP_pkcs11_rc2_64_cbc()
|
||||
#define EVP_pkcs11_rc2_cbc() hc_EVP_pkcs11_rc2_cbc()
|
||||
#define EVP_pkcs11_camellia_128_cbc() hc_EVP_pkcs11_camellia_128_cbc()
|
||||
#define EVP_pkcs11_camellia_192_cbc() hc_EVP_pkcs11_camellia_192_cbc()
|
||||
#define EVP_pkcs11_camellia_256_cbc() hc_EVP_pkcs11_camellia_256_cbc()
|
||||
|
||||
#define EVP_pkcs11_hcrypto_md2() hc_EVP_pkcs11_hcrypto_md2()
|
||||
#define EVP_pkcs11_hcrypto_md4() hc_EVP_pkcs11_hcrypto_md4()
|
||||
#define EVP_pkcs11_hcrypto_md5() hc_EVP_pkcs11_hcrypto_md5()
|
||||
#define EVP_pkcs11_hcrypto_sha1() hc_EVP_pkcs11_hcrypto_sha1()
|
||||
#define EVP_pkcs11_hcrypto_sha256() hc_EVP_pkcs11_hcrypto_sha256()
|
||||
#define EVP_pkcs11_hcrypto_sha384() hc_EVP_pkcs11_hcrypto_sha384()
|
||||
#define EVP_pkcs11_hcrypto_sha512() hc_EVP_pkcs11_hcrypto_sha512()
|
||||
#define EVP_pkcs11_hcrypto_des_cbc() hc_EVP_pkcs11_hcrypto_des_cbc()
|
||||
#define EVP_pkcs11_hcrypto_des_ede3_cbc() hc_EVP_pkcs11_hcrypto_des_ede3_cbc()
|
||||
#define EVP_pkcs11_hcrypto_aes_128_cbc() hc_EVP_pkcs11_hcrypto_aes_128_cbc()
|
||||
#define EVP_pkcs11_hcrypto_aes_192_cbc() hc_EVP_pkcs11_hcrypto_aes_192_cbc()
|
||||
#define EVP_pkcs11_hcrypto_aes_256_cbc() hc_EVP_pkcs11_hcrypto_aes_256_cbc()
|
||||
#define EVP_pkcs11_hcrypto_aes_128_cfb8() hc_EVP_pkcs11_hcrypto_aes_128_cfb8()
|
||||
#define EVP_pkcs11_hcrypto_aes_192_cfb8() hc_EVP_pkcs11_hcrypto_aes_192_cfb8()
|
||||
#define EVP_pkcs11_hcrypto_aes_256_cfb8() hc_EVP_pkcs11_hcrypto_aes_256_cfb8()
|
||||
#define EVP_pkcs11_hcrypto_rc4() hc_EVP_pkcs11_hcrypto_rc4()
|
||||
#define EVP_pkcs11_hcrypto_rc4_40() hc_EVP_pkcs11_hcrypto_rc4_40()
|
||||
#define EVP_pkcs11_hcrypto_rc2_40_cbc() hc_EVP_pkcs11_hcrypto_rc2_40_cbc()
|
||||
#define EVP_pkcs11_hcrypto_rc2_64_cbc() hc_EVP_pkcs11_hcrypto_rc2_64_cbc()
|
||||
#define EVP_pkcs11_hcrypto_rc2_cbc() hc_EVP_pkcs11_hcrypto_rc2_cbc()
|
||||
#define EVP_pkcs11_hcrypto_camellia_128_cbc() hc_EVP_pkcs11_hcrypto_camellia_128_cbc()
|
||||
#define EVP_pkcs11_hcrypto_camellia_192_cbc() hc_EVP_pkcs11_hcrypto_camellia_192_cbc()
|
||||
#define EVP_pkcs11_hcrypto_camellia_256_cbc() hc_EVP_pkcs11_hcrypto_camellia_256_cbc()
|
||||
|
||||
HC_CPP_BEGIN
|
||||
|
||||
/*
|
||||
* Strict PKCS#11 implementations (these will return NULL if the underlying
|
||||
* PKCS#11 implementation does not implement the cipher or hash).
|
||||
*/
|
||||
const EVP_MD * hc_EVP_pkcs11_md2(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_md4(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_md5(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_sha1(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_sha256(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_sha384(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_sha512(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_rc2_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_rc2_40_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_rc2_64_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_rc4(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_rc4_40(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_des_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_des_ede3_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_128_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_192_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_256_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_128_cfb8(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_192_cfb8(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_aes_256_cfb8(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_camellia_128_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_camellia_192_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_camellia_256_cbc(void);
|
||||
|
||||
/*
|
||||
* PKCS#11 implementations with fallback to hcrypto.
|
||||
*/
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_md2(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_md4(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_md5(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_sha1(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_sha256(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_sha384(void);
|
||||
const EVP_MD * hc_EVP_pkcs11_hcrypto_sha512(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_rc2_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_rc2_40_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_rc2_64_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_rc4(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_rc4_40(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_des_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_des_ede3_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_128_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_192_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_256_cbc(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_128_cfb8(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_192_cfb8(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_aes_256_cfb8(void);
|
||||
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_camellia_128_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_camellia_192_cbc(void);
|
||||
const EVP_CIPHER * hc_EVP_pkcs11_hcrypto_camellia_256_cbc(void);
|
||||
|
||||
HC_CPP_END
|
||||
|
||||
#endif /* HEIM_EVP_PKCS11_H */
|
@@ -48,6 +48,7 @@
|
||||
#include <evp-hcrypto.h>
|
||||
#include <evp-cc.h>
|
||||
#include <evp-w32.h>
|
||||
#include <evp-pkcs11.h>
|
||||
|
||||
#include <krb5-types.h>
|
||||
#include <roken.h>
|
||||
@@ -55,6 +56,8 @@
|
||||
#ifndef HCRYPTO_DEF_PROVIDER
|
||||
# ifdef __APPLE__
|
||||
# define HCRYPTO_DEF_PROVIDER cc
|
||||
# elif __sun
|
||||
# define HCRYPTO_DEF_PROVIDER pkcs11_hcrypto
|
||||
# else
|
||||
# define HCRYPTO_DEF_PROVIDER hcrypto
|
||||
# endif
|
||||
@@ -1126,7 +1129,7 @@ EVP_des_cbc(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* The tripple DES cipher type
|
||||
* The triple DES cipher type
|
||||
*
|
||||
* @return the DES-EDE3-CBC EVP_CIPHER pointer.
|
||||
*
|
||||
|
@@ -177,6 +177,23 @@ EXPORTS
|
||||
;! hc_EVP_cc_aes_192_cfb8
|
||||
;! hc_EVP_cc_aes_256_cfb8
|
||||
|
||||
hc_EVP_pkcs11_md2
|
||||
hc_EVP_pkcs11_md4
|
||||
hc_EVP_pkcs11_md5
|
||||
hc_EVP_pkcs11_sha1
|
||||
hc_EVP_pkcs11_sha256
|
||||
hc_EVP_pkcs11_des_ede3_cbc
|
||||
hc_EVP_pkcs11_aes_128_cbc
|
||||
hc_EVP_pkcs11_aes_192_cbc
|
||||
hc_EVP_pkcs11_aes_256_cbc
|
||||
hc_EVP_pkcs11_aes_128_cfb8
|
||||
hc_EVP_pkcs11_aes_192_cfb8
|
||||
hc_EVP_pkcs11_aes_256_cfb8
|
||||
hc_EVP_pkcs11_rc2_40_cbc
|
||||
hc_EVP_pkcs11_rc2_cbc
|
||||
hc_EVP_pkcs11_rc4
|
||||
hc_EVP_pkcs11_rc4_40
|
||||
|
||||
hc_EVP_w32crypto_md2 ;!
|
||||
hc_EVP_w32crypto_md4 ;!
|
||||
hc_EVP_w32crypto_md5 ;!
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include <evp-hcrypto.h>
|
||||
#include <evp-cc.h>
|
||||
#include <evp-w32.h>
|
||||
#include <evp-pkcs11.h>
|
||||
#include <hex.h>
|
||||
#include <err.h>
|
||||
|
||||
@@ -87,6 +88,8 @@ static unsigned char *d;
|
||||
#define PROVIDER_USAGE "hcrypto|cc"
|
||||
#elif defined(WIN32)
|
||||
#define PROVIDER_USAGE "hcrypto|w32crypto"
|
||||
#elif __sun || defined(PKCS11_MODULE_PATH)
|
||||
#define PROVIDER_USAGE "hcrypto|pkcs11"
|
||||
#else
|
||||
#define PROVIDER_USAGE "hcrypto"
|
||||
#endif
|
||||
@@ -122,6 +125,11 @@ test_bulk_cipher(const char *cname, const EVP_CIPHER *c)
|
||||
int i;
|
||||
int64_t M = 0;
|
||||
|
||||
if (c == NULL) {
|
||||
printf("%s not supported\n", cname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < loops; i++) {
|
||||
EVP_CIPHER_CTX ectx;
|
||||
EVP_CIPHER_CTX dctx;
|
||||
@@ -171,6 +179,11 @@ test_bulk_digest(const char *cname, const EVP_MD *md)
|
||||
unsigned int tmp = sizeof(digest);
|
||||
int64_t M = 0;
|
||||
|
||||
if (md == NULL) {
|
||||
printf("%s not supported\n", cname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < loops; i++) {
|
||||
STATS_START(M);
|
||||
EVP_Digest(d, len, digest, &tmp, md, NULL);
|
||||
@@ -237,6 +250,20 @@ test_bulk_provider_w32crypto(void)
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
#if __sun || defined(PKCS11_MODULE_PATH)
|
||||
static void
|
||||
test_bulk_provider_pkcs11(void)
|
||||
{
|
||||
test_bulk_cipher("pkcs11_aes_256_cbc", EVP_pkcs11_aes_256_cbc());
|
||||
test_bulk_cipher("pkcs11_rc4", EVP_pkcs11_rc4());
|
||||
test_bulk_digest("pkcs11_md5", EVP_pkcs11_md5());
|
||||
test_bulk_digest("pkcs11_sha1", EVP_pkcs11_sha1());
|
||||
test_bulk_digest("pkcs11_sha256", EVP_pkcs11_sha256());
|
||||
test_bulk_digest("pkcs11_sha384", EVP_pkcs11_sha384());
|
||||
test_bulk_digest("pkcs11_sha512", EVP_pkcs11_sha512());
|
||||
}
|
||||
#endif /* __sun || PKCS11_MODULE_PATH */
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -275,6 +302,10 @@ main(int argc, char **argv)
|
||||
#ifdef WIN32
|
||||
else if (strcmp(provider, "w32crypto") == 0)
|
||||
test_bulk_provider_w32crypto();
|
||||
#endif
|
||||
#if __sun || defined(PKCS11_MODULE_PATH)
|
||||
else if (strcmp(provider, "pkcs11") == 0)
|
||||
test_bulk_provider_pkcs11();
|
||||
#endif
|
||||
else
|
||||
usage(1);
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include <evp-hcrypto.h>
|
||||
#include <evp-cc.h>
|
||||
#include <evp-w32.h>
|
||||
#include <evp-pkcs11.h>
|
||||
#include <hex.h>
|
||||
#include <err.h>
|
||||
|
||||
@@ -398,5 +399,21 @@ main(int argc, char **argv)
|
||||
ret += test_cipher(i, EVP_w32crypto_rc4(), &rc4_tests[i]);
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* PKCS#11 */
|
||||
#if __sun || defined(PKCS11_MODULE_PATH)
|
||||
for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_aes_256_cbc(), &aes_tests[i]);
|
||||
for (i = 0; i < sizeof(aes_cfb_tests)/sizeof(aes_cfb_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_aes_128_cfb8(), &aes_cfb_tests[i]);
|
||||
for (i = 0; i < sizeof(rc2_tests)/sizeof(rc2_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_rc2_cbc(), &rc2_tests[i]);
|
||||
for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_rc2_40_cbc(), &rc2_40_tests[i]);
|
||||
for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_des_ede3_cbc(), &des_ede3_tests[i]);
|
||||
for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
|
||||
ret += test_cipher(i, EVP_pkcs11_rc4(), &rc4_tests[i]);
|
||||
#endif /* PKCS11_MODULE_PATH */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -201,6 +201,24 @@ HEIMDAL_CRYPTO_1.0 {
|
||||
hc_EVP_hcrypto_rc4;
|
||||
hc_EVP_hcrypto_rc4_40;
|
||||
|
||||
hc_EVP_pkcs11_md2;
|
||||
hc_EVP_pkcs11_md4;
|
||||
hc_EVP_pkcs11_md5;
|
||||
hc_EVP_pkcs11_sha1;
|
||||
hc_EVP_pkcs11_sha256;
|
||||
hc_EVP_pkcs11_des_ede3_cbc;
|
||||
hc_EVP_pkcs11_aes_128_cbc;
|
||||
hc_EVP_pkcs11_aes_192_cbc;
|
||||
hc_EVP_pkcs11_aes_256_cbc;
|
||||
hc_EVP_pkcs11_aes_128_cfb8;
|
||||
hc_EVP_pkcs11_aes_192_cfb8;
|
||||
hc_EVP_pkcs11_aes_256_cfb8;
|
||||
hc_EVP_pkcs11_rc2_40_cbc;
|
||||
hc_EVP_pkcs11_rc2_64_cbc;
|
||||
hc_EVP_pkcs11_rc2_cbc;
|
||||
hc_EVP_pkcs11_rc4;
|
||||
hc_EVP_pkcs11_rc4_40;
|
||||
|
||||
hc_EVP_hcrypto_aes_128_cts;
|
||||
hc_EVP_hcrypto_aes_192_cts;
|
||||
hc_EVP_hcrypto_aes_256_cts;
|
||||
|
Reference in New Issue
Block a user