From 0e65ab1c3ca4597ac474a4b049d242b7260a47ed Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 23 Jan 2019 12:34:56 +1000 Subject: [PATCH 1/5] Add PKCS#11 examples and test --- .gitignore | 7 + pkcs11/Makefile | 36 ++ pkcs11/README.md | 83 ++++ pkcs11/mksofthsm2_conf.sh | 18 + pkcs11/opencryptoki.sh | 18 + pkcs11/pkcs11_aesgcm.c | 125 ++++++ pkcs11/pkcs11_ecc.c | 202 +++++++++ pkcs11/pkcs11_rsa.c | 321 ++++++++++++++ pkcs11/pkcs11_test.c | 877 ++++++++++++++++++++++++++++++++++++++ pkcs11/softhsm2.sh | 21 + 10 files changed, 1708 insertions(+) create mode 100644 pkcs11/Makefile create mode 100644 pkcs11/README.md create mode 100755 pkcs11/mksofthsm2_conf.sh create mode 100755 pkcs11/opencryptoki.sh create mode 100644 pkcs11/pkcs11_aesgcm.c create mode 100644 pkcs11/pkcs11_ecc.c create mode 100644 pkcs11/pkcs11_rsa.c create mode 100644 pkcs11/pkcs11_test.c create mode 100755 pkcs11/softhsm2.sh diff --git a/.gitignore b/.gitignore index 7567363b..2d1f211d 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,10 @@ certmanager/certverify rsa/sign rsa/verify +pkcs11/pkcs11_test +pkcs11/pkcs11_rsa +pkcs11/pkcs11_ecc +pkcs11/pkcs11_aesgcm +pkcs11/softhsm2.conf +pkcs11/softhsm2 + diff --git a/pkcs11/Makefile b/pkcs11/Makefile new file mode 100644 index 00000000..3f2c1889 --- /dev/null +++ b/pkcs11/Makefile @@ -0,0 +1,36 @@ +# ECC Examples Makefile +CC = gcc +LIB_PATH = /usr/local +CFLAGS = -Wall -I$(LIB_PATH)/include +LIBS = -L$(LIB_PATH)/lib -lm + +# option variables +DYN_LIB = -lwolfssl +STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a +DEBUG_FLAGS = -g -DDEBUG +DEBUG_INC_PATHS = -MD +OPTIMIZE = -Os + +# Options +CFLAGS+=$(DEBUG_FLAGS) +#CFLAGS+=$(OPTIMIZE) +LIBS+=$(STATIC_LIB) -ldl -lm +#LIBS+=$(DYN_LIB) + +# build targets +SRC=$(wildcard *.c) +TARGETS=$(patsubst %.c, %, $(SRC)) + +.PHONY: clean all + +all: $(TARGETS) + +debug: CFLAGS+=$(DEBUG_FLAGS) +debug: all + +# build template +%: %.c + $(CC) -o $@ $< $(CFLAGS) $(LIBS) + +clean: + rm -f $(TARGETS) diff --git a/pkcs11/README.md b/pkcs11/README.md new file mode 100644 index 00000000..3011ed68 --- /dev/null +++ b/pkcs11/README.md @@ -0,0 +1,83 @@ + + +### Setting up and testing SoftHSM version 2 + +# Change to source code directory of SoftHSM version 2 + +sh ./autogen.sh +# (May need to install pkg-config and libssl-dev) + +./configure --disable-gost + +sudo make install + + +# Change to wolfssl-examples/pkcs11 directory + +./mksofthsm2_conf.sh + +export SOFTHSM2_CONF=$PWD/softhsm2.conf + + +# Running tests + +softhsm2-util --init-token --slot 0 --label SoftToken +# Use PIN: cryptoki +# Use User PIN: cryptoki + +# Use the slot id from the output + +export SOFTHSM2_SLOTID= + +./softhsm2.sh + + + +### Setting up and testing openCryptoki + + +# Change to source code directory of openCryptoki + +./bootstrap.sh + +./configure +# (May need to install flex, bison and openldap-devel [or libldap2-dev].) + +make + +# Setup pkcs11 group and put current user into it +sudo groupadd pkcs11 +sudo usermod -a -G pkcs11 $USER + +# Install library +sudo make install + +sudo ldconfig /usr/local/lib + +# Start the daemon +sudo /usr/local/sbin/pkcsslotd + +# (May need to logout and login to be able to use pkcsconf) + +# Setup token +echo "87654321 +SoftToken" | pkcsconf -I -c 3 + +echo "87654321 +cryptoki +cryptoki " | pkcsconf -P -c 3 + +echo "cryptoki +cryptoki +cryptoki" | pkcsconf -u -c 3 + + +# Running tests + +# Start daemon if not running already +sudo /usr/local/sbin/pkcsslotd + +# Change to wolfssl-examples/pkcs11 directory + +./opencryptoki.sh + diff --git a/pkcs11/mksofthsm2_conf.sh b/pkcs11/mksofthsm2_conf.sh new file mode 100755 index 00000000..92abbd2e --- /dev/null +++ b/pkcs11/mksofthsm2_conf.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +echo " +# SoftHSM v2 configuration file + +directories.tokendir = $PWD/softhsm2/ +objectstore.backend = file + +# ERROR, WARNING, INFO, DEBUG +log.level = ERROR + +# If CKF_REMOVABLE_DEVICE flag should be set +slots.removable = false +" > softhsm2.conf + +rm -rf ./softhsm2 +mkdir softhsm2 + diff --git a/pkcs11/opencryptoki.sh b/pkcs11/opencryptoki.sh new file mode 100755 index 00000000..457b3933 --- /dev/null +++ b/pkcs11/opencryptoki.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +echo "# Note opencryptoki does not support ECC not AES-GCM but operations" +echo "# are performed in software" +echo +echo "# RSA example" +./pkcs11_rsa /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki +echo +echo "# ECC example" +./pkcs11_ecc /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki +echo +echo "# AES-GCM example" +./pkcs11_aesgcm /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki +echo +echo "# PKCS #11 test" +./pkcs11_test /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki + + diff --git a/pkcs11/pkcs11_aesgcm.c b/pkcs11/pkcs11_aesgcm.c new file mode 100644 index 00000000..53ddb334 --- /dev/null +++ b/pkcs11/pkcs11_aesgcm.c @@ -0,0 +1,125 @@ + + +#include +#include +#include +#include +#include +#include + +#if !defined(NO_AES) && defined(HAVE_AESGCM) +int aesgcm_enc_dec(int devId) +{ + Aes aesEnc; + Aes aesDec; + unsigned char key[AES_256_KEY_SIZE]; + int ret = 0; + unsigned char data[33]; + unsigned char enc[33]; + unsigned char dec[33]; + unsigned char iv[GCM_NONCE_MID_SZ]; + unsigned char authTag[AES_BLOCK_SIZE]; + + memset(key, 9, sizeof(key)); + memset(data, 9, sizeof(data)); + memset(iv, 9, sizeof(iv)); + + fprintf(stderr, "Encrypt with AES128-GCM\n"); + ret = wc_AesInit_Id(&aesEnc, NULL, 0, NULL, devId); + if (ret == 0) { + ret = wc_AesGcmSetKey(&aesEnc, key, AES_128_KEY_SIZE); + if (ret != 0) + fprintf(stderr, "Set Key failed: %d\n", ret); + } + if (ret == 0) { + ret = wc_AesGcmEncrypt(&aesEnc, enc, data, sizeof(data), iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Encrypt failed: %d\n", ret); + } + + if (ret == 0) { + fprintf(stderr, "Decrypt with AES128-GCM\n"); + ret = wc_AesInit_Id(&aesDec, NULL, 0, NULL, devId); + } + if (ret == 0) { + ret = wc_AesGcmSetKey(&aesDec, key, AES_128_KEY_SIZE); + if (ret != 0) + fprintf(stderr, "Set Key failed: %d\n", ret); + } + if (ret == 0) { + ret = wc_AesGcmDecrypt(&aesDec, dec, enc, sizeof(enc), iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Decrypt failed: %d\n", ret); + } + + return ret; +} +#endif + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: pkcs11_aesgcm \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + #if !defined(NO_AES) && defined(HAVE_AESGCM) + ret = aesgcm_enc_dec(devId); + if (ret != 0) + ret = 1; + #endif + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} + diff --git a/pkcs11/pkcs11_ecc.c b/pkcs11/pkcs11_ecc.c new file mode 100644 index 00000000..727fd29a --- /dev/null +++ b/pkcs11/pkcs11_ecc.c @@ -0,0 +1,202 @@ + + +#include +#include +#include +#include +#include +#include + +static WC_RNG rng; + +#ifdef HAVE_ECC +/* ./certs/ecc-client-key.der, ECC */ +static const unsigned char ecc_clikey_der_256[] = +{ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xF8, + 0xCF, 0x92, 0x6B, 0xBD, 0x1E, 0x28, 0xF1, 0xA8, + 0xAB, 0xA1, 0x23, 0x4F, 0x32, 0x74, 0x18, 0x88, + 0x50, 0xAD, 0x7E, 0xC7, 0xEC, 0x92, 0xF8, 0x8F, + 0x97, 0x4D, 0xAF, 0x56, 0x89, 0x65, 0xC7, 0xA0, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0xA1, 0x44, 0x03, 0x42, 0x00, + 0x04, 0x55, 0xBF, 0xF4, 0x0F, 0x44, 0x50, 0x9A, + 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, 0x4D, 0xF5, + 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, + 0x9B, 0xDA, 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, + 0x76, 0x16, 0xC6, 0x56, 0x95, 0x06, 0xCC, 0x01, + 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, 0xF7, 0xBD, + 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikey_der_256 = sizeof(ecc_clikey_der_256); + +/* ./certs/ecc-client-keyPub.der, ECC */ +static const unsigned char ecc_clikeypub_der_256[] = +{ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4, + 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, + 0x4D, 0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, + 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56, + 0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, + 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikeypub_der_256 = sizeof(ecc_clikeypub_der_256); + + +int decode_private_key(ecc_key* key, int devId) +{ + int ret; + word32 idx; + + fprintf(stderr, "Decode ECC Private Key\n"); + ret = wc_ecc_init_ex(key, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize ECC key: %d\n", ret); + } + if (ret == 0) { + idx = 0; + ret = wc_EccPrivateKeyDecode(ecc_clikey_der_256, &idx, key, + (word32)sizeof_ecc_clikey_der_256); + if (ret != 0) + fprintf(stderr, "Failed to decode private key: %d\n", ret); + } + + return ret; +} + +int decode_public_key(ecc_key* key, int devId) +{ + int ret; + word32 idx; + + fprintf(stderr, "Decode ECC Public Key\n"); + ret = wc_ecc_init_ex(key, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize ECC key: %d\n", ret); + } + if (ret == 0) { + idx = 0; + ret = wc_EccPublicKeyDecode(ecc_clikeypub_der_256, &idx, key, + (word32)sizeof_ecc_clikeypub_der_256); + if (ret != 0) + fprintf(stderr, "Failed to decode public key: %d\n", ret); + } + + return ret; +} + +int ecdsa_sign_verify(int devId) +{ + int ret = 0; + byte hash[32], sig[128]; + word32 hashSz, sigSz; + int verify; + ecc_key eccPriv; + ecc_key eccPub; + + memset(hash, 9, sizeof(hash)); + hashSz = sizeof(hash); + sigSz = sizeof(sig); + + ret = decode_private_key(&eccPriv, devId); + if (ret == 0) { + fprintf(stderr, "Sign with ECC Keys\n"); + ret = wc_ecc_sign_hash(hash, hashSz, sig, &sigSz, &rng, &eccPriv); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + wc_ecc_free(&eccPriv); + } + + if (ret == 0) { + ret = decode_public_key(&eccPub, devId); + if (ret == 0) { + fprintf(stderr, "Verify with ECC Keys\n"); + ret = wc_ecc_verify_hash(sig, sigSz, hash, (int)hashSz, &verify, + &eccPub); + if (ret < 0 || !verify) + fprintf(stderr, "Failed to verify: %d (%d)\n", ret, verify); + if (!verify) + ret = -1; + wc_ecc_free(&eccPub); + } + } + + return ret; +} +#endif + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: pkcs11_ecc \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + wc_InitRng_ex(&rng, NULL, devId); + + #ifdef HAVE_ECC + ret = ecdsa_sign_verify(devId); + if (ret != 0) + ret = 1; + #endif + + wc_FreeRng(&rng); + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} + diff --git a/pkcs11/pkcs11_rsa.c b/pkcs11/pkcs11_rsa.c new file mode 100644 index 00000000..eb09c4a1 --- /dev/null +++ b/pkcs11/pkcs11_rsa.c @@ -0,0 +1,321 @@ + + +#include +#include +#include +#include +#include +#include + +#ifndef NO_RSA +static const unsigned char client_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, 0x32, + 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, 0x9A, + 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, 0xB2, + 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, 0x44, + 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, 0x67, + 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, 0xF7, + 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, 0x1E, + 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, 0x65, + 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, 0xF7, + 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, 0x78, + 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, 0xD2, + 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, 0x51, + 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, 0xE4, + 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, 0xD0, + 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, 0x43, + 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, 0x86, + 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, 0x72, + 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, 0xEF, + 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, 0x03, + 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, 0xA3, + 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, 0x8A, + 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, 0x25, + 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, 0x18, + 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, 0x84, + 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, 0xAE, + 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, 0xA2, 0xE6, + 0xD8, 0x5F, 0x10, 0x71, 0x64, 0x08, 0x9E, 0x2E, 0x6D, 0xD1, + 0x6D, 0x1E, 0x85, 0xD2, 0x0A, 0xB1, 0x8C, 0x47, 0xCE, 0x2C, + 0x51, 0x6A, 0xA0, 0x12, 0x9E, 0x53, 0xDE, 0x91, 0x4C, 0x1D, + 0x6D, 0xEA, 0x59, 0x7B, 0xF2, 0x77, 0xAA, 0xD9, 0xC6, 0xD9, + 0x8A, 0xAB, 0xD8, 0xE1, 0x16, 0xE4, 0x63, 0x26, 0xFF, 0xB5, + 0x6C, 0x13, 0x59, 0xB8, 0xE3, 0xA5, 0xC8, 0x72, 0x17, 0x2E, + 0x0C, 0x9F, 0x6F, 0xE5, 0x59, 0x3F, 0x76, 0x6F, 0x49, 0xB1, + 0x11, 0xC2, 0x5A, 0x2E, 0x16, 0x29, 0x0D, 0xDE, 0xB7, 0x8E, + 0xDC, 0x40, 0xD5, 0xA2, 0xEE, 0xE0, 0x1E, 0xA1, 0xF4, 0xBE, + 0x97, 0xDB, 0x86, 0x63, 0x96, 0x14, 0xCD, 0x98, 0x09, 0x60, + 0x2D, 0x30, 0x76, 0x9C, 0x3C, 0xCD, 0xE6, 0x88, 0xEE, 0x47, + 0x92, 0x79, 0x0B, 0x5A, 0x00, 0xE2, 0x5E, 0x5F, 0x11, 0x7C, + 0x7D, 0xF9, 0x08, 0xB7, 0x20, 0x06, 0x89, 0x2A, 0x5D, 0xFD, + 0x00, 0xAB, 0x22, 0xE1, 0xF0, 0xB3, 0xBC, 0x24, 0xA9, 0x5E, + 0x26, 0x0E, 0x1F, 0x00, 0x2D, 0xFE, 0x21, 0x9A, 0x53, 0x5B, + 0x6D, 0xD3, 0x2B, 0xAB, 0x94, 0x82, 0x68, 0x43, 0x36, 0xD8, + 0xF6, 0x2F, 0xC6, 0x22, 0xFC, 0xB5, 0x41, 0x5D, 0x0D, 0x33, + 0x60, 0xEA, 0xA4, 0x7D, 0x7E, 0xE8, 0x4B, 0x55, 0x91, 0x56, + 0xD3, 0x5C, 0x57, 0x8F, 0x1F, 0x94, 0x17, 0x2F, 0xAA, 0xDE, + 0xE9, 0x9E, 0xA8, 0xF4, 0xCF, 0x8A, 0x4C, 0x8E, 0xA0, 0xE4, + 0x56, 0x73, 0xB2, 0xCF, 0x4F, 0x86, 0xC5, 0x69, 0x3C, 0xF3, + 0x24, 0x20, 0x8B, 0x5C, 0x96, 0x0C, 0xFA, 0x6B, 0x12, 0x3B, + 0x9A, 0x67, 0xC1, 0xDF, 0xC6, 0x96, 0xB2, 0xA5, 0xD5, 0x92, + 0x0D, 0x9B, 0x09, 0x42, 0x68, 0x24, 0x10, 0x45, 0xD4, 0x50, + 0xE4, 0x17, 0x39, 0x48, 0xD0, 0x35, 0x8B, 0x94, 0x6D, 0x11, + 0xDE, 0x8F, 0xCA, 0x59, 0x02, 0x81, 0x81, 0x00, 0xEA, 0x24, + 0xA7, 0xF9, 0x69, 0x33, 0xE9, 0x71, 0xDC, 0x52, 0x7D, 0x88, + 0x21, 0x28, 0x2F, 0x49, 0xDE, 0xBA, 0x72, 0x16, 0xE9, 0xCC, + 0x47, 0x7A, 0x88, 0x0D, 0x94, 0x57, 0x84, 0x58, 0x16, 0x3A, + 0x81, 0xB0, 0x3F, 0xA2, 0xCF, 0xA6, 0x6C, 0x1E, 0xB0, 0x06, + 0x29, 0x00, 0x8F, 0xE7, 0x77, 0x76, 0xAC, 0xDB, 0xCA, 0xC7, + 0xD9, 0x5E, 0x9B, 0x3F, 0x26, 0x90, 0x52, 0xAE, 0xFC, 0x38, + 0x90, 0x00, 0x14, 0xBB, 0xB4, 0x0F, 0x58, 0x94, 0xE7, 0x2F, + 0x6A, 0x7E, 0x1C, 0x4F, 0x41, 0x21, 0xD4, 0x31, 0x59, 0x1F, + 0x4E, 0x8A, 0x1A, 0x8D, 0xA7, 0x57, 0x6C, 0x22, 0xD8, 0xE5, + 0xF4, 0x7E, 0x32, 0xA6, 0x10, 0xCB, 0x64, 0xA5, 0x55, 0x03, + 0x87, 0xA6, 0x27, 0x05, 0x8C, 0xC3, 0xD7, 0xB6, 0x27, 0xB2, + 0x4D, 0xBA, 0x30, 0xDA, 0x47, 0x8F, 0x54, 0xD3, 0x3D, 0x8B, + 0x84, 0x8D, 0x94, 0x98, 0x58, 0xA5, 0x02, 0x81, 0x81, 0x00, + 0xD5, 0x38, 0x1B, 0xC3, 0x8F, 0xC5, 0x93, 0x0C, 0x47, 0x0B, + 0x6F, 0x35, 0x92, 0xC5, 0xB0, 0x8D, 0x46, 0xC8, 0x92, 0x18, + 0x8F, 0xF5, 0x80, 0x0A, 0xF7, 0xEF, 0xA1, 0xFE, 0x80, 0xB9, + 0xB5, 0x2A, 0xBA, 0xCA, 0x18, 0xB0, 0x5D, 0xA5, 0x07, 0xD0, + 0x93, 0x8D, 0xD8, 0x9C, 0x04, 0x1C, 0xD4, 0x62, 0x8E, 0xA6, + 0x26, 0x81, 0x01, 0xFF, 0xCE, 0x8A, 0x2A, 0x63, 0x34, 0x35, + 0x40, 0xAA, 0x6D, 0x80, 0xDE, 0x89, 0x23, 0x6A, 0x57, 0x4D, + 0x9E, 0x6E, 0xAD, 0x93, 0x4E, 0x56, 0x90, 0x0B, 0x6D, 0x9D, + 0x73, 0x8B, 0x0C, 0xAE, 0x27, 0x3D, 0xDE, 0x4E, 0xF0, 0xAA, + 0xC5, 0x6C, 0x78, 0x67, 0x6C, 0x94, 0x52, 0x9C, 0x37, 0x67, + 0x6C, 0x2D, 0xEF, 0xBB, 0xAF, 0xDF, 0xA6, 0x90, 0x3C, 0xC4, + 0x47, 0xCF, 0x8D, 0x96, 0x9E, 0x98, 0xA9, 0xB4, 0x9F, 0xC5, + 0xA6, 0x50, 0xDC, 0xB3, 0xF0, 0xFB, 0x74, 0x17, 0x02, 0x81, + 0x80, 0x5E, 0x83, 0x09, 0x62, 0xBD, 0xBA, 0x7C, 0xA2, 0xBF, + 0x42, 0x74, 0xF5, 0x7C, 0x1C, 0xD2, 0x69, 0xC9, 0x04, 0x0D, + 0x85, 0x7E, 0x3E, 0x3D, 0x24, 0x12, 0xC3, 0x18, 0x7B, 0xF3, + 0x29, 0xF3, 0x5F, 0x0E, 0x76, 0x6C, 0x59, 0x75, 0xE4, 0x41, + 0x84, 0x69, 0x9D, 0x32, 0xF3, 0xCD, 0x22, 0xAB, 0xB0, 0x35, + 0xBA, 0x4A, 0xB2, 0x3C, 0xE5, 0xD9, 0x58, 0xB6, 0x62, 0x4F, + 0x5D, 0xDE, 0xE5, 0x9E, 0x0A, 0xCA, 0x53, 0xB2, 0x2C, 0xF7, + 0x9E, 0xB3, 0x6B, 0x0A, 0x5B, 0x79, 0x65, 0xEC, 0x6E, 0x91, + 0x4E, 0x92, 0x20, 0xF6, 0xFC, 0xFC, 0x16, 0xED, 0xD3, 0x76, + 0x0C, 0xE2, 0xEC, 0x7F, 0xB2, 0x69, 0x13, 0x6B, 0x78, 0x0E, + 0x5A, 0x46, 0x64, 0xB4, 0x5E, 0xB7, 0x25, 0xA0, 0x5A, 0x75, + 0x3A, 0x4B, 0xEF, 0xC7, 0x3C, 0x3E, 0xF7, 0xFD, 0x26, 0xB8, + 0x20, 0xC4, 0x99, 0x0A, 0x9A, 0x73, 0xBE, 0xC3, 0x19, 0x02, + 0x81, 0x81, 0x00, 0xBA, 0x44, 0x93, 0x14, 0xAC, 0x34, 0x19, + 0x3B, 0x5F, 0x91, 0x60, 0xAC, 0xF7, 0xB4, 0xD6, 0x81, 0x05, + 0x36, 0x51, 0x53, 0x3D, 0xE8, 0x65, 0xDC, 0xAF, 0x2E, 0xDC, + 0x61, 0x3E, 0xC9, 0x7D, 0xB8, 0x7F, 0x87, 0xF0, 0x3B, 0x9B, + 0x03, 0x82, 0x29, 0x37, 0xCE, 0x72, 0x4E, 0x11, 0xD5, 0xB1, + 0xC1, 0x0C, 0x07, 0xA0, 0x99, 0x91, 0x4A, 0x8D, 0x7F, 0xEC, + 0x79, 0xCF, 0xF1, 0x39, 0xB5, 0xE9, 0x85, 0xEC, 0x62, 0xF7, + 0xDA, 0x7D, 0xBC, 0x64, 0x4D, 0x22, 0x3C, 0x0E, 0xF2, 0xD6, + 0x51, 0xF5, 0x87, 0xD8, 0x99, 0xC0, 0x11, 0x20, 0x5D, 0x0F, + 0x29, 0xFD, 0x5B, 0xE2, 0xAE, 0xD9, 0x1C, 0xD9, 0x21, 0x56, + 0x6D, 0xFC, 0x84, 0xD0, 0x5F, 0xED, 0x10, 0x15, 0x1C, 0x18, + 0x21, 0xE7, 0xC4, 0x3D, 0x4B, 0xD7, 0xD0, 0x9E, 0x6A, 0x95, + 0xCF, 0x22, 0xC9, 0x03, 0x7B, 0x9E, 0xE3, 0x60, 0x01, 0xFC, + 0x2F, 0x02, 0x81, 0x80, 0x11, 0xD0, 0x4B, 0xCF, 0x1B, 0x67, + 0xB9, 0x9F, 0x10, 0x75, 0x47, 0x86, 0x65, 0xAE, 0x31, 0xC2, + 0xC6, 0x30, 0xAC, 0x59, 0x06, 0x50, 0xD9, 0x0F, 0xB5, 0x70, + 0x06, 0xF7, 0xF0, 0xD3, 0xC8, 0x62, 0x7C, 0xA8, 0xDA, 0x6E, + 0xF6, 0x21, 0x3F, 0xD3, 0x7F, 0x5F, 0xEA, 0x8A, 0xAB, 0x3F, + 0xD9, 0x2A, 0x5E, 0xF3, 0x51, 0xD2, 0xC2, 0x30, 0x37, 0xE3, + 0x2D, 0xA3, 0x75, 0x0D, 0x1E, 0x4D, 0x21, 0x34, 0xD5, 0x57, + 0x70, 0x5C, 0x89, 0xBF, 0x72, 0xEC, 0x4A, 0x6E, 0x68, 0xD5, + 0xCD, 0x18, 0x74, 0x33, 0x4E, 0x8C, 0x3A, 0x45, 0x8F, 0xE6, + 0x96, 0x40, 0xEB, 0x63, 0xF9, 0x19, 0x86, 0x3A, 0x51, 0xDD, + 0x89, 0x4B, 0xB0, 0xF3, 0xF9, 0x9F, 0x5D, 0x28, 0x95, 0x38, + 0xBE, 0x35, 0xAB, 0xCA, 0x5C, 0xE7, 0x93, 0x53, 0x34, 0xA1, + 0x45, 0x5D, 0x13, 0x39, 0x65, 0x42, 0x46, 0xA1, 0x9F, 0xCD, + 0xF5, 0xBF +}; +static const int sizeof_client_key_der_2048 = sizeof(client_key_der_2048); + +static const unsigned char client_keypub_der_2048[] = +{ + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, + 0x32, 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, + 0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, + 0xB2, 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, + 0x44, 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, + 0x67, 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, + 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, + 0x1E, 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, + 0x65, 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, + 0xF7, 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, + 0x78, 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, + 0xD2, 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, + 0x51, 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, + 0xE4, 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, + 0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, + 0x43, 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, + 0x86, 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, + 0x72, 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, + 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, + 0x03, 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, + 0xA3, 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, + 0x8A, 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, + 0x25, 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, + 0x18, 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, + 0x84, 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, + 0xAE, 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, + 0x03, 0x01, 0x00, 0x01 +}; +static const int sizeof_client_keypub_der_2048 = sizeof(client_keypub_der_2048); + +static int decode_private_key(RsaKey* key, int devId) +{ + int ret; + word32 idx = 0; + + fprintf(stderr, "Decode Private RSA Key\n"); + ret = wc_InitRsaKey_ex(key, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize RSA key: %d\n", ret); + } + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(client_key_der_2048, &idx, key, + (word32)sizeof_client_key_der_2048); + if (ret != 0) + fprintf(stderr, "Failed to decode private key: %d\n", ret); + } + + return ret; +} + +static int decode_public_key(RsaKey* key, int devId) +{ + int ret; + word32 idx = 0; + + fprintf(stderr, "Decode Public RSA Key\n"); + ret = wc_InitRsaKey_ex(key, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize RSA key: %d\n", ret); + } + if (ret == 0) { + ret = wc_RsaPublicKeyDecode(client_keypub_der_2048, &idx, key, + (word32)sizeof_client_keypub_der_2048); + if (ret != 0) + fprintf(stderr, "Failed to decode public key: %d\n", ret); + } + + return ret; +} + +static int rsa_sign_verify(int devId) +{ + int ret = 0; + byte hash[32], sig[2048/8]; + word32 hashSz, sigSz; + RsaKey priv; + RsaKey pub; + + memset(hash, 9, sizeof(hash)); + hashSz = sizeof(hash); + sigSz = sizeof(sig); + + ret = decode_private_key(&priv, devId); + if (ret == 0) { + fprintf(stderr, "Signing\n"); + sigSz = ret = wc_RsaSSL_Sign(hash, hashSz, sig, (int)sigSz, &priv, + NULL); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + else + ret = 0; + + wc_FreeRsaKey(&priv); + } + + if (ret == 0) { + ret = decode_public_key(&pub, devId); + if (ret == 0) { + fprintf(stderr, "Verifying\n"); + ret = wc_RsaSSL_Verify(sig, sigSz, hash, (int)hashSz, &pub); + if (ret < 0) + fprintf(stderr, "Failed to verify: %d\n", ret); + else + ret = 0; + + wc_FreeRsaKey(&pub); + } + } + + return ret; +} +#endif + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: pkcs11_rsa \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + else { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + else { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + #ifndef NO_RSA + ret = rsa_sign_verify(devId); + if (ret != 0) + ret = 1; + #endif + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + if (ret == 0) + fprintf(stderr, "Success\n"); + + return ret; +} + diff --git a/pkcs11/pkcs11_test.c b/pkcs11/pkcs11_test.c new file mode 100644 index 00000000..b26d3f33 --- /dev/null +++ b/pkcs11/pkcs11_test.c @@ -0,0 +1,877 @@ + + +#include +#include +#include +#include +#include +#include + +#ifndef NO_RSA +static const unsigned char client_key_der_2048[] = +{ + 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, 0x32, + 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, 0x9A, + 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, 0xB2, + 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, 0x44, + 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, 0x67, + 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, 0xF7, + 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, 0x1E, + 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, 0x65, + 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, 0xF7, + 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, 0x78, + 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, 0xD2, + 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, 0x51, + 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, 0xE4, + 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, 0xD0, + 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, 0x43, + 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, 0x86, + 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, 0x72, + 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, 0xEF, + 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, 0x03, + 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, 0xA3, + 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, 0x8A, + 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, 0x25, + 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, 0x18, + 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, 0x84, + 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, 0xAE, + 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, 0xA2, 0xE6, + 0xD8, 0x5F, 0x10, 0x71, 0x64, 0x08, 0x9E, 0x2E, 0x6D, 0xD1, + 0x6D, 0x1E, 0x85, 0xD2, 0x0A, 0xB1, 0x8C, 0x47, 0xCE, 0x2C, + 0x51, 0x6A, 0xA0, 0x12, 0x9E, 0x53, 0xDE, 0x91, 0x4C, 0x1D, + 0x6D, 0xEA, 0x59, 0x7B, 0xF2, 0x77, 0xAA, 0xD9, 0xC6, 0xD9, + 0x8A, 0xAB, 0xD8, 0xE1, 0x16, 0xE4, 0x63, 0x26, 0xFF, 0xB5, + 0x6C, 0x13, 0x59, 0xB8, 0xE3, 0xA5, 0xC8, 0x72, 0x17, 0x2E, + 0x0C, 0x9F, 0x6F, 0xE5, 0x59, 0x3F, 0x76, 0x6F, 0x49, 0xB1, + 0x11, 0xC2, 0x5A, 0x2E, 0x16, 0x29, 0x0D, 0xDE, 0xB7, 0x8E, + 0xDC, 0x40, 0xD5, 0xA2, 0xEE, 0xE0, 0x1E, 0xA1, 0xF4, 0xBE, + 0x97, 0xDB, 0x86, 0x63, 0x96, 0x14, 0xCD, 0x98, 0x09, 0x60, + 0x2D, 0x30, 0x76, 0x9C, 0x3C, 0xCD, 0xE6, 0x88, 0xEE, 0x47, + 0x92, 0x79, 0x0B, 0x5A, 0x00, 0xE2, 0x5E, 0x5F, 0x11, 0x7C, + 0x7D, 0xF9, 0x08, 0xB7, 0x20, 0x06, 0x89, 0x2A, 0x5D, 0xFD, + 0x00, 0xAB, 0x22, 0xE1, 0xF0, 0xB3, 0xBC, 0x24, 0xA9, 0x5E, + 0x26, 0x0E, 0x1F, 0x00, 0x2D, 0xFE, 0x21, 0x9A, 0x53, 0x5B, + 0x6D, 0xD3, 0x2B, 0xAB, 0x94, 0x82, 0x68, 0x43, 0x36, 0xD8, + 0xF6, 0x2F, 0xC6, 0x22, 0xFC, 0xB5, 0x41, 0x5D, 0x0D, 0x33, + 0x60, 0xEA, 0xA4, 0x7D, 0x7E, 0xE8, 0x4B, 0x55, 0x91, 0x56, + 0xD3, 0x5C, 0x57, 0x8F, 0x1F, 0x94, 0x17, 0x2F, 0xAA, 0xDE, + 0xE9, 0x9E, 0xA8, 0xF4, 0xCF, 0x8A, 0x4C, 0x8E, 0xA0, 0xE4, + 0x56, 0x73, 0xB2, 0xCF, 0x4F, 0x86, 0xC5, 0x69, 0x3C, 0xF3, + 0x24, 0x20, 0x8B, 0x5C, 0x96, 0x0C, 0xFA, 0x6B, 0x12, 0x3B, + 0x9A, 0x67, 0xC1, 0xDF, 0xC6, 0x96, 0xB2, 0xA5, 0xD5, 0x92, + 0x0D, 0x9B, 0x09, 0x42, 0x68, 0x24, 0x10, 0x45, 0xD4, 0x50, + 0xE4, 0x17, 0x39, 0x48, 0xD0, 0x35, 0x8B, 0x94, 0x6D, 0x11, + 0xDE, 0x8F, 0xCA, 0x59, 0x02, 0x81, 0x81, 0x00, 0xEA, 0x24, + 0xA7, 0xF9, 0x69, 0x33, 0xE9, 0x71, 0xDC, 0x52, 0x7D, 0x88, + 0x21, 0x28, 0x2F, 0x49, 0xDE, 0xBA, 0x72, 0x16, 0xE9, 0xCC, + 0x47, 0x7A, 0x88, 0x0D, 0x94, 0x57, 0x84, 0x58, 0x16, 0x3A, + 0x81, 0xB0, 0x3F, 0xA2, 0xCF, 0xA6, 0x6C, 0x1E, 0xB0, 0x06, + 0x29, 0x00, 0x8F, 0xE7, 0x77, 0x76, 0xAC, 0xDB, 0xCA, 0xC7, + 0xD9, 0x5E, 0x9B, 0x3F, 0x26, 0x90, 0x52, 0xAE, 0xFC, 0x38, + 0x90, 0x00, 0x14, 0xBB, 0xB4, 0x0F, 0x58, 0x94, 0xE7, 0x2F, + 0x6A, 0x7E, 0x1C, 0x4F, 0x41, 0x21, 0xD4, 0x31, 0x59, 0x1F, + 0x4E, 0x8A, 0x1A, 0x8D, 0xA7, 0x57, 0x6C, 0x22, 0xD8, 0xE5, + 0xF4, 0x7E, 0x32, 0xA6, 0x10, 0xCB, 0x64, 0xA5, 0x55, 0x03, + 0x87, 0xA6, 0x27, 0x05, 0x8C, 0xC3, 0xD7, 0xB6, 0x27, 0xB2, + 0x4D, 0xBA, 0x30, 0xDA, 0x47, 0x8F, 0x54, 0xD3, 0x3D, 0x8B, + 0x84, 0x8D, 0x94, 0x98, 0x58, 0xA5, 0x02, 0x81, 0x81, 0x00, + 0xD5, 0x38, 0x1B, 0xC3, 0x8F, 0xC5, 0x93, 0x0C, 0x47, 0x0B, + 0x6F, 0x35, 0x92, 0xC5, 0xB0, 0x8D, 0x46, 0xC8, 0x92, 0x18, + 0x8F, 0xF5, 0x80, 0x0A, 0xF7, 0xEF, 0xA1, 0xFE, 0x80, 0xB9, + 0xB5, 0x2A, 0xBA, 0xCA, 0x18, 0xB0, 0x5D, 0xA5, 0x07, 0xD0, + 0x93, 0x8D, 0xD8, 0x9C, 0x04, 0x1C, 0xD4, 0x62, 0x8E, 0xA6, + 0x26, 0x81, 0x01, 0xFF, 0xCE, 0x8A, 0x2A, 0x63, 0x34, 0x35, + 0x40, 0xAA, 0x6D, 0x80, 0xDE, 0x89, 0x23, 0x6A, 0x57, 0x4D, + 0x9E, 0x6E, 0xAD, 0x93, 0x4E, 0x56, 0x90, 0x0B, 0x6D, 0x9D, + 0x73, 0x8B, 0x0C, 0xAE, 0x27, 0x3D, 0xDE, 0x4E, 0xF0, 0xAA, + 0xC5, 0x6C, 0x78, 0x67, 0x6C, 0x94, 0x52, 0x9C, 0x37, 0x67, + 0x6C, 0x2D, 0xEF, 0xBB, 0xAF, 0xDF, 0xA6, 0x90, 0x3C, 0xC4, + 0x47, 0xCF, 0x8D, 0x96, 0x9E, 0x98, 0xA9, 0xB4, 0x9F, 0xC5, + 0xA6, 0x50, 0xDC, 0xB3, 0xF0, 0xFB, 0x74, 0x17, 0x02, 0x81, + 0x80, 0x5E, 0x83, 0x09, 0x62, 0xBD, 0xBA, 0x7C, 0xA2, 0xBF, + 0x42, 0x74, 0xF5, 0x7C, 0x1C, 0xD2, 0x69, 0xC9, 0x04, 0x0D, + 0x85, 0x7E, 0x3E, 0x3D, 0x24, 0x12, 0xC3, 0x18, 0x7B, 0xF3, + 0x29, 0xF3, 0x5F, 0x0E, 0x76, 0x6C, 0x59, 0x75, 0xE4, 0x41, + 0x84, 0x69, 0x9D, 0x32, 0xF3, 0xCD, 0x22, 0xAB, 0xB0, 0x35, + 0xBA, 0x4A, 0xB2, 0x3C, 0xE5, 0xD9, 0x58, 0xB6, 0x62, 0x4F, + 0x5D, 0xDE, 0xE5, 0x9E, 0x0A, 0xCA, 0x53, 0xB2, 0x2C, 0xF7, + 0x9E, 0xB3, 0x6B, 0x0A, 0x5B, 0x79, 0x65, 0xEC, 0x6E, 0x91, + 0x4E, 0x92, 0x20, 0xF6, 0xFC, 0xFC, 0x16, 0xED, 0xD3, 0x76, + 0x0C, 0xE2, 0xEC, 0x7F, 0xB2, 0x69, 0x13, 0x6B, 0x78, 0x0E, + 0x5A, 0x46, 0x64, 0xB4, 0x5E, 0xB7, 0x25, 0xA0, 0x5A, 0x75, + 0x3A, 0x4B, 0xEF, 0xC7, 0x3C, 0x3E, 0xF7, 0xFD, 0x26, 0xB8, + 0x20, 0xC4, 0x99, 0x0A, 0x9A, 0x73, 0xBE, 0xC3, 0x19, 0x02, + 0x81, 0x81, 0x00, 0xBA, 0x44, 0x93, 0x14, 0xAC, 0x34, 0x19, + 0x3B, 0x5F, 0x91, 0x60, 0xAC, 0xF7, 0xB4, 0xD6, 0x81, 0x05, + 0x36, 0x51, 0x53, 0x3D, 0xE8, 0x65, 0xDC, 0xAF, 0x2E, 0xDC, + 0x61, 0x3E, 0xC9, 0x7D, 0xB8, 0x7F, 0x87, 0xF0, 0x3B, 0x9B, + 0x03, 0x82, 0x29, 0x37, 0xCE, 0x72, 0x4E, 0x11, 0xD5, 0xB1, + 0xC1, 0x0C, 0x07, 0xA0, 0x99, 0x91, 0x4A, 0x8D, 0x7F, 0xEC, + 0x79, 0xCF, 0xF1, 0x39, 0xB5, 0xE9, 0x85, 0xEC, 0x62, 0xF7, + 0xDA, 0x7D, 0xBC, 0x64, 0x4D, 0x22, 0x3C, 0x0E, 0xF2, 0xD6, + 0x51, 0xF5, 0x87, 0xD8, 0x99, 0xC0, 0x11, 0x20, 0x5D, 0x0F, + 0x29, 0xFD, 0x5B, 0xE2, 0xAE, 0xD9, 0x1C, 0xD9, 0x21, 0x56, + 0x6D, 0xFC, 0x84, 0xD0, 0x5F, 0xED, 0x10, 0x15, 0x1C, 0x18, + 0x21, 0xE7, 0xC4, 0x3D, 0x4B, 0xD7, 0xD0, 0x9E, 0x6A, 0x95, + 0xCF, 0x22, 0xC9, 0x03, 0x7B, 0x9E, 0xE3, 0x60, 0x01, 0xFC, + 0x2F, 0x02, 0x81, 0x80, 0x11, 0xD0, 0x4B, 0xCF, 0x1B, 0x67, + 0xB9, 0x9F, 0x10, 0x75, 0x47, 0x86, 0x65, 0xAE, 0x31, 0xC2, + 0xC6, 0x30, 0xAC, 0x59, 0x06, 0x50, 0xD9, 0x0F, 0xB5, 0x70, + 0x06, 0xF7, 0xF0, 0xD3, 0xC8, 0x62, 0x7C, 0xA8, 0xDA, 0x6E, + 0xF6, 0x21, 0x3F, 0xD3, 0x7F, 0x5F, 0xEA, 0x8A, 0xAB, 0x3F, + 0xD9, 0x2A, 0x5E, 0xF3, 0x51, 0xD2, 0xC2, 0x30, 0x37, 0xE3, + 0x2D, 0xA3, 0x75, 0x0D, 0x1E, 0x4D, 0x21, 0x34, 0xD5, 0x57, + 0x70, 0x5C, 0x89, 0xBF, 0x72, 0xEC, 0x4A, 0x6E, 0x68, 0xD5, + 0xCD, 0x18, 0x74, 0x33, 0x4E, 0x8C, 0x3A, 0x45, 0x8F, 0xE6, + 0x96, 0x40, 0xEB, 0x63, 0xF9, 0x19, 0x86, 0x3A, 0x51, 0xDD, + 0x89, 0x4B, 0xB0, 0xF3, 0xF9, 0x9F, 0x5D, 0x28, 0x95, 0x38, + 0xBE, 0x35, 0xAB, 0xCA, 0x5C, 0xE7, 0x93, 0x53, 0x34, 0xA1, + 0x45, 0x5D, 0x13, 0x39, 0x65, 0x42, 0x46, 0xA1, 0x9F, 0xCD, + 0xF5, 0xBF +}; +static const int sizeof_client_key_der_2048 = sizeof(client_key_der_2048); + +#if 0 +static const unsigned char client_keypub_der_2048[] = +{ + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xC3, 0x03, 0xD1, 0x2B, 0xFE, 0x39, 0xA4, + 0x32, 0x45, 0x3B, 0x53, 0xC8, 0x84, 0x2B, 0x2A, 0x7C, 0x74, + 0x9A, 0xBD, 0xAA, 0x2A, 0x52, 0x07, 0x47, 0xD6, 0xA6, 0x36, + 0xB2, 0x07, 0x32, 0x8E, 0xD0, 0xBA, 0x69, 0x7B, 0xC6, 0xC3, + 0x44, 0x9E, 0xD4, 0x81, 0x48, 0xFD, 0x2D, 0x68, 0xA2, 0x8B, + 0x67, 0xBB, 0xA1, 0x75, 0xC8, 0x36, 0x2C, 0x4A, 0xD2, 0x1B, + 0xF7, 0x8B, 0xBA, 0xCF, 0x0D, 0xF9, 0xEF, 0xEC, 0xF1, 0x81, + 0x1E, 0x7B, 0x9B, 0x03, 0x47, 0x9A, 0xBF, 0x65, 0xCC, 0x7F, + 0x65, 0x24, 0x69, 0xA6, 0xE8, 0x14, 0x89, 0x5B, 0xE4, 0x34, + 0xF7, 0xC5, 0xB0, 0x14, 0x93, 0xF5, 0x67, 0x7B, 0x3A, 0x7A, + 0x78, 0xE1, 0x01, 0x56, 0x56, 0x91, 0xA6, 0x13, 0x42, 0x8D, + 0xD2, 0x3C, 0x40, 0x9C, 0x4C, 0xEF, 0xD1, 0x86, 0xDF, 0x37, + 0x51, 0x1B, 0x0C, 0xA1, 0x3B, 0xF5, 0xF1, 0xA3, 0x4A, 0x35, + 0xE4, 0xE1, 0xCE, 0x96, 0xDF, 0x1B, 0x7E, 0xBF, 0x4E, 0x97, + 0xD0, 0x10, 0xE8, 0xA8, 0x08, 0x30, 0x81, 0xAF, 0x20, 0x0B, + 0x43, 0x14, 0xC5, 0x74, 0x67, 0xB4, 0x32, 0x82, 0x6F, 0x8D, + 0x86, 0xC2, 0x88, 0x40, 0x99, 0x36, 0x83, 0xBA, 0x1E, 0x40, + 0x72, 0x22, 0x17, 0xD7, 0x52, 0x65, 0x24, 0x73, 0xB0, 0xCE, + 0xEF, 0x19, 0xCD, 0xAE, 0xFF, 0x78, 0x6C, 0x7B, 0xC0, 0x12, + 0x03, 0xD4, 0x4E, 0x72, 0x0D, 0x50, 0x6D, 0x3B, 0xA3, 0x3B, + 0xA3, 0x99, 0x5E, 0x9D, 0xC8, 0xD9, 0x0C, 0x85, 0xB3, 0xD9, + 0x8A, 0xD9, 0x54, 0x26, 0xDB, 0x6D, 0xFA, 0xAC, 0xBB, 0xFF, + 0x25, 0x4C, 0xC4, 0xD1, 0x79, 0xF4, 0x71, 0xD3, 0x86, 0x40, + 0x18, 0x13, 0xB0, 0x63, 0xB5, 0x72, 0x4E, 0x30, 0xC4, 0x97, + 0x84, 0x86, 0x2D, 0x56, 0x2F, 0xD7, 0x15, 0xF7, 0x7F, 0xC0, + 0xAE, 0xF5, 0xFC, 0x5B, 0xE5, 0xFB, 0xA1, 0xBA, 0xD3, 0x02, + 0x03, 0x01, 0x00, 0x01 +}; +static const int sizeof_client_keypub_der_2048 = sizeof(client_keypub_der_2048); +#endif +#endif + +#ifdef HAVE_ECC +/* ./certs/ecc-client-key.der, ECC */ +static const unsigned char ecc_clikey_der_256[] = +{ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xF8, + 0xCF, 0x92, 0x6B, 0xBD, 0x1E, 0x28, 0xF1, 0xA8, + 0xAB, 0xA1, 0x23, 0x4F, 0x32, 0x74, 0x18, 0x88, + 0x50, 0xAD, 0x7E, 0xC7, 0xEC, 0x92, 0xF8, 0x8F, + 0x97, 0x4D, 0xAF, 0x56, 0x89, 0x65, 0xC7, 0xA0, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0xA1, 0x44, 0x03, 0x42, 0x00, + 0x04, 0x55, 0xBF, 0xF4, 0x0F, 0x44, 0x50, 0x9A, + 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, 0x4D, 0xF5, + 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, + 0x9B, 0xDA, 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, + 0x76, 0x16, 0xC6, 0x56, 0x95, 0x06, 0xCC, 0x01, + 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, 0xF7, 0xBD, + 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikey_der_256 = sizeof(ecc_clikey_der_256); + +/* ./certs/ecc-client-keyPub.der, ECC */ +static const unsigned char ecc_clikeypub_der_256[] = +{ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x55, 0xBF, 0xF4, + 0x0F, 0x44, 0x50, 0x9A, 0x3D, 0xCE, 0x9B, 0xB7, 0xF0, 0xC5, + 0x4D, 0xF5, 0x70, 0x7B, 0xD4, 0xEC, 0x24, 0x8E, 0x19, 0x80, + 0xEC, 0x5A, 0x4C, 0xA2, 0x24, 0x03, 0x62, 0x2C, 0x9B, 0xDA, + 0xEF, 0xA2, 0x35, 0x12, 0x43, 0x84, 0x76, 0x16, 0xC6, 0x56, + 0x95, 0x06, 0xCC, 0x01, 0xA9, 0xBD, 0xF6, 0x75, 0x1A, 0x42, + 0xF7, 0xBD, 0xA9, 0xB2, 0x36, 0x22, 0x5F, 0xC7, 0x5D, 0x7F, + 0xB4 +}; +static const int sizeof_ecc_clikeypub_der_256 = sizeof(ecc_clikeypub_der_256); + +static const unsigned char ecc_secret_256[] = +{ + 0xcc, 0xfb, 0x45, 0xaf, 0xc3, 0x9c, 0xd7, 0x9e, + 0x1f, 0xd1, 0xc7, 0xb8, 0x0e, 0x63, 0xd2, 0xb0, + 0x09, 0xba, 0x5a, 0xbb, 0xcf, 0x9b, 0xe2, 0x9b, + 0x8b, 0x25, 0xe4, 0x6d, 0x5c, 0x9e, 0xdd, 0xf9 +}; +static const int sizeof_ecc_secret_256 = sizeof(ecc_secret_256); +#endif + +static WC_RNG rng; + +#ifndef NO_RSA +int decode_rsa_key(RsaKey* key, int devId) +{ + int ret; + word32 idx = 0; + + ret = wc_InitRsaKey_ex(key, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize RSA key: %d\n", ret); + } + if (ret == 0) { + ret = wc_RsaPrivateKeyDecode(client_key_der_2048, &idx, key, + (word32)sizeof_client_key_der_2048); + if (ret != 0) + fprintf(stderr, "Failed to decode private key: %d\n", ret); + } + + return ret; +} + +#ifndef WOLFSSL_KEY_GEN +static CK_BBOOL ckTrue = CK_TRUE; +static CK_BYTE pub_exp[] = { 0x01, 0x00, 0x01 }; + +int get_public_key(RsaKey* key, Pkcs11Token* token, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE pubKey) +{ + int ret = 0; + unsigned char* mod = NULL; + unsigned char* exp = NULL; + int modSz, expSz; + CK_ATTRIBUTE template[] = { + {CKA_MODULUS, NULL_PTR, 0}, + {CKA_PUBLIC_EXPONENT, NULL_PTR, 0} + }; + CK_RV rv; + + rv = token->func->C_GetAttributeValue(session, pubKey, template, 2); + if (rv == CKR_OK) { + modSz = template[0].ulValueLen; + expSz = template[1].ulValueLen; + mod = (unsigned char *)malloc(modSz); + template[0].pValue = mod; + exp = (CK_BYTE_PTR) malloc(expSz); + template[1].pValue = exp; + + rv = token->func->C_GetAttributeValue(session, pubKey, template, 2); + } + if (rv == CKR_OK) + ret = wc_RsaPublicKeyDecodeRaw(mod, modSz, exp, expSz, key); + + if (exp != NULL) + free(exp); + if (mod != NULL) + free(mod); + + return ret; +} + +int gen_rsa_key(Pkcs11Token* token, RsaKey* key, unsigned char* id, int idLen, + int devId) +{ + int ret = 0; + CK_RV rv; + CK_ULONG bits = 2048; + CK_OBJECT_HANDLE pubKey = NULL_PTR, privKey = NULL_PTR; + CK_MECHANISM mech; + CK_ATTRIBUTE pubKeyTmpl[] = { + { CKA_MODULUS_BITS, &bits, sizeof(bits) }, + { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) }, + { CKA_VERIFY, &ckTrue, sizeof(ckTrue) }, + { CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp) } + }; + CK_ATTRIBUTE privKeyTmpl[] = { + {CKA_DECRYPT, &ckTrue, sizeof(ckTrue) }, + {CKA_SIGN, &ckTrue, sizeof(ckTrue) }, + {CKA_ID, id, idLen } + }; + int privTmplCnt = 2; + + if (idLen > 0) + privTmplCnt++; + if (ret == 0) { + mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; + mech.ulParameterLen = 0; + mech.pParameter = NULL; + + rv = token->func->C_GenerateKeyPair(token->handle, &mech, pubKeyTmpl, 4, + privKeyTmpl, privTmplCnt, &pubKey, &privKey); + if (rv != CKR_OK) + ret = -1; + } + + if (ret == 0) + ret = get_public_key(key, token, token->handle, pubKey); + + return ret; +} +#else +int gen_rsa_key(Pkcs11Token* token, RsaKey* key, unsigned char* id, int idLen, + int devId) +{ + int ret; + + ret = wc_InitRsaKey_Id(key, id, idLen, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize RSA key: %d\n", ret); + } + + if (ret == 0) { + ret = wc_MakeRsaKey(key, 2048, 0x10001, &rng); + if (ret != 0) + fprintf(stderr, "Failed to generate RSA key: %d\n", ret); + } + + return ret; +} +#endif + +int rsaenc_test(RsaKey* key) +{ + int ret = 0; + byte plain[128], out[2048/8], dec[2048/8]; + word32 plainSz, outSz, decSz; + + memset(plain, 9, sizeof(plain)); + plainSz = sizeof(plain); + outSz = sizeof(out); + decSz = sizeof(dec); + + if (ret == 0) { + outSz = ret = wc_RsaPublicEncrypt_ex(plain, plainSz, out, (int)outSz, + key, &rng, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, + 0); + if (ret < 0) + fprintf(stderr, "Failed to perform public encrypt: %d\n", ret); + else + ret = 0; + } + if (ret == 0) { + decSz = ret = wc_RsaPrivateDecrypt_ex(out, outSz, dec, (int)decSz, key, + WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0); + if (ret < 0) + fprintf(stderr, "Failed to perform private decrypt: %d\n", ret); + else + ret = 0; + } + + if (ret == 0) { + if (decSz != plainSz || memcmp(plain, dec, decSz) != 0) { + fprintf(stderr, "Decrypted data does not match plain text"); + ret = -1; + } + } + + return ret; +} + +int rsasig_test(RsaKey* key) +{ + int ret = 0; + byte plain[128], out[2048/8]; + word32 plainSz, outSz; + + memset(plain, 9, sizeof(plain)); + plainSz = sizeof(plain); + outSz = sizeof(out); + + if (ret == 0) { + outSz = ret = wc_RsaSSL_Sign(plain, plainSz, out, (int)outSz, key, + NULL); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_RsaSSL_Verify(out, outSz, plain, (int)plainSz, key); + if (ret < 0) + fprintf(stderr, "Failed to verify: %d\n", ret); + else + ret = 0; + } + + return ret; +} +#endif + +#ifdef HAVE_ECC +int decode_ecc_keys(ecc_key* privKey, ecc_key* pubKey, int devId) +{ + int ret; + word32 idx; + + ret = wc_ecc_init_ex(privKey, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize ECC key: %d\n", ret); + } + if (ret == 0) { + ret = wc_ecc_init_ex(pubKey, NULL, devId); + if (ret != 0) { + fprintf(stderr, "Failed to initialize ECC key: %d\n", ret); + } + } + if (ret == 0) { + idx = 0; + ret = wc_EccPrivateKeyDecode(ecc_clikey_der_256, &idx, privKey, + (word32)sizeof_ecc_clikey_der_256); + if (ret != 0) + fprintf(stderr, "Failed to decode private key: %d\n", ret); + } + if (ret == 0) { + idx = 0; + ret = wc_EccPublicKeyDecode(ecc_clikeypub_der_256, &idx, pubKey, + (word32)sizeof_ecc_clikeypub_der_256); + if (ret != 0) + fprintf(stderr, "Failed to decode public key: %d\n", ret); + } + + return ret; +} + +int gen_ec_keys(Pkcs11Token* token, ecc_key* key, unsigned char* id, int idLen, + int devId) +{ + int ret; + + ret = wc_ecc_init_id(key, id, idLen, NULL, devId); + if (ret != 0) + fprintf(stderr, "Failed to initialize EC key: %d\n", ret); + if (ret == 0) { + ret = wc_ecc_make_key_ex(&rng, 32, key, ECC_CURVE_DEF); + if (ret != 0) + fprintf(stderr, "Failed to generate EC key: %d\n", ret); + } + return ret; +} + +int ecdh_test(ecc_key* privKey, ecc_key* pubKey, int check) +{ + int ret = 0; + byte out[256/8]; + word32 outSz = sizeof(out); + + if (ret == 0) { + ret = wc_ecc_shared_secret(privKey, pubKey, out, &outSz); + if (ret < 0) + fprintf(stderr, "Failed to perform EC key derivation: %d\n", ret); + else + ret = 0; + } + if (ret == 0 && check) { + if (outSz != sizeof_ecc_secret_256 || + memcmp(out, ecc_secret_256, outSz) != 0) { + fprintf(stderr, "Secert does not match expected"); + ret = -1; + } + } + + return ret; +} + +int ecdsa_test(ecc_key* privKey, ecc_key* pubKey, ecc_key* privKeySoft, + ecc_key* pubKeySoft) +{ + int ret = 0; + byte hash[32], out[128]; + word32 hashSz, outSz; + int verify; + + memset(hash, 9, sizeof(hash)); + hashSz = sizeof(hash); + outSz = sizeof(out); + + if (ret == 0) { + ret = wc_ecc_sign_hash(hash, hashSz, out, &outSz, &rng, privKey); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + } + if (ret == 0) { + ret = wc_ecc_verify_hash(out, outSz, hash, (int)hashSz, &verify, + pubKey); + if (ret < 0 || !verify) + fprintf(stderr, "Failed to verify: %d (%d)\n", ret, verify); + if (!verify) + ret = -1; + } + if (ret == 0) { + ret = wc_ecc_verify_hash(out, outSz, hash, (int)hashSz, &verify, + pubKeySoft); + if (ret < 0 || !verify) + fprintf(stderr, "Failed to verify in software: %d (%d)\n", ret, verify); + if (!verify) + ret = -1; + } + if (ret == 0 && privKeySoft != NULL) { + outSz = sizeof(out); + ret = wc_ecc_sign_hash(hash, hashSz, out, &outSz, &rng, privKeySoft); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + } + if (ret == 0 && privKeySoft != NULL) { + ret = wc_ecc_verify_hash(out, outSz, hash, (int)hashSz, &verify, + pubKey); + if (ret < 0 || !verify) + fprintf(stderr, "Failed to verify software signature: %d (%d)\n", ret, verify); + if (!verify) + ret = -1; + } + + return ret; +} +#endif + +#if !defined(NO_AES) && defined(HAVE_AESGCM) +int aesgcm_test(int devId, Pkcs11Token* token) +{ + Aes aes; + unsigned char key[AES_256_KEY_SIZE]; + int ret = 0; + unsigned char data[33]; + unsigned char enc[33]; + unsigned char dec[33]; + unsigned char iv[GCM_NONCE_MID_SZ]; + unsigned char authTag[16]; + unsigned char exp[33] = { + 0x6c, 0xe8, 0x76, 0xda, 0x06, 0x52, 0xd9, 0xe0, + 0x2d, 0xdb, 0x34, 0x44, 0x29, 0xb2, 0x68, 0x34, + 0x2d, 0x1d, 0x30, 0x86, 0x85, 0x15, 0xeb, 0xbd, + 0xf1, 0x5e, 0xab, 0x20, 0x35, 0x9f, 0xb1, 0x0d, + 0x84 + }; + unsigned char expTag[16] = { + 0x62, 0x51, 0x91, 0xbe, 0x5c, 0x19, 0x00, 0xb3, + 0x89, 0xc5, 0x3c, 0x72, 0x0a, 0x92, 0x36, 0xc6 + }; + unsigned char exp256[33] = { + 0x64, 0x35, 0xa0, 0xcb, 0x9d, 0xad, 0x9a, 0xbc, + 0x09, 0xca, 0x71, 0xbb, 0xe0, 0x63, 0x12, 0x10, + 0x55, 0x87, 0x72, 0xe9, 0xd2, 0xbc, 0x09, 0x3d, + 0xde, 0x7e, 0xe7, 0x92, 0xc0, 0x28, 0xc4, 0x37, + 0x31 + }; + unsigned char expTag256[16] = { + 0xac, 0xe6, 0xd6, 0x1d, 0x53, 0x88, 0x3f, 0x85, + 0xb1, 0x86, 0x3e, 0xe3, 0xdd, 0x49, 0xc6, 0xc1 + }; + + memset(key, 9, sizeof(key)); + memset(data, 9, sizeof(data)); + memset(iv, 9, sizeof(iv)); + + /* AES128-GCM */ + ret = wc_AesInit_Id(&aes, NULL, 0, NULL, devId); + if (ret == 0) { + ret = wc_AesGcmSetKey(&aes, key, AES_128_KEY_SIZE); + if (ret != 0) + fprintf(stderr, "Set Key failed: %d\n", ret); + } + if (ret == 0) { + ret = wc_AesGcmEncrypt(&aes, enc, data, sizeof(data), iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Encrypt failed: %d\n", ret); + } + if (ret == 0) { + if (memcmp(enc, exp, sizeof(exp)) != 0) { + fprintf(stderr, "Encrypted data didn't match expected\n"); + ret = -1; + } + } + if (ret == 0) { + if (memcmp(authTag, expTag, sizeof(expTag)) != 0) { + fprintf(stderr, "Auth tag didn't match expected\n"); + ret = -1; + } + } + if (ret == 0) { + ret = wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc), iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Decrypt failed: %d\n", ret); + } + if (ret == 0) { + if (memcmp(dec, data, ret) != 0) { + fprintf(stderr, "Decrypted data didn't match plaintext\n"); + ret = -1; + } + } + + if (ret == 0) { + wc_Pkcs11Token_Open(token, 1); + /* AES256-GCM */ + if (ret == 0) + ret = wc_AesInit_Id(&aes, (unsigned char*)"AES123", 6, NULL, devId); + if (ret == 0) { + ret = wc_AesGcmSetKey(&aes, key, AES_256_KEY_SIZE); + if (ret != 0) + fprintf(stderr, "Set Key failed: %d\n", ret); + } + if (ret == 0) { + ret = wc_Pkcs11StoreKey(token, PKCS11_KEY_TYPE_AES_GCM, 1, + (void*)&aes); + if (ret == NOT_COMPILED_IN) + ret = 0; + if (ret != 0) + fprintf(stderr, "Store Key failed: %d\n", ret); + } + if (ret == 0) { + ret = wc_AesGcmEncrypt(&aes, enc, data, sizeof(data), iv, + sizeof(iv), authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Encrypt failed: %d\n", ret); + } + if (ret == 0) { + if (memcmp(enc, exp256, sizeof(exp256)) != 0) { + fprintf(stderr, "Encrypted data didn't match expected\n"); + ret = -1; + } + } + if (ret == 0) { + if (memcmp(authTag, expTag256, sizeof(expTag256)) != 0) { + fprintf(stderr, "Auth tag didn't match expected\n"); + ret = -1; + } + } + if (ret == 0) { + ret = wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc), iv, sizeof(iv), + authTag, sizeof(authTag), NULL, 0); + if (ret != 0) + fprintf(stderr, "Decrypt failed: %d\n", ret); + } + if (ret == 0) { + if (memcmp(dec, data, ret) != 0) { + fprintf(stderr, "Decrypted data didn't match plaintext\n"); + ret = -1; + } + } + wc_Pkcs11Token_Close(token); + } + + return ret; +} +#endif + +int pkcs11_test(int devId, Pkcs11Token* token) +{ + int ret = 0; +#ifndef NO_RSA + RsaKey key; +#endif +#ifdef HAVE_ECC + ecc_key eccPriv; + ecc_key eccPub; + ecc_key eccPrivSoft; + ecc_key eccPubSoft; +#endif + + memset(&key, 0, sizeof(key)); + + if (ret != 0) + fprintf(stderr, "Failed to register device\n"); +#ifndef NO_RSA + if (ret == 0) { + fprintf(stderr, "Decode RSA Key\n"); + ret = decode_rsa_key(&key, devId); + } + if (ret == 0) { + fprintf(stderr, "Encrypt/Decrypt with RSA Key\n"); + ret = rsaenc_test(&key); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with RSA Key\n"); + ret = rsasig_test(&key); + } + wc_FreeRsaKey(&key); + + if (ret == 0) { + wc_Pkcs11Token_Open(token, 1); + fprintf(stderr, "Generate RSA Key\n"); + ret = gen_rsa_key(token, &key, NULL, 0, devId); + } + if (ret == 0) { + fprintf(stderr, "Encrypt/Decrypt with RSA Key\n"); + ret = rsaenc_test(&key); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with RSA Key\n"); + ret = rsasig_test(&key); + } + wc_Pkcs11Token_Close(token); + wc_FreeRsaKey(&key); + + if (ret == 0) { + wc_Pkcs11Token_Open(token, 1); + fprintf(stderr, "Generate RSA Key\n"); + ret = gen_rsa_key(token, &key, (unsigned char*)"123", 3, + devId); + } + if (ret == 0) { + fprintf(stderr, "Encrypt/Decrypt with RSA Key\n"); + ret = rsaenc_test(&key); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with RSA Key\n"); + ret = rsasig_test(&key); + } + wc_Pkcs11Token_Close(token); + wc_FreeRsaKey(&key); +#endif + +#ifdef HAVE_ECC + if (ret == 0) { + fprintf(stderr, "Decode ECC Keys\n"); + ret = decode_ecc_keys(&eccPrivSoft, &eccPubSoft, INVALID_DEVID); + } + + if (ret == 0) { + fprintf(stderr, "Decode ECC Keys\n"); + ret = decode_ecc_keys(&eccPriv, &eccPub, devId); + } + if (ret == 0) { + fprintf(stderr, "Derive secret with ECC Keys\n"); + ret = ecdh_test(&eccPriv, &eccPub, 1); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with ECC Keys\n"); + ret = ecdsa_test(&eccPriv, &eccPub, &eccPrivSoft, &eccPubSoft); + } + wc_ecc_free(&eccPub); + wc_ecc_free(&eccPriv); + + if (ret == 0) { + wc_Pkcs11Token_Open(token, 1); + fprintf(stderr, "Generate EC Keys\n"); + ret = gen_ec_keys(token, &eccPriv, NULL, 0, devId); + memcpy(&eccPub, &eccPriv, sizeof(ecc_key)); + eccPub.devId = INVALID_DEVID; + } + if (ret == 0) { + fprintf(stderr, "Derive secret with ECC Keys\n"); + ret = ecdh_test(&eccPriv, &eccPriv, 0); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with ECC Keys\n"); + ret = ecdsa_test(&eccPriv, &eccPriv, NULL, &eccPub); + } + wc_Pkcs11Token_Close(token); + wc_ecc_free(&eccPriv); + + if (ret == 0) { + wc_Pkcs11Token_Open(token, 1); + fprintf(stderr, "Generate EC Keys\n"); + ret = gen_ec_keys(token, &eccPriv, (unsigned char*)"123ecc", 6, + devId); + memcpy(&eccPub, &eccPriv, sizeof(ecc_key)); + eccPub.devId = INVALID_DEVID; + } + if (ret == 0) { + fprintf(stderr, "Derive secret with ECC Keys\n"); + ret = ecdh_test(&eccPriv, &eccPriv, 0); + } + if (ret == 0) { + fprintf(stderr, "Sign/Verify with ECC Keys\n"); + ret = ecdsa_test(&eccPriv, &eccPriv, NULL, &eccPub); + } + wc_Pkcs11Token_Close(token); + wc_ecc_free(&eccPriv); + + wc_ecc_free(&eccPubSoft); + wc_ecc_free(&eccPrivSoft); +#endif + +#if !defined(NO_AES) && defined(HAVE_AESGCM) + if (ret == 0) { + fprintf(stderr, "AES-GCM encrypt/decrypt\n"); + ret = aesgcm_test(devId, token); + } +#endif + + if (ret == 0) + fprintf(stderr, "Success\n"); + + return ret; +} + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: pkcs11_test \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + wc_InitRng_ex(&rng, NULL, devId); + + ret = pkcs11_test(devId, &token); + if (ret != 0) + ret = 1; + + wc_FreeRng(&rng); + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} + diff --git a/pkcs11/softhsm2.sh b/pkcs11/softhsm2.sh new file mode 100755 index 00000000..8b645dec --- /dev/null +++ b/pkcs11/softhsm2.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ $# -gt 0 ] +then + SOFTHSM2_SLOTID=$1 +fi + +echo "# Using slot ID: $SOFTHSM2_SLOTID" +echo +echo "# RSA example" +./pkcs11_rsa /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki +echo +echo "# ECC example" +./pkcs11_ecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki +echo +echo "# AES-GCM example" +./pkcs11_aesgcm /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki +echo +echo "# PKCS#11 test" +./pkcs11_test /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki + From cfba1af8af9bb4f93b35d697c99217f0de8c79c8 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 6 Feb 2019 08:23:37 +1000 Subject: [PATCH 2/5] Add PKCS #11 API README and generate ECC key sample --- .gitignore | 1 + pkcs11/PKCS11.md | 164 +++++++++++++++++++++++++++++++++++++++++ pkcs11/opencryptoki.sh | 3 + pkcs11/pkcs11_genecc.c | 135 +++++++++++++++++++++++++++++++++ pkcs11/softhsm2.sh | 3 + 5 files changed, 306 insertions(+) create mode 100644 pkcs11/PKCS11.md create mode 100644 pkcs11/pkcs11_genecc.c diff --git a/.gitignore b/.gitignore index 2d1f211d..d0f2295f 100644 --- a/.gitignore +++ b/.gitignore @@ -139,6 +139,7 @@ rsa/verify pkcs11/pkcs11_test pkcs11/pkcs11_rsa pkcs11/pkcs11_ecc +pkcs11/pkcs11_genecc pkcs11/pkcs11_aesgcm pkcs11/softhsm2.conf pkcs11/softhsm2 diff --git a/pkcs11/PKCS11.md b/pkcs11/PKCS11.md new file mode 100644 index 00000000..e7564af8 --- /dev/null +++ b/pkcs11/PKCS11.md @@ -0,0 +1,164 @@ + + +## Using PKCS #11 with wolfSSL + +# Initializing PKCS #11 library + +In order to use a PKCS #11 device it is necessary to load the device specific +PKCS #11 shared (or dynamic) library. + +The wolfSSL API wc_Pkcs11_Initialize() takes the path to the library and +initializes a Pkcs11Dev instance for accessing tokens. + +/** + * Load library, get function list and initialize PKCS#11. + * + * @param dev [in] Device object. + * @param library [in] Library name including path. + * @param heap [in] Heap hint. + * @return BAD_FUNC_ARG when dev or library are NULL pointers. + * BAD_PATH_ERROR when dynamic library cannot be opened. + * WC_INIT_E when the initialization PKCS#11 fails. + * WC_HW_E when unable to get PKCS#11 function list. + * 0 on success. + */ +int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap); + +# Finalizing PKCS #11 library + +When the device is not longer required then Pkcs11Dev instance can be finalized. +This unloads the shared library. + +/** + * Close the Pkcs#11 library. + * + * @param dev [in] Device object. + */ +void wc_Pkcs11_Finalize(Pkcs11Dev* dev); + +# Initializing a token + +PKCS #11 defines tokens to be in slots. wolfSSL assumes that the token is in a +slot and abstracts slots away. + +To initialize a token instance using the API wc_Pkcs11Token_Init(). +The slot number of the token need not be supplied if the token name is unique. +Pass -1 for the slotId to find token by name on any slot. +The userPin must be supplied to login into a session. + +/** + * Set up a token for use. + * + * @param token [in] Token object. + * @param dev [in] PKCS#11 device object. + * @param slotId [in] Slot number of the token.
+ * Passing -1 uses the first available slot. + * @param tokenName [in] Name of token to initialize. + * @param userPin [in] PIN to use to login as user. + * @param userPinSz [in] Number of bytes in PIN. + * @return BAD_FUNC_ARG when token, dev and/or tokenName is NULL. + * WC_INIT_E when initializing token fails. + * WC_HW_E when another PKCS#11 library call fails. + * -1 when no slot available. + * 0 on success. + */ +int wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId, + const char* tokenName, const unsigned char* userPin, int userPinSz); + +# Finalize token + +Finalizing a token will close all session on the token and zeroize any User PIN. + +/** + * Finalize token. + * Closes all sessions on token. + * + * @param token [in] Token object. + */ +void wc_Pkcs11Token_Final(Pkcs11Token* token); + +# Open Session + +A session needs to be opened on a token in order for operations to be performed. +If keys need to persist across operations in a session or you need to manage +sessions in the application then opening a session using the API +wc_Pkcs11Token_Open(). + +A session can be opened for reading and writing by setting the flag to 1. + +/** + * Open a session on the token to be used for all operations. + * + * @param token [in] Token object. + * @param readWrite [in] Boolean indicating to open session for Read/Write. + * @return BAD_FUNC_ARG when token is NULL. + * WC_HW_E when opening the session fails. + * 0 on success. + */ +int wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite); + + +# Close Session + +If you opened a session in your application then you should close it too. +Use the API wc_Pkcs11Token_Close() to close the session. wolfSSL will create +a session to perform any new cryptographic operations. +Any keys in the session will be lost. + +/** + * Close the token's session. + * All object, like keys, will be destoyed. + * + * @param token [in] Token object. + */ +void wc_Pkcs11Token_Close(Pkcs11Token* token); + +# Registering a PKCS #11 device + +Cryptographic operations will be performed on a PKCS #11 device when initialized +with a device identifier associated with a token. +An application chooses a number that will be the device identifier and +associates the PKCS #11 callback and Pkcs11Token pointer using the API +wc_CryptoDev_RegisterDevice(). + +e.g.: + int ret; + int devId = 1; + Pkcs11Token token; + + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, &token); + if (ret != 0) + fprintf(stderr, "Failed to register token"); + +# Initializing ECDSA Cryptographic Operation + +To initialize ECC signing or verification operration to use the PKCS #11 token, +use the API wc_ecc_init_ex(). + +e.g: + int ret; + ecc_key key; + int devId = 1; + + ret = wc_ecc_init_ex(&key, NULL, devId); + + +# Using a Private Key + +To use an EC private key, load as normal. +(Keys can be generated on the device and the private key will not come off.) + +Perform the cryptographic operation as normal and the private key will be loaded +onto the token in the session if required. + + +# Performing other PKCS #11 operations + +The function list is available as the field func in Pkcs11Dev, Pkcs11Token and +Pkcs11Session. + +The Slot Id is availabe in Pkcs11Token and Pkcs11Session as slotId. + +The session handle is available in Pkcs11Token and Pkcs11Session aa handle. + + diff --git a/pkcs11/opencryptoki.sh b/pkcs11/opencryptoki.sh index 457b3933..c6167b87 100755 --- a/pkcs11/opencryptoki.sh +++ b/pkcs11/opencryptoki.sh @@ -9,6 +9,9 @@ echo echo "# ECC example" ./pkcs11_ecc /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki echo +echo "# Generate ECC example" +./pkcs11_genecc /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki +echo echo "# AES-GCM example" ./pkcs11_aesgcm /usr/local/lib/opencryptoki/libopencryptoki.so 3 SoftToken cryptoki echo diff --git a/pkcs11/pkcs11_genecc.c b/pkcs11/pkcs11_genecc.c new file mode 100644 index 00000000..94ba11be --- /dev/null +++ b/pkcs11/pkcs11_genecc.c @@ -0,0 +1,135 @@ + + +#include +#include +#include +#include +#include +#include + +static WC_RNG rng; + +int gen_ec_keys(Pkcs11Token* token, ecc_key* key, unsigned char* id, int idLen, + int devId) +{ + int ret; + + ret = wc_ecc_init_id(key, id, idLen, NULL, devId); + if (ret != 0) + fprintf(stderr, "Failed to initialize EC key: %d\n", ret); + if (ret == 0) { + ret = wc_ecc_make_key_ex(&rng, 32, key, ECC_CURVE_DEF); + if (ret != 0) + fprintf(stderr, "Failed to generate EC key: %d\n", ret); + } + return ret; +} + +int ecdsa_sign_verify(int devId, Pkcs11Token* token) +{ + int ret = 0; + byte hash[32], out[128]; + word32 hashSz, outSz; + int verify; + ecc_key eccKey; + + memset(hash, 9, sizeof(hash)); + hashSz = sizeof(hash); + outSz = sizeof(out); + + ret = wc_Pkcs11Token_Open(token, 1); + if (ret == 0) { + fprintf(stderr, "Generate EC Keys\n"); + ret = gen_ec_keys(token, &eccKey, (unsigned char*)"123ecc", 6, devId); + + if (ret == 0) { + ret = wc_ecc_sign_hash(hash, hashSz, out, &outSz, &rng, &eccKey); + if (ret < 0) + fprintf(stderr, "Failed to sign: %d\n", ret); + } + if (ret == 0) { + /* Don't use device for public key operation. */ + eccKey.devId = INVALID_DEVID; + + ret = wc_ecc_verify_hash(out, outSz, hash, (int)hashSz, &verify, + &eccKey); + if (ret < 0 || !verify) + fprintf(stderr, "Failed to verify: %d (%d)\n", ret, verify); + if (!verify) + ret = -1; + } + wc_Pkcs11Token_Close(token); + wc_ecc_free(&eccKey); + } + + return ret; +} + + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: pkcs11_genecc \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + wc_InitRng_ex(&rng, NULL, devId); + + ret = ecdsa_sign_verify(devId, &token); + if (ret != 0) + ret = 1; + + wc_FreeRng(&rng); + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} + diff --git a/pkcs11/softhsm2.sh b/pkcs11/softhsm2.sh index 8b645dec..299a17ea 100755 --- a/pkcs11/softhsm2.sh +++ b/pkcs11/softhsm2.sh @@ -13,6 +13,9 @@ echo echo "# ECC example" ./pkcs11_ecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki echo +echo "# Generate ECC example" +./pkcs11_genecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki +echo echo "# AES-GCM example" ./pkcs11_aesgcm /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki echo From 7e771fdfdf04723416928cf5f480c344d8fc8fdb Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 8 Feb 2019 12:26:58 +1000 Subject: [PATCH 3/5] Add SSL server sample --- .gitignore | 1 + pkcs11/README.md | 27 +++- pkcs11/server-tls-pkcs11.c | 274 +++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 pkcs11/server-tls-pkcs11.c diff --git a/.gitignore b/.gitignore index d0f2295f..8fdd2ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -141,6 +141,7 @@ pkcs11/pkcs11_rsa pkcs11/pkcs11_ecc pkcs11/pkcs11_genecc pkcs11/pkcs11_aesgcm +pkcs11/server-tls-pkcs11 pkcs11/softhsm2.conf pkcs11/softhsm2 diff --git a/pkcs11/README.md b/pkcs11/README.md index 3011ed68..13a58766 100644 --- a/pkcs11/README.md +++ b/pkcs11/README.md @@ -65,7 +65,7 @@ SoftToken" | pkcsconf -I -c 3 echo "87654321 cryptoki -cryptoki " | pkcsconf -P -c 3 +cryptoki" | pkcsconf -P -c 3 echo "cryptoki cryptoki @@ -81,3 +81,28 @@ sudo /usr/local/sbin/pkcsslotd ./opencryptoki.sh + + +### Server TLS PKCS #11 + +The example server-tls-pkcs11 is a server that uses a private key that has been +stored on the PKCS #11 device. + +The id of the private key is two hex bytes: 0x00, 0x01 + +Change this to be the id that you set when importing the key. + +## SoftHSM version 2 + +# Import private key + +softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label rsa2048 + +## Run server and client + +./server-tls-pkcs11 $SOFTHSM2_SLOTID SoftToken cryptoki + +# In wolfSSL directory +./examples/client/client + + diff --git a/pkcs11/server-tls-pkcs11.c b/pkcs11/server-tls-pkcs11.c new file mode 100644 index 00000000..8c952506 --- /dev/null +++ b/pkcs11/server-tls-pkcs11.c @@ -0,0 +1,274 @@ +/* server-tls.c + * + * Copyright (C) 2006-2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* the usual suspects */ +#include +#include +#include + +/* socket includes */ +#include +#include +#include +#include + +/* wolfSSL */ +#include +#include +#include + +#define DEFAULT_PORT 11111 + +#define CERT_FILE "../certs/server-cert.pem" +#define PRIV_KEY_ID {0x00, 0x01} + +#ifndef WOLFCRYPT_ONLY +int server_tls(int devId) +{ + int sockfd; + int connd; + struct sockaddr_in servAddr; + struct sockaddr_in clientAddr; + socklen_t size = sizeof(clientAddr); + char buff[256]; + size_t len; + int shutdown = 0; + int ret; + unsigned char privKeyId[] = PRIV_KEY_ID; + + /* declare wolfSSL objects */ + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + + + /* Initialize wolfSSL */ + wolfSSL_Init(); + + + + /* Create a socket that uses an internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "ERROR: failed to create the socket\n"); + return -1; + } + + + + /* Create and initialize WOLFSSL_CTX */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + return -1; + } + + if (wolfSSL_CTX_SetDevId(ctx, devId) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + return -1; + } + + /* Load server certificates into WOLFSSL_CTX */ + if (wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) + != SSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CERT_FILE); + return -1; + } + + /* Load server key into WOLFSSL_CTX */ + if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, 2, 2048) != SSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to set id.\n"); + return -1; + } + + + + /* Initialize the server address struct with zeros */ + memset(&servAddr, 0, sizeof(servAddr)); + + /* Fill in the server address */ + servAddr.sin_family = AF_INET; /* using IPv4 */ + servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */ + servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */ + + + + /* Bind the server socket to our port */ + if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { + fprintf(stderr, "ERROR: failed to bind\n"); + return -1; + } + + /* Listen for a new connection, allow 5 pending connections */ + if (listen(sockfd, 5) == -1) { + fprintf(stderr, "ERROR: failed to listen\n"); + return -1; + } + + + + /* Continue to accept clients until shutdown is issued */ + while (!shutdown) { + printf("Waiting for a connection...\n"); + + /* Accept client connections */ + if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size)) + == -1) { + fprintf(stderr, "ERROR: failed to accept the connection\n\n"); + return -1; + } + + /* Create a WOLFSSL object */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); + return -1; + } + + /* Attach wolfSSL to the socket */ + wolfSSL_set_fd(ssl, connd); + + /* Establish TLS connection */ + ret = wolfSSL_accept(ssl); + if (ret != SSL_SUCCESS) { + fprintf(stderr, "wolfSSL_accept error = %d\n", + wolfSSL_get_error(ssl, ret)); + return -1; + } + + + printf("Client connected successfully\n"); + + + + /* Read the client data into our buff array */ + memset(buff, 0, sizeof(buff)); + if (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) { + fprintf(stderr, "ERROR: failed to read\n"); + return -1; + } + + /* Print to stdout any data the client sends */ + printf("Client: %s\n", buff); + + /* Check for server shutdown command */ + if (strncmp(buff, "shutdown", 8) == 0) { + printf("Shutdown command issued!\n"); + shutdown = 1; + } + + + + /* Write our reply into buff */ + memset(buff, 0, sizeof(buff)); + memcpy(buff, "I hear ya fa shizzle!\n", sizeof(buff)); + len = strnlen(buff, sizeof(buff)); + + /* Reply back to the client */ + if (wolfSSL_write(ssl, buff, len) != len) { + fprintf(stderr, "ERROR: failed to write\n"); + return -1; + } + + + + /* Cleanup after this connection */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ + close(connd); /* Close the connection to the client */ + } + + printf("Shutdown complete\n"); + + + + /* Cleanup and return */ + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ + close(sockfd); /* Close the socket listening for clients */ + return 0; /* Return reporting a success */ +} +#endif + +int main(int argc, char* argv[]) +{ + int ret; + const char* library; + const char* slot; + const char* tokenName; + const char* userPin; + Pkcs11Dev dev; + Pkcs11Token token; + int slotId; + int devId = 1; + + if (argc != 5) { + fprintf(stderr, + "Usage: server_tls_pkcs11 \n"); + return 1; + } + + library = argv[1]; + slot = argv[2]; + tokenName = argv[3]; + userPin = argv[4]; + slotId = atoi(slot); + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); + + ret = wc_Pkcs11_Initialize(&dev, library, NULL); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 library\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_Pkcs11Token_Init(&token, &dev, slotId, tokenName, + (byte*)userPin, strlen(userPin)); + if (ret != 0) { + fprintf(stderr, "Failed to initialize PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, + &token); + if (ret != 0) { + fprintf(stderr, "Failed to register PKCS#11 token\n"); + ret = 2; + } + if (ret == 0) { + #if !defined(WOLFCRYPT_ONLY) + ret = server_tls(devId); + if (ret != 0) + ret = 1; + #endif + } + wc_Pkcs11Token_Final(&token); + } + wc_Pkcs11_Finalize(&dev); + } + + wolfCrypt_Cleanup(); + + return ret; +} + From 10bf5d543b77325be463013162f249413bb684c3 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 12 Feb 2019 16:10:03 -0800 Subject: [PATCH 4/5] Fixes when building against latest master (plus https://github.com/wolfSSL/wolfssl/pull/2070). Updates to README.md for building wolfSSL. --- pkcs11/Makefile | 8 ++++---- pkcs11/README.md | 12 +++++++++++- pkcs11/server-tls-pkcs11.c | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/pkcs11/Makefile b/pkcs11/Makefile index 3f2c1889..3085ca27 100644 --- a/pkcs11/Makefile +++ b/pkcs11/Makefile @@ -12,10 +12,10 @@ DEBUG_INC_PATHS = -MD OPTIMIZE = -Os # Options -CFLAGS+=$(DEBUG_FLAGS) -#CFLAGS+=$(OPTIMIZE) -LIBS+=$(STATIC_LIB) -ldl -lm -#LIBS+=$(DYN_LIB) +#CFLAGS+=$(DEBUG_FLAGS) +CFLAGS+=$(OPTIMIZE) +#LIBS+=$(STATIC_LIB) -ldl -lm +LIBS+=$(DYN_LIB) # build targets SRC=$(wildcard *.c) diff --git a/pkcs11/README.md b/pkcs11/README.md index 13a58766..83098b21 100644 --- a/pkcs11/README.md +++ b/pkcs11/README.md @@ -100,9 +100,19 @@ softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id ## Run server and client +### Build wolfSSL + +./autogen.sh +./configure --enable-pkcs11 +make +sudo make install + +### Build Server Example + +make ./server-tls-pkcs11 $SOFTHSM2_SLOTID SoftToken cryptoki -# In wolfSSL directory +### Run Client ./examples/client/client diff --git a/pkcs11/server-tls-pkcs11.c b/pkcs11/server-tls-pkcs11.c index 8c952506..592bce1f 100644 --- a/pkcs11/server-tls-pkcs11.c +++ b/pkcs11/server-tls-pkcs11.c @@ -95,7 +95,7 @@ int server_tls(int devId) } /* Load server key into WOLFSSL_CTX */ - if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, 2, 2048) != SSL_SUCCESS) { + if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, 2, devId, 2048) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to set id.\n"); return -1; } From 4b0a218e089b5ad0b7c762ad27faf23c55453bbd Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 13 Feb 2019 13:41:52 -0800 Subject: [PATCH 5/5] Updates to README.md and PKCS11.md documents. Cleanup to use sizeof for `privKeyId` in TLS server example. --- pkcs11/PKCS11.md | 101 ++++++++-------- pkcs11/README.md | 238 ++++++++++++++++++++++--------------- pkcs11/server-tls-pkcs11.c | 3 +- 3 files changed, 196 insertions(+), 146 deletions(-) diff --git a/pkcs11/PKCS11.md b/pkcs11/PKCS11.md index e7564af8..746efc13 100644 --- a/pkcs11/PKCS11.md +++ b/pkcs11/PKCS11.md @@ -1,15 +1,12 @@ +# Using PKCS #11 with wolfSSL +## Initializing PKCS #11 library -## Using PKCS #11 with wolfSSL +In order to use a PKCS #11 device it is necessary to load the device specific PKCS #11 shared (or dynamic) library. -# Initializing PKCS #11 library - -In order to use a PKCS #11 device it is necessary to load the device specific -PKCS #11 shared (or dynamic) library. - -The wolfSSL API wc_Pkcs11_Initialize() takes the path to the library and -initializes a Pkcs11Dev instance for accessing tokens. +The wolfSSL API `wc_Pkcs11_Initialize()` takes the path to the library and initializes a Pkcs11Dev instance for accessing tokens. +``` /** * Load library, get function list and initialize PKCS#11. * @@ -23,29 +20,34 @@ initializes a Pkcs11Dev instance for accessing tokens. * 0 on success. */ int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap); +``` -# Finalizing PKCS #11 library +## Finalizing PKCS #11 library When the device is not longer required then Pkcs11Dev instance can be finalized. + This unloads the shared library. +``` /** * Close the Pkcs#11 library. * * @param dev [in] Device object. */ void wc_Pkcs11_Finalize(Pkcs11Dev* dev); +``` -# Initializing a token +## Initializing a token -PKCS #11 defines tokens to be in slots. wolfSSL assumes that the token is in a -slot and abstracts slots away. +PKCS #11 defines tokens to be in slots. wolfSSL assumes that the token is in a slot and abstracts slots away. + +To initialize a token instance using the API `wc_Pkcs11Token_Init()`. + +The slot number of the token need not be supplied if the token name is unique. Pass -1 for the slotId to find token by name on any slot. -To initialize a token instance using the API wc_Pkcs11Token_Init(). -The slot number of the token need not be supplied if the token name is unique. -Pass -1 for the slotId to find token by name on any slot. The userPin must be supplied to login into a session. +``` /** * Set up a token for use. * @@ -64,11 +66,13 @@ The userPin must be supplied to login into a session. */ int wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId, const char* tokenName, const unsigned char* userPin, int userPinSz); +``` -# Finalize token +## Finalize token Finalizing a token will close all session on the token and zeroize any User PIN. +``` /** * Finalize token. * Closes all sessions on token. @@ -76,16 +80,17 @@ Finalizing a token will close all session on the token and zeroize any User PIN. * @param token [in] Token object. */ void wc_Pkcs11Token_Final(Pkcs11Token* token); +``` -# Open Session +## Open Session A session needs to be opened on a token in order for operations to be performed. -If keys need to persist across operations in a session or you need to manage -sessions in the application then opening a session using the API -wc_Pkcs11Token_Open(). + +If keys need to persist across operations in a session or you need to manage sessions in the application then opening a session using the API `wc_Pkcs11Token_Open()`. A session can be opened for reading and writing by setting the flag to 1. +``` /** * Open a session on the token to be used for all operations. * @@ -96,15 +101,17 @@ A session can be opened for reading and writing by setting the flag to 1. * 0 on success. */ int wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite); +``` - -# Close Session +## Close Session If you opened a session in your application then you should close it too. -Use the API wc_Pkcs11Token_Close() to close the session. wolfSSL will create -a session to perform any new cryptographic operations. + +Use the API `wc_Pkcs11Token_Close()` to close the session. wolfSSL will create a session to perform any new cryptographic operations. + Any keys in the session will be lost. +``` /** * Close the token's session. * All object, like keys, will be destoyed. @@ -112,15 +119,15 @@ Any keys in the session will be lost. * @param token [in] Token object. */ void wc_Pkcs11Token_Close(Pkcs11Token* token); +``` -# Registering a PKCS #11 device +## Registering a PKCS #11 device -Cryptographic operations will be performed on a PKCS #11 device when initialized -with a device identifier associated with a token. -An application chooses a number that will be the device identifier and -associates the PKCS #11 callback and Pkcs11Token pointer using the API -wc_CryptoDev_RegisterDevice(). +Cryptographic operations will be performed on a PKCS #11 device when initialized with a device identifier associated with a token. +An application chooses a number that will be the device identifier and associates the PKCS #11 callback and Pkcs11Token pointer using the API `wc_CryptoDev_RegisterDevice()`. + +``` e.g.: int ret; int devId = 1; @@ -129,36 +136,32 @@ e.g.: ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb, &token); if (ret != 0) fprintf(stderr, "Failed to register token"); +``` -# Initializing ECDSA Cryptographic Operation +## Initializing ECDSA Cryptographic Operation -To initialize ECC signing or verification operration to use the PKCS #11 token, -use the API wc_ecc_init_ex(). +To initialize ECC signing or verification operation to use the PKCS #11 token, use the API `wc_ecc_init_ex()`. +``` e.g: int ret; ecc_key key; int devId = 1; ret = wc_ecc_init_ex(&key, NULL, devId); +``` + +## Using a Private Key + +To use an EC private key, load as normal. (Keys can be generated on the device and the private key will not come off.) + +Perform the cryptographic operation as normal and the private key will be loaded onto the token in the session if required. -# Using a Private Key +## Performing other PKCS #11 operations -To use an EC private key, load as normal. -(Keys can be generated on the device and the private key will not come off.) - -Perform the cryptographic operation as normal and the private key will be loaded -onto the token in the session if required. - - -# Performing other PKCS #11 operations - -The function list is available as the field func in Pkcs11Dev, Pkcs11Token and -Pkcs11Session. - -The Slot Id is availabe in Pkcs11Token and Pkcs11Session as slotId. - -The session handle is available in Pkcs11Token and Pkcs11Session aa handle. +The function list is available as the field `func` in Pkcs11Dev, Pkcs11Token and Pkcs11Session. +The Slot Id is available in Pkcs11Token and Pkcs11Session as `slotId`. +The session handle is available in Pkcs11Token and Pkcs11Session as `handle`. diff --git a/pkcs11/README.md b/pkcs11/README.md index 83098b21..a2b2240c 100644 --- a/pkcs11/README.md +++ b/pkcs11/README.md @@ -1,118 +1,164 @@ +# Examples for PKCS #11 with wolfSSL + +These examples demonstrate using wolfSSL's PKCS #11 feature for the following algorithms: + +* ECC Key Gen, Sign/Verify and ECDHE (Shared Secret) +* RSA Key Gen and Sign/Verify +* AES GCM + +This also includes a TLS server example using a PKCS 11 based key. + +## API Reference + +See [PKCS11.md](./PKCS11.md) in this folder. + +## Setting up and testing SoftHSM version 2 + +1. Change to source code directory of SoftHSM version 2 + + This tool can be found here: https://github.com/opendnssec/SoftHSMv2 + + ``` + ./autogen.sh + ./configure --disable-gost + sudo make install + ``` + + *Note: May need to install pkg-config and libssl-dev* + +2. Change to wolfssl directory + + ``` + ./autogen.sh + ./configure --enable-pkcs11 + make + sudo make install + ``` + +3. Change to wolfssl-examples/pkcs11 directory + + ``` + ./mksofthsm2_conf.sh + export SOFTHSM2_CONF=$PWD/softhsm2.conf + ``` + +4. Running tests + + `softhsm2-util --init-token --slot 0 --label SoftToken` + + * Use PIN: cryptoki + * Use User PIN: cryptoki + + Use the slot id from the output: + + `export SOFTHSM2_SLOTID=` + + Run the examples: + + `./softhsm2.sh` -### Setting up and testing SoftHSM version 2 - -# Change to source code directory of SoftHSM version 2 - -sh ./autogen.sh -# (May need to install pkg-config and libssl-dev) - -./configure --disable-gost - -sudo make install +## Setting up and testing openCryptoki -# Change to wolfssl-examples/pkcs11 directory +1. Change to source code directory of openCryptoki -./mksofthsm2_conf.sh + This tool can be found here: https://github.com/opencryptoki/opencryptoki -export SOFTHSM2_CONF=$PWD/softhsm2.conf + ``` + ./bootstrap.sh + ./configure + make + ``` + + *Note: May need to install flex, bison and openldap-devel [or libldap2-dev]* + +2. Setup pkcs11 group and put current user into it + + ``` + sudo groupadd pkcs11 + sudo usermod -a -G pkcs11 $USER + ``` + +3. Install library + + ``` + sudo make install + sudo ldconfig /usr/local/lib + ``` + +4. Start the daemon + + `sudo /usr/local/sbin/pkcsslotd` + + *Note: May need to logout and login to be able to use pkcsconf.* + +5. Setup token + + ``` + echo "87654321 + SoftToken" | pkcsconf -I -c 3 + ``` + + ``` + echo "87654321 + cryptoki + cryptoki" | pkcsconf -P -c 3 + ``` + + ``` + echo "cryptoki + cryptoki + cryptoki" | pkcsconf -u -c 3 + ``` + +6. Start daemon if not running already: + + `sudo /usr/local/sbin/pkcsslotd` + +7. Build and install wolfSSL + + Change to wolfssl directory and run: + + ``` + ./autogen.sh + ./configure --enable-pkcs11 + make + sudo make install + ``` -# Running tests +8. Running tests -softhsm2-util --init-token --slot 0 --label SoftToken -# Use PIN: cryptoki -# Use User PIN: cryptoki - -# Use the slot id from the output - -export SOFTHSM2_SLOTID= - -./softhsm2.sh + Change to wolfssl-examples/pkcs11 directory: + + `./opencryptoki.sh` +## TLS Server Example with PKCS #11 -### Setting up and testing openCryptoki +The example `server-tls-pkcs11` is a server that uses a private key that has been stored on the PKCS #11 device. - -# Change to source code directory of openCryptoki - -./bootstrap.sh - -./configure -# (May need to install flex, bison and openldap-devel [or libldap2-dev].) - -make - -# Setup pkcs11 group and put current user into it -sudo groupadd pkcs11 -sudo usermod -a -G pkcs11 $USER - -# Install library -sudo make install - -sudo ldconfig /usr/local/lib - -# Start the daemon -sudo /usr/local/sbin/pkcsslotd - -# (May need to logout and login to be able to use pkcsconf) - -# Setup token -echo "87654321 -SoftToken" | pkcsconf -I -c 3 - -echo "87654321 -cryptoki -cryptoki" | pkcsconf -P -c 3 - -echo "cryptoki -cryptoki -cryptoki" | pkcsconf -u -c 3 - - -# Running tests - -# Start daemon if not running already -sudo /usr/local/sbin/pkcsslotd - -# Change to wolfssl-examples/pkcs11 directory - -./opencryptoki.sh - - - -### Server TLS PKCS #11 - -The example server-tls-pkcs11 is a server that uses a private key that has been -stored on the PKCS #11 device. - -The id of the private key is two hex bytes: 0x00, 0x01 +The id of the private key is two hex bytes: `0x00, 0x01` Change this to be the id that you set when importing the key. -## SoftHSM version 2 +1. SoftHSM version 2 -# Import private key + Import private key: + + `softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label rsa2048` -softhsm2-util --import ../certs/server-keyPkcs8.pem --slot $SOFTHSM2_SLOTID --id 0001 --label rsa2048 + Enter PIN: cryptoki -## Run server and client +2. Run server and client -### Build wolfSSL - -./autogen.sh -./configure --enable-pkcs11 -make -sudo make install - -### Build Server Example - -make -./server-tls-pkcs11 $SOFTHSM2_SLOTID SoftToken cryptoki - -### Run Client -./examples/client/client + `./server-tls-pkcs11 /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki` + + From wolfssl root: + `./examples/client/client` +## Support + +For questions please contact wolfSSL support by email at [support@wolfssl.com](mailto:support@wolfssl.com) diff --git a/pkcs11/server-tls-pkcs11.c b/pkcs11/server-tls-pkcs11.c index 592bce1f..463280da 100644 --- a/pkcs11/server-tls-pkcs11.c +++ b/pkcs11/server-tls-pkcs11.c @@ -95,7 +95,8 @@ int server_tls(int devId) } /* Load server key into WOLFSSL_CTX */ - if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, 2, devId, 2048) != SSL_SUCCESS) { + if (wolfSSL_CTX_use_PrivateKey_id(ctx, privKeyId, sizeof(privKeyId), devId, + 2048) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to set id.\n"); return -1; }