Add PKCS #11 API README and generate ECC key sample
parent
0e65ab1c3c
commit
cfba1af8af
|
@ -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
|
||||
|
|
|
@ -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.<br>
|
||||
* 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.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/wc_pkcs11.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
|
||||
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 <libname> <slot> <tokenname> <userpin>\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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue