Skip to content

(initial) ML-DSA support #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 20, 2024
Merged
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
488 changes: 488 additions & 0 deletions src/wh_client_crypto.c

Large diffs are not rendered by default.

143 changes: 143 additions & 0 deletions src/wh_client_cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ static int _xferSha256BlockAndUpdateDigest(whClientContext* ctx,
wc_Sha256* sha256,
whPacket* packet,
uint32_t isLastBlock);
static int _handlePqcSigKeyGen(whClientContext* ctx, wc_CryptoInfo* info);
static int _handlePqcSign(whClientContext* ctx, wc_CryptoInfo* info);
static int _handlePqcVerify(whClientContext* ctx, wc_CryptoInfo* info);
static int _handlePqcSigCheckPrivKey(whClientContext* ctx, wc_CryptoInfo* info);

#ifdef WOLFHSM_CFG_DMA
static int _handleSha256Dma(wc_CryptoInfo* info, void* inCtx, whPacket* packet);
#endif /* WOLFHSM_CFG_DMA */
Expand Down Expand Up @@ -331,6 +336,25 @@ int wh_Client_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
} break;
#endif /* HAVE_CURVE25519 */

#if defined(HAVE_DILITHIUM) || defined(HAVE_FALCON)
case WC_PK_TYPE_PQC_SIG_KEYGEN:
ret = _handlePqcSigKeyGen(ctx, info);
break;

case WC_PK_TYPE_PQC_SIG_SIGN:
ret = _handlePqcSign(ctx, info);
break;

case WC_PK_TYPE_PQC_SIG_VERIFY:
ret = _handlePqcVerify(ctx, info);
break;

case WC_PK_TYPE_PQC_SIG_CHECK_PRIV_KEY:
ret = _handlePqcSigCheckPrivKey(ctx, info);
break;

#endif /* HAVE_DILITHIUM || HAVE_FALCON */

case WC_PK_TYPE_NONE:
default:
ret = CRYPTOCB_UNAVAILABLE;
Expand Down Expand Up @@ -727,6 +751,125 @@ static int _handleSha256Dma(wc_CryptoInfo* info, void* inCtx, whPacket* packet)
#endif /* ! NO_SHA256 */


#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)
static int _handlePqcSigKeyGen(whClientContext* ctx, wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

/* Extract info parameters */
WC_RNG* rng = info->pk.pqc_sig_kg.rng;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for client-side rng

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in #86

int size = info->pk.pqc_sig_kg.size;
void* key = info->pk.pqc_sig_kg.key;
int type = info->pk.pqc_sig_kg.type;

switch (type) {
#ifdef HAVE_DILITHIUM
case WC_PQC_SIG_TYPE_DILITHIUM: {
int level = ((MlDsaKey*)key)->level;
ret = wh_Client_MlDsaMakeExportKey(ctx, level, key, size, rng);
} break;
#endif /* HAVE_DILITHIUM */

/* Support for additional PQC algorithms should be added here */

default:
ret = CRYPTOCB_UNAVAILABLE;
break;
}

return ret;
}

static int _handlePqcSign(whClientContext* ctx, wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

/* Extract info parameters */
const byte* in = info->pk.pqc_sign.in;
word32 in_len = info->pk.pqc_sign.inlen;
byte* out = info->pk.pqc_sign.out;
word32* out_len = info->pk.pqc_sign.outlen;
WC_RNG* rng = info->pk.pqc_sign.rng;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No client-side rng needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in #86

void* key = info->pk.pqc_sign.key;
int type = info->pk.pqc_sign.type;

switch (type) {
#ifdef HAVE_DILITHIUM
case WC_PQC_SIG_TYPE_DILITHIUM:
ret = wh_Client_MlDsaSign(ctx, in, in_len, out, out_len, rng, key);
break;
#endif /* HAVE_DILITHIUM */

/* Support for additional PQC algorithms should be added here */

default:
ret = CRYPTOCB_UNAVAILABLE;
break;
}

return ret;
}

static int _handlePqcVerify(whClientContext* ctx, wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

/* Extract info parameters */
const byte* sig = info->pk.pqc_verify.sig;
word32 sig_len = info->pk.pqc_verify.siglen;
const byte* msg = info->pk.pqc_verify.msg;
word32 msg_len = info->pk.pqc_verify.msglen;
int* res = info->pk.pqc_verify.res;
void* key = info->pk.pqc_verify.key;
int type = info->pk.pqc_verify.type;

switch (type) {
#ifdef HAVE_DILITHIUM
case WC_PQC_SIG_TYPE_DILITHIUM:
ret = wh_Client_MlDsaVerify(ctx, sig, sig_len, msg, msg_len, res,
key);
break;
#endif /* HAVE_DILITHIUM */

/* Support for additional PQC algorithms should be added here */

default:
ret = CRYPTOCB_UNAVAILABLE;
break;
}

return ret;
}

static int _handlePqcSigCheckPrivKey(whClientContext* ctx, wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

/* Extract info parameters */
void* key = info->pk.pqc_sig_check.key;
const byte* pubKey = info->pk.pqc_sig_check.pubKey;
word32 pubKeySz = info->pk.pqc_sig_check.pubKeySz;
int type = info->pk.pqc_sig_check.type;

switch (type) {
#ifdef HAVE_DILITHIUM
case WC_PQC_SIG_TYPE_DILITHIUM:
ret = wh_Client_MlDsaCheckPrivKey(ctx, key, pubKey, pubKeySz);
break;
#endif /* HAVE_DILITHIUM */

/* Support for additional PQC algorithms should be added here */

default:
ret = CRYPTOCB_UNAVAILABLE;
break;
}

return ret;
}
#endif /* HAVE_FALCON || HAVE_DILITHIUM */


#ifdef WOLFHSM_CFG_DMA
int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx)
{
Expand Down
10 changes: 10 additions & 0 deletions src/wh_comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ int wh_CommClient_SendRequest(whCommClient* context, uint16_t magic,
return WH_ERROR_BADARGS;
}

/* Check if the data size is within allowed limits */
if (data_size > WOLFHSM_CFG_COMM_DATA_LEN) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did we miss this?? I assume the lower-level does a sanity check but we should have caught it here. Nice!

return WH_ERROR_BADARGS;
}

context->hdr->magic = magic;
context->hdr->kind = wh_Translate16(magic, kind);
context->hdr->seq = wh_Translate16(magic, context->seq + 1);
Expand Down Expand Up @@ -298,6 +303,11 @@ int wh_CommServer_SendResponse(whCommServer* context,
return WH_ERROR_BADARGS;
}

/* Check if the data size is within allowed limits */
if (data_size > WOLFHSM_CFG_COMM_DATA_LEN) {
return WH_ERROR_BADARGS;
}

context->hdr->magic = magic;
context->hdr->kind = wh_Translate16(magic, kind);
context->hdr->seq = wh_Translate16(magic, seq);
Expand Down
34 changes: 34 additions & 0 deletions src/wh_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "wolfssl/wolfcrypt/rsa.h"
#include "wolfssl/wolfcrypt/curve25519.h"
#include "wolfssl/wolfcrypt/ecc.h"
#include "wolfssl/wolfcrypt/dilithium.h"

#include "wolfhsm/wh_error.h"
#include "wolfhsm/wh_utils.h"
Expand Down Expand Up @@ -246,4 +247,37 @@ int wh_Crypto_Curve25519DeserializeKey(const uint8_t* derBuffer,
}
#endif /* HAVE_CURVE25519 */

#ifdef HAVE_DILITHIUM
int wh_Crypto_MlDsaSerializeKeyDer(MlDsaKey* key, uint16_t max_size,
uint8_t* buffer, uint16_t* out_size)
{
int ret = 0;

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

ret = wc_Dilithium_KeyToDer(key, buffer, max_size);

/* ASN.1 functions return the size of the DER encoded key on success */
if (ret > 0) {
*out_size = ret;
ret = WH_ERROR_OK;
}
return ret;
}

int wh_Crypto_MlDsaDeserializeKeyDer(const uint8_t* buffer, uint16_t size,
MlDsaKey* key)
{
word32 idx = 0;

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

return wc_Dilithium_PrivateKeyDecode(buffer, &idx, key, size);
}
#endif /* HAVE_DILITHIUM */

#endif /* !WOLFHSM_CFG_NO_CRYPTO */
Loading