Skip to content

Commit

Permalink
Merge pull request #9 from jpbland1/add-rsa
Browse files Browse the repository at this point in the history
add rsa, currently fails because rsa keygen and export
  • Loading branch information
billphipps authored Apr 18, 2024
2 parents 7d02a84 + 363ba6d commit 42186b7
Show file tree
Hide file tree
Showing 8 changed files with 388 additions and 30 deletions.
92 changes: 91 additions & 1 deletion src/wh_client_cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ int wolfHSM_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
uint32_t field;
uint8_t* key;
uint8_t* iv;
uint8_t* in;
uint8_t* authIn;
uint8_t* authTag;
uint8_t* sig;
Expand All @@ -52,6 +51,7 @@ int wolfHSM_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
uint16_t group = WH_MESSAGE_GROUP_CRYPTO;
uint16_t action;
uint16_t dataSz;
uint8_t* in;
uint8_t* out;

if (devId == INVALID_DEVID || info == NULL)
Expand All @@ -66,6 +66,96 @@ int wolfHSM_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
packet->pkAnyReq.type = info->pk.type;
switch (info->pk.type)
{
case WC_PK_TYPE_RSA_KEYGEN:
/* set size */
packet->pkRsakgReq.size = info->pk.rsakg.size;
/* set e */
packet->pkRsakgReq.e = info->pk.rsakg.e;
/* write request */
ret = wh_Client_SendRequest(ctx, group,
WC_ALGO_TYPE_PK,
WOLFHSM_PACKET_STUB_SIZE + sizeof(packet->pkRsakgReq),
rawPacket);
if (ret == 0) {
do {
ret = wh_Client_RecvResponse(ctx, &group, &action, &dataSz,
rawPacket);
} while (ret == WH_ERROR_NOTREADY);
}
if (ret == 0) {
if (packet->rc != 0)
ret = packet->rc;
else {
info->pk.rsakg.key->devCtx =
(void*)((intptr_t)packet->pkRsakgRes.keyId);
}
}
break;
case WC_PK_TYPE_RSA:
/* in and out are after the fixed size fields */
in = (uint8_t*)(&packet->pkRsaReq + 1);
out = (uint8_t*)(&packet->pkRsaRes + 1);
/* set type */
packet->pkRsaReq.opType = info->pk.rsa.type;
/* set keyId */
packet->pkRsaReq.keyId =
(intptr_t)(info->pk.rsa.key->devCtx);
/* set inLen */
packet->pkRsaReq.inLen = info->pk.rsa.inLen;
/* set outLen */
packet->pkRsaReq.outLen = *info->pk.rsa.outLen;
/* set in */
XMEMCPY(in, info->pk.rsa.in, info->pk.rsa.inLen);
/* write request */
ret = wh_Client_SendRequest(ctx, group,
WC_ALGO_TYPE_PK,
WOLFHSM_PACKET_STUB_SIZE + sizeof(packet->pkRsaReq)
+ info->pk.rsa.inLen,
rawPacket);
/* read response */
if (ret == 0) {
do {
ret = wh_Client_RecvResponse(ctx, &group, &action, &dataSz,
rawPacket);
} while (ret == WH_ERROR_NOTREADY);
}
if (ret == 0) {
if (packet->rc != 0)
ret = packet->rc;
else {
/* read outLen */
*info->pk.rsa.outLen = packet->pkRsaRes.outLen;
/* read out */
XMEMCPY(info->pk.rsa.out, out, packet->pkRsaRes.outLen);
}
}
break;
case WC_PK_TYPE_RSA_GET_SIZE:
/* set keyId */
packet->pkRsaGetSizeReq.keyId =
(intptr_t)(info->pk.rsa_get_size.key->devCtx);
/* write request */
ret = wh_Client_SendRequest(ctx, group,
WC_ALGO_TYPE_PK,
WOLFHSM_PACKET_STUB_SIZE + sizeof(packet->pkRsaGetSizeReq),
rawPacket);
/* read response */
if (ret == 0) {
do {
ret = wh_Client_RecvResponse(ctx, &group, &action, &dataSz,
rawPacket);
} while (ret == WH_ERROR_NOTREADY);
}
if (ret == 0) {
if (packet->rc != 0)
ret = packet->rc;
else {
/* read outLen */
*info->pk.rsa_get_size.keySize =
packet->pkRsaGetSizeRes.keySize;
}
}
break;
case WC_PK_TYPE_CURVE25519_KEYGEN:
packet->pkCurve25519kgReq.sz = info->pk.curve25519kg.size;
/* write request */
Expand Down
197 changes: 171 additions & 26 deletions src/wh_server_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,54 +19,112 @@
#include "wolfhsm/wh_packet.h"
#include "wolfhsm/wh_server_crypto.h"

#ifndef NO_RSA
static int hsmCacheKeyRsa(whServerContext* server, RsaKey* key)
{
int ret = 0;
int slotIdx = 0;
whKeyId keyId = 0;
/* get a free slot */
ret = slotIdx = hsmCacheFindSlot(server);
if (ret >= 0) {
ret = keyId = hsmGetUniqueId(server);
}
if (ret > 0 ) {
/* export key */
ret = wc_RsaKeyToDer(key, server->cache[slotIdx].buffer,
WOLFHSM_KEYCACHE_BUFSIZE);
}
if (ret > 0) {
/* set meta */
XMEMSET((uint8_t*)server->cache[slotIdx].meta, 0,
sizeof(server->cache[slotIdx].meta));
server->cache[slotIdx].meta->id = keyId;
server->cache[slotIdx].meta->len = ret;
/* export keyId */
ret = keyId;
}
return ret;
}

static int hsmLoadKeyRsa(whServerContext* server, RsaKey* key, whKeyId keyId)
{
int ret = 0;
int slotIdx = 0;
uint32_t idx = 0;
uint32_t size;
/* freshen the key */
ret = slotIdx = hsmFreshenKey(server, keyId);
/* decode the key */
if (ret >= 0) {
size = WOLFHSM_KEYCACHE_BUFSIZE;
ret = wc_RsaPrivateKeyDecode(server->cache[slotIdx].buffer, &idx, key,
size);
}
return ret;
}
#endif /* !NO_RSA */

#ifdef HAVE_CURVE25519
static int hsmCacheKeyCurve25519(whServerContext* server, curve25519_key* key)
{
int ret;
int slotIdx = 0;
word32 privSz = CURVE25519_KEYSIZE;
word32 pubSz = CURVE25519_KEYSIZE;
whNvmMetadata meta[1] = {{0}};
byte keyBuf[CURVE25519_KEYSIZE * 2];
/* store public, then private so that loading an external public only key
* will work along with our keys */
ret = wc_curve25519_export_key_raw(key, keyBuf + CURVE25519_KEYSIZE,
&privSz, keyBuf, &pubSz);
/* cache key */
if (ret == 0) {
ret = hsmGetUniqueId(server);
whKeyId keyId = 0;
/* get a free slot */
ret = slotIdx = hsmCacheFindSlot(server);
if (ret >= 0) {
ret = keyId = hsmGetUniqueId(server);
}
if (ret > 0) {
XMEMSET(meta, 0, sizeof(whNvmMetadata));
meta->len = privSz + pubSz;
meta->id = ret;
ret = hsmCacheKey(server, meta, keyBuf);
/* export key */
ret = wc_curve25519_export_key_raw(key,
server->cache[slotIdx].buffer + CURVE25519_KEYSIZE, &privSz,
server->cache[slotIdx].buffer, &pubSz);
}
if (ret == 0) {
/* set meta */
XMEMSET((uint8_t*)server->cache[slotIdx].meta, 0,
sizeof(server->cache[slotIdx].meta));
server->cache[slotIdx].meta->id = keyId;
server->cache[slotIdx].meta->len = CURVE25519_KEYSIZE * 2;
/* export keyId */
ret = keyId;
}
if (ret == 0)
ret = meta->id;
return ret;
}

static int hsmLoadKeyCurve25519(whServerContext* server, curve25519_key* key, whKeyId keyId)
static int hsmLoadKeyCurve25519(whServerContext* server, curve25519_key* key,
whKeyId keyId)
{
int ret;
int ret = 0;
int slotIdx = 0;
uint32_t privSz = CURVE25519_KEYSIZE;
uint32_t pubSz = CURVE25519_KEYSIZE;
uint32_t size = privSz + pubSz;
byte keyBuf[CURVE25519_KEYSIZE * 2];
ret = hsmReadKey(server, keyId, NULL, keyBuf, &size);
/* freshen the key */
ret = slotIdx = hsmFreshenKey(server, keyId);
/* decode the key */
if (ret == 0)
ret = wc_curve25519_import_public(keyBuf, pubSz, key);
if (ret >= 0) {
ret = wc_curve25519_import_public(server->cache[slotIdx].buffer, pubSz,
key);
}
/* only import private if what we got back holds 2 keys */
if (ret == 0 && size == CURVE25519_KEYSIZE * 2)
ret = wc_curve25519_import_private(keyBuf + pubSz, privSz, key);
if (ret == 0 && server->cache[slotIdx].meta->len == CURVE25519_KEYSIZE * 2) {
ret = wc_curve25519_import_private(
server->cache[slotIdx].buffer + pubSz, privSz, key);
}
return ret;
}
#endif /* HAVE_CURVE25519 */

int wh_Server_HandleCryptoRequest(whServerContext* server,
uint16_t action, uint8_t* data, uint16_t* size)
{
int ret = 0;
word32 field;
uint32_t field;
uint8_t* in;
uint8_t* out;
whPacket* packet = (whPacket*)data;
#ifdef WOLFHSM_SYMMETRIC_INTERNAL
Expand All @@ -81,6 +139,89 @@ int wh_Server_HandleCryptoRequest(whServerContext* server,
case WC_ALGO_TYPE_PK:
switch (packet->pkAnyReq.type)
{
#ifndef NO_RSA
case WC_PK_TYPE_RSA_KEYGEN:
/* init the rsa key */
ret = wc_InitRsaKey_ex(server->crypto->rsa, NULL, INVALID_DEVID);
/* make the rsa key with the given params */
if (ret == 0) {
ret = wc_MakeRsaKey(server->crypto->rsa,
packet->pkRsakgReq.size,
packet->pkRsakgReq.e,
server->crypto->rng);
}
/* cache the generated key, data will be blown away */
if (ret == 0) {
ret = hsmCacheKeyRsa(server, server->crypto->rsa);
}
wc_FreeRsaKey(server->crypto->rsa);
if (ret > 0) {
/* set the assigned id */
packet->pkRsakgRes.keyId = ret;
*size = WOLFHSM_PACKET_STUB_SIZE +
sizeof(packet->pkRsakgRes);
ret = 0;
}
break;
case WC_PK_TYPE_RSA:
switch (packet->pkRsaReq.opType)
{
case RSA_PUBLIC_ENCRYPT:
case RSA_PUBLIC_DECRYPT:
case RSA_PRIVATE_ENCRYPT:
case RSA_PRIVATE_DECRYPT:
/* in and out are after the fixed size fields */
in = (uint8_t*)(&packet->pkRsaReq + 1);
out = (uint8_t*)(&packet->pkRsaRes + 1);
/* init rsa key */
ret = wc_InitRsaKey_ex(server->crypto->rsa, NULL,
INVALID_DEVID);
/* load the key from the keystore */
if (ret == 0) {
ret = hsmLoadKeyRsa(server, server->crypto->rsa,
packet->pkRsaReq.keyId);
}
/* do the rsa operation */
if (ret == 0) {
field = packet->pkRsaReq.outLen;
ret = wc_RsaFunction( in, packet->pkRsaReq.inLen,
out, &field, packet->pkRsaReq.opType,
server->crypto->rsa, server->crypto->rng);
}
/* free the key */
wc_FreeRsaKey(server->crypto->rsa);
if (ret == 0) {
/*set outLen */
packet->pkRsaRes.outLen = field;
*size = WOLFHSM_PACKET_STUB_SIZE +
sizeof(packet->pkRsaRes) + field;
}
break;
}
break;
case WC_PK_TYPE_RSA_GET_SIZE:
/* init rsa key */
ret = wc_InitRsaKey_ex(server->crypto->rsa, NULL,
server->crypto->devId);
/* load the key from the keystore */
if (ret == 0) {
ret = hsmLoadKeyRsa(server, server->crypto->rsa,
packet->pkRsaGetSizeReq.keyId);
}
/* get the size */
if (ret == 0)
ret = wc_RsaEncryptSize(server->crypto->rsa);
wc_FreeRsaKey(server->crypto->rsa);
if (ret > 0) {
/*set keySize */
packet->pkRsaGetSizeRes.keySize = ret;
*size = WOLFHSM_PACKET_STUB_SIZE +
sizeof(packet->pkRsaGetSizeRes);
ret = 0;
}
break;
#endif /* !NO_RSA */
#ifdef HAVE_CURVE25519
case WC_PK_TYPE_CURVE25519_KEYGEN:
/* init private key */
ret = wc_curve25519_init_ex(server->crypto->curve25519Private, NULL,
Expand All @@ -93,7 +234,8 @@ int wh_Server_HandleCryptoRequest(whServerContext* server,
}
/* cache the generated key */
if (ret == 0) {
ret = hsmCacheKeyCurve25519(server, server->crypto->curve25519Private);
ret = hsmCacheKeyCurve25519(server,
server->crypto->curve25519Private);
}
/* set the assigned id */
wc_curve25519_free(server->crypto->curve25519Private);
Expand Down Expand Up @@ -144,11 +286,13 @@ int wh_Server_HandleCryptoRequest(whServerContext* server,
packet->pkCurve25519Res.sz = field;
}
break;
#endif /* HAVE_CURVE25519 */
default:
ret = NOT_COMPILED_IN;
break;
}
break;
#ifndef WC_NO_RNG
case WC_ALGO_TYPE_RNG:
/* out is after the fixed size fields */
out = (uint8_t*)(&packet->rngRes + 1);
Expand All @@ -159,6 +303,7 @@ int wh_Server_HandleCryptoRequest(whServerContext* server,
packet->rngRes.sz;
}
break;
#endif /* !WC_NO_RNG */
case WC_ALGO_TYPE_NONE:
default:
ret = NOT_COMPILED_IN;
Expand Down
Loading

0 comments on commit 42186b7

Please sign in to comment.