Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
969 changes: 969 additions & 0 deletions src/wh_client_crypto.c

Large diffs are not rendered by default.

81 changes: 73 additions & 8 deletions src/wh_client_cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@
#include "wolfhsm/wh_message_crypto.h"


#if defined(WOLFSSL_HAVE_MLKEM)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_HAVE_FRODOKEM)
static int _handlePqcKemKeyGen(whClientContext* ctx, wc_CryptoInfo* info,
int useDma);
static int _handlePqcEncaps(whClientContext* ctx, wc_CryptoInfo* info,
int useDma);
static int _handlePqcDecaps(whClientContext* ctx, wc_CryptoInfo* info,
int useDma);
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_HAVE_MLKEM || WOLFSSL_HAVE_FRODOKEM */
#if defined(WOLFSSL_HAVE_LMS) || defined(WOLFSSL_HAVE_XMSS)
static int _handlePqcStatefulSigKeyGen(whClientContext* ctx,
wc_CryptoInfo* info, int useDma);
Expand Down Expand Up @@ -531,7 +531,7 @@ int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* inCtx)
} break;
#endif /* HAVE_ED25519 */

#if defined(WOLFSSL_HAVE_MLKEM)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_HAVE_FRODOKEM)
case WC_PK_TYPE_PQC_KEM_KEYGEN:
ret = _handlePqcKemKeyGen(ctx, info, 0);
break;
Expand All @@ -544,7 +544,7 @@ int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* inCtx)
ret = _handlePqcDecaps(ctx, info, 0);
break;

#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_HAVE_MLKEM || WOLFSSL_HAVE_FRODOKEM */
#if defined(WOLFSSL_HAVE_LMS) || defined(WOLFSSL_HAVE_XMSS)
case WC_PK_TYPE_PQC_STATEFUL_SIG_KEYGEN:
ret = _handlePqcStatefulSigKeyGen(ctx, info, 0);
Expand Down Expand Up @@ -789,7 +789,7 @@ int wh_Client_CryptoCbStd(int devId, wc_CryptoInfo* info, void* inCtx)
return ret;
}

#if defined(WOLFSSL_HAVE_MLKEM)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_HAVE_FRODOKEM)
static int _handlePqcKemKeyGen(whClientContext* ctx, wc_CryptoInfo* info,
int useDma)
{
Expand All @@ -810,6 +810,7 @@ static int _handlePqcKemKeyGen(whClientContext* ctx, wc_CryptoInfo* info,
(void)size;

switch (type) {
#ifdef WOLFSSL_HAVE_MLKEM
case WC_PQC_KEM_TYPE_KYBER: {
int level = ((MlKemKey*)key)->type;
#ifdef WOLFHSM_CFG_DMA
Expand All @@ -822,6 +823,22 @@ static int _handlePqcKemKeyGen(whClientContext* ctx, wc_CryptoInfo* info,
ret = wh_Client_MlKemMakeExportKey(ctx, level, key);
}
} break;
#endif /* WOLFSSL_HAVE_MLKEM */

#ifdef WOLFSSL_HAVE_FRODOKEM
case WC_PQC_KEM_TYPE_FRODOKEM: {
int frodoType = ((FrodoKemKey*)key)->type;
#ifdef WOLFHSM_CFG_DMA
if (useDma) {
ret = wh_Client_FrodoKemMakeExportKeyDma(ctx, frodoType, key);
}
else
#endif /* WOLFHSM_CFG_DMA */
{
ret = wh_Client_FrodoKemMakeExportKey(ctx, frodoType, key);
}
} break;
#endif /* WOLFSSL_HAVE_FRODOKEM */

default:
ret = CRYPTOCB_UNAVAILABLE;
Expand Down Expand Up @@ -859,6 +876,7 @@ static int _handlePqcEncaps(whClientContext* ctx, wc_CryptoInfo* info,
#endif

switch (type) {
#ifdef WOLFSSL_HAVE_MLKEM
case WC_PQC_KEM_TYPE_KYBER:
#ifdef WOLFHSM_CFG_DMA
if (useDma) {
Expand All @@ -878,6 +896,30 @@ static int _handlePqcEncaps(whClientContext* ctx, wc_CryptoInfo* info,
info->pk.pqc_encaps.sharedSecretLen = sharedSecLen;
}
break;
#endif /* WOLFSSL_HAVE_MLKEM */

#ifdef WOLFSSL_HAVE_FRODOKEM
case WC_PQC_KEM_TYPE_FRODOKEM:
#ifdef WOLFHSM_CFG_DMA
if (useDma) {
ret = wh_Client_FrodoKemEncapsulateDma(
ctx, key, ciphertext, &ciphertextLen, sharedSecret,
&sharedSecLen);
}
else
#endif /* WOLFHSM_CFG_DMA */
{
ret = wh_Client_FrodoKemEncapsulate(ctx, key, ciphertext,
&ciphertextLen,
sharedSecret,
&sharedSecLen);
}
if (ret == WH_ERROR_OK) {
info->pk.pqc_encaps.ciphertextLen = ciphertextLen;
info->pk.pqc_encaps.sharedSecretLen = sharedSecLen;
}
break;
#endif /* WOLFSSL_HAVE_FRODOKEM */

default:
ret = CRYPTOCB_UNAVAILABLE;
Expand Down Expand Up @@ -915,6 +957,7 @@ static int _handlePqcDecaps(whClientContext* ctx, wc_CryptoInfo* info,
#endif

switch (type) {
#ifdef WOLFSSL_HAVE_MLKEM
case WC_PQC_KEM_TYPE_KYBER:
#ifdef WOLFHSM_CFG_DMA
if (useDma) {
Expand All @@ -933,6 +976,28 @@ static int _handlePqcDecaps(whClientContext* ctx, wc_CryptoInfo* info,
info->pk.pqc_decaps.sharedSecretLen = sharedSecLen;
}
break;
#endif /* WOLFSSL_HAVE_MLKEM */

#ifdef WOLFSSL_HAVE_FRODOKEM
case WC_PQC_KEM_TYPE_FRODOKEM:
#ifdef WOLFHSM_CFG_DMA
if (useDma) {
ret = wh_Client_FrodoKemDecapsulateDma(
ctx, key, ciphertext, ciphertextLen, sharedSecret,
&sharedSecLen);
}
else
#endif /* WOLFHSM_CFG_DMA */
{
ret = wh_Client_FrodoKemDecapsulate(ctx, key, ciphertext,
ciphertextLen, sharedSecret,
&sharedSecLen);
}
if (ret == WH_ERROR_OK) {
info->pk.pqc_decaps.sharedSecretLen = sharedSecLen;
}
break;
#endif /* WOLFSSL_HAVE_FRODOKEM */

default:
ret = CRYPTOCB_UNAVAILABLE;
Expand All @@ -948,7 +1013,7 @@ static int _handlePqcDecaps(whClientContext* ctx, wc_CryptoInfo* info,

return ret;
}
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_HAVE_MLKEM || WOLFSSL_HAVE_FRODOKEM */

#if defined(WOLFSSL_HAVE_LMS) || defined(WOLFSSL_HAVE_XMSS)
static int _handlePqcStatefulSigKeyGen(whClientContext* ctx,
Expand Down Expand Up @@ -1538,7 +1603,7 @@ int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx)

case WC_ALGO_TYPE_PK: {
switch (info->pk.type) {
#if defined(WOLFSSL_HAVE_MLKEM)
#if defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_HAVE_FRODOKEM)
case WC_PK_TYPE_PQC_KEM_KEYGEN:
ret = _handlePqcKemKeyGen(ctx, info, 1);
break;
Expand All @@ -1548,7 +1613,7 @@ int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx)
case WC_PK_TYPE_PQC_KEM_DECAPS:
ret = _handlePqcDecaps(ctx, info, 1);
break;
#endif /* WOLFSSL_HAVE_MLKEM */
#endif /* WOLFSSL_HAVE_MLKEM || WOLFSSL_HAVE_FRODOKEM */
#if defined(WOLFSSL_HAVE_LMS) || defined(WOLFSSL_HAVE_XMSS)
case WC_PK_TYPE_PQC_STATEFUL_SIG_KEYGEN:
ret = _handlePqcStatefulSigKeyGen(ctx, info, 1);
Expand Down
111 changes: 111 additions & 0 deletions src/wh_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,117 @@ int wh_Crypto_MlKemDeserializeKey(const uint8_t* buffer, uint16_t size,
}
#endif /* WOLFSSL_HAVE_MLKEM */

#ifdef WOLFSSL_HAVE_FRODOKEM
int wh_Crypto_FrodoKemSerializeKey(FrodoKemKey* key, uint16_t max_size,
uint8_t* buffer, uint16_t* out_size)
{
int ret = WH_ERROR_OK;
word32 keySize = 0;

if ((key == NULL) || (buffer == NULL) || (out_size == NULL)) {
return WH_ERROR_BADARGS;
}

/* Try the private key first. The size query succeeds whether or not a
* private key is present, so the encode return is what distinguishes a
* public-only key. */
ret = wc_FrodoKemKey_PrivateKeySize(key, &keySize);
if (ret == WH_ERROR_OK) {
if (keySize > max_size) {
return WH_ERROR_BADARGS;
}
ret = wc_FrodoKemKey_EncodePrivateKey(key, buffer, keySize);
}
if (ret != WH_ERROR_OK) {
/* Private key encoding failed - try public key only */
ret = wc_FrodoKemKey_PublicKeySize(key, &keySize);
if (ret == WH_ERROR_OK) {
if (keySize > max_size) {
return WH_ERROR_BADARGS;
}
ret = wc_FrodoKemKey_EncodePublicKey(key, buffer, keySize);
}
}

if (ret == WH_ERROR_OK) {
*out_size = (uint16_t)keySize;
}
else {
/* Clear buffer to avoid leaking partial key material on error */
wc_ForceZero(buffer, keySize);
}

return ret;
}

int wh_Crypto_FrodoKemDeserializeKey(const uint8_t* buffer, uint16_t size,
FrodoKemKey* key)
{
static const int bases[] = {
WC_FRODOKEM_640,
WC_FRODOKEM_976,
WC_FRODOKEM_1344,
};
int ret;
int origType;
int origDevId;
void* origHeap;
int modifiers;
word32 i;

if ((buffer == NULL) || (key == NULL) || (size == 0)) {
return WH_ERROR_BADARGS;
}

origType = key->type;
origDevId = key->devId;
origHeap = key->heap;

/* The AES and ephemeral modifiers do not change any encoded length, so
* they cannot be recovered from the buffer. Keep whatever the caller
* configured and only probe the base parameter set. */
modifiers = origType & ~FRODOKEM_BASE_MASK;

/* First, try decoding with the type already set in the key */
ret = wc_FrodoKemKey_DecodePrivateKey(key, buffer, size);
if (ret == WH_ERROR_OK) {
return ret;
}
ret = wc_FrodoKemKey_DecodePublicKey(key, buffer, size);
if (ret == WH_ERROR_OK) {
return ret;
}

/* Current type didn't work, try the other base parameter sets in place */
for (i = 0; i < XELEM_CNT(bases); i++) {
int type = bases[i] | modifiers;

if (type == origType) {
continue;
}
wc_FrodoKemKey_Free(key);
ret = wc_FrodoKemKey_Init(key, type, origHeap, origDevId);
if (ret != WH_ERROR_OK) {
continue;
}
ret = wc_FrodoKemKey_DecodePrivateKey(key, buffer, size);
if (ret == WH_ERROR_OK) {
return ret;
}
ret = wc_FrodoKemKey_DecodePublicKey(key, buffer, size);
if (ret == WH_ERROR_OK) {
return ret;
}
}

/* None of the parameter sets worked. Restore the original type; the error
* is reported in ret, so the Init return is not useful here. */
wc_FrodoKemKey_Free(key);
(void)wc_FrodoKemKey_Init(key, origType, origHeap, origDevId);
return ret;
}
#endif /* WOLFSSL_HAVE_FRODOKEM */

#if defined(WOLFSSL_HAVE_LMS) || defined(WOLFSSL_HAVE_XMSS)
/* Stateful hash-based signature key serialization helpers (LMS / XMSS).
*
Expand Down
Loading
Loading