diff --git a/src/internal.c b/src/internal.c index 528ad1dc7..2c3e9a52f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7807,13 +7807,13 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) #if defined(HAVE_PQC) #if defined(HAVE_FALCON) case DYNAMIC_TYPE_FALCON: - wc_falcon_init((falcon_key*)*pKey); + wc_falcon_init_ex((falcon_key*)*pKey, ssl->heap, ssl->devId); ret = 0; break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) case DYNAMIC_TYPE_DILITHIUM: - wc_dilithium_init((dilithium_key*)*pKey); + wc_dilithium_init_ex((dilithium_key*)*pKey, ssl->heap, ssl->devId); ret = 0; break; #endif /* HAVE_DILITHIUM */ @@ -27534,6 +27534,55 @@ int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType, } #endif } + else if (hsType == DYNAMIC_TYPE_DILITHIUM) { +#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + dilithium_key* dilithiumKey; + + dilithiumKey = (dilithium_key*)XMALLOC(sizeof(dilithium_key), heap, + DYNAMIC_TYPE_DILITHIUM); + if (dilithiumKey == NULL) { + return MEMORY_E; + } + + if (label) { + ret = wc_dilithium_init_label(dilithiumKey, (char*)data, + heap, devId); + } + else if (id) { + ret = wc_dilithium_init_id(dilithiumKey, data, length, heap, devId); + } + if (ret == 0) { + *pkey = (void*)dilithiumKey; + } + else { + XFREE(dilithiumKey, heap, DYNAMIC_TYPE_DILITHIUM); + } +#endif + } + else if (hsType == DYNAMIC_TYPE_FALCON) { +#if defined(HAVE_PQC) && defined(HAVE_FALCON) + falcon_key* falconKey; + + falconKey = (falcon_key*)XMALLOC(sizeof(falcon_key), heap, + DYNAMIC_TYPE_FALCON); + if (falconKey == NULL) { + return MEMORY_E; + } + + if (label) { + ret = wc_falcon_init_label(falconKey, (char*)data, heap, devId); + } + else if (id) { + ret = wc_falcon_init_id(falconKey, data, length, heap, devId); + } + if (ret == 0) { + *pkey = (void*)falconKey; + } + else { + XFREE(falconKey, heap, DYNAMIC_TYPE_FALCON); + } +#endif + } return ret; } @@ -27582,6 +27631,10 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ssl->hsType = DYNAMIC_TYPE_RSA; else if (ssl->buffers.keyType == ecc_dsa_sa_algo) ssl->hsType = DYNAMIC_TYPE_ECC; + else if (ssl->buffers.keyType == falcon_level5_sa_algo) + ssl->hsType = DYNAMIC_TYPE_FALCON; + else if (ssl->buffers.keyType == dilithium_level5_sa_algo) + ssl->hsType = DYNAMIC_TYPE_DILITHIUM; ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); if (ret != 0) { goto exit_dpk; @@ -27637,6 +27690,59 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } #else ret = NOT_COMPILED_IN; + #endif + } + else if (ssl->buffers.keyType == falcon_level5_sa_algo) { + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if (ssl->buffers.keyLabel) { + ret = wc_falcon_init_label((falcon_key*)ssl->hsKey, + (char*)ssl->buffers.key->buffer, + ssl->heap, ssl->buffers.keyDevId); + } + else if (ssl->buffers.keyId) { + ret = wc_falcon_init_id((falcon_key*)ssl->hsKey, + ssl->buffers.key->buffer, + ssl->buffers.key->length, ssl->heap, + ssl->buffers.keyDevId); + } + if (ret == 0) { + if (ssl->buffers.keySz < ssl->options.minFalconKeySz) { + WOLFSSL_MSG("Falcon key size too small"); + ERROR_OUT(FALCON_KEY_SIZE_E, exit_dpk); + } + + /* Return the maximum signature length. */ + *length = (word16)wc_falcon_sig_size((falcon_key*)ssl->hsKey); + } + #else + ret = NOT_COMPILED_IN; + #endif + } + else if (ssl->buffers.keyType == dilithium_level5_sa_algo) { + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if (ssl->buffers.keyLabel) { + ret = wc_dilithium_init_label((dilithium_key*)ssl->hsKey, + (char*)ssl->buffers.key->buffer, + ssl->heap, ssl->buffers.keyDevId); + } + else if (ssl->buffers.keyId) { + ret = wc_dilithium_init_id((dilithium_key*)ssl->hsKey, + ssl->buffers.key->buffer, + ssl->buffers.key->length, ssl->heap, + ssl->buffers.keyDevId); + } + if (ret == 0) { + if (ssl->buffers.keySz < ssl->options.minDilithiumKeySz) { + WOLFSSL_MSG("Dilithium key size too small"); + ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dpk); + } + + /* Return the maximum signature length. */ + *length = (word16)wc_dilithium_sig_size( + (dilithium_key*)ssl->hsKey); + } + #else + ret = NOT_COMPILED_IN; #endif } goto exit_dpk; diff --git a/src/ssl.c b/src/ssl.c index 950a0a4f8..61fca152c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7838,6 +7838,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #if defined(HAVE_FALCON) case FALCON_LEVEL1k: case FALCON_LEVEL5k: + #ifdef WOLF_PRIVATE_KEY_ID + keyType = falcon_level5_sa_algo; + #endif /* Falcon is fixed key size */ keySz = FALCON_MAX_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { @@ -7860,6 +7863,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, case DILITHIUM_LEVEL2k: case DILITHIUM_LEVEL3k: case DILITHIUM_LEVEL5k: + #ifdef WOLF_PRIVATE_KEY_ID + keyType = dilithium_level5_sa_algo; + #endif /* Dilithium is fixed key size */ keySz = DILITHIUM_MAX_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { @@ -9207,6 +9213,19 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, type = DYNAMIC_TYPE_ECC; } #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((der->keyOID == DILITHIUM_LEVEL2k) || + (der->keyOID == DILITHIUM_LEVEL3k) || + (der->keyOID == DILITHIUM_LEVEL5k)) { + type = DYNAMIC_TYPE_DILITHIUM; + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((der->keyOID == FALCON_LEVEL1k) || + (der->keyOID == FALCON_LEVEL5k)) { + type = DYNAMIC_TYPE_FALCON; + } + #endif ret = CreateDevPrivateKey(&pkey, buff, size, type, isKeyLabel, isKeyId, heap, devId); @@ -9228,6 +9247,23 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, der->publicKey, der->pubKeySize); } #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((der->keyOID == DILITHIUM_LEVEL2k) || + (der->keyOID == DILITHIUM_LEVEL3k) || + (der->keyOID == DILITHIUM_LEVEL5k)) { + ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, + WC_PQC_SIG_TYPE_DILITHIUM, + der->publicKey, der->pubKeySize); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((der->keyOID == FALCON_LEVEL1k) || + (der->keyOID == FALCON_LEVEL5k)) { + ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, + WC_PQC_SIG_TYPE_FALCON, + der->publicKey, der->pubKeySize); + } + #endif } #else /* devId was set, don't check, for now */ @@ -9247,6 +9283,19 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, if (der->keyOID == ECDSAk) { wc_ecc_free((ecc_key*)pkey); } + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((der->keyOID == DILITHIUM_LEVEL2k) || + (der->keyOID == DILITHIUM_LEVEL3k) || + (der->keyOID == DILITHIUM_LEVEL5k)) { + wc_dilithium_free((dilithium_key*)pkey); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((der->keyOID == FALCON_LEVEL1k) || + (der->keyOID == FALCON_LEVEL5k)) { + wc_falcon_free((falcon_key*)pkey); + } #endif XFREE(pkey, heap, type); } diff --git a/src/tls.c b/src/tls.c index 0b4cea8e5..04794ae94 100644 --- a/src/tls.c +++ b/src/tls.c @@ -8419,7 +8419,7 @@ static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) return BAD_FUNC_ARG; } - ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID); + ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); if (ret != 0) { wc_ecc_free(&eccpubkey); WOLFSSL_MSG("Error creating Kyber KEM"); @@ -8911,7 +8911,7 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl, return MEMORY_E; } - ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID); + ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); if (ret != 0) { wc_ecc_free(&eccpubkey); WOLFSSL_MSG("Error creating Kyber KEM"); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a326e9dc9..6c2dc443c 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16441,7 +16441,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx, if (sigCtx->key.falcon == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } - if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) { + if ((ret = wc_falcon_init_ex(sigCtx->key.falcon, + sigCtx->heap, sigCtx->devId)) < 0) { goto exit_cs; } if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1)) @@ -16467,7 +16468,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx, if (sigCtx->key.falcon == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } - if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) { + if ((ret = wc_falcon_init_ex(sigCtx->key.falcon, + sigCtx->heap, sigCtx->devId)) < 0) { goto exit_cs; } if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5)) @@ -16495,7 +16497,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx, if (sigCtx->key.dilithium == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } - if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) { + if ((ret = wc_dilithium_init_ex(sigCtx->key.dilithium, + sigCtx->heap, sigCtx->devId)) < 0) { goto exit_cs; } if ((ret = wc_dilithium_set_level( @@ -16521,7 +16524,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx, if (sigCtx->key.dilithium == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } - if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) { + if ((ret = wc_dilithium_init_ex(sigCtx->key.dilithium, + sigCtx->heap, sigCtx->devId)) < 0) { goto exit_cs; } if ((ret = wc_dilithium_set_level( @@ -16547,7 +16551,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx, if (sigCtx->key.dilithium == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } - if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) { + if ((ret = wc_dilithium_init_ex(sigCtx->key.dilithium, + sigCtx->heap, sigCtx->devId)) < 0) { goto exit_cs; } if ((ret = wc_dilithium_set_level( diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index ce49e4671..07b37f1ba 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -785,6 +785,291 @@ int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen, } #endif /* HAVE_ED25519 */ +#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER) +int wc_CryptoCb_PqcKemGetDevId(int type, void* key) +{ + int devId = INVALID_DEVID; + + if (key == NULL) + return devId; + + /* get devId */ +#if defined(WOLFSSL_HAVE_KYBER) + if (type == WC_PQC_KEM_TYPE_KYBER) { + devId = ((KyberKey*) key)->devId; + } +#endif + + return devId; +} + +int wc_CryptoCb_MakePqcKemKey(WC_RNG* rng, int type, int keySize, void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcKemGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_KEYGEN; + cryptoInfo.pk.pqc_kem_kg.rng = rng; + cryptoInfo.pk.pqc_kem_kg.size = keySize; + cryptoInfo.pk.pqc_kem_kg.key = key; + cryptoInfo.pk.pqc_kem_kg.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_PqcEncapsulate(byte* ciphertext, word32 ciphertextLen, + byte* sharedSecret, word32 sharedSecretLen, WC_RNG* rng, int type, + void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcKemGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_ENCAPS; + cryptoInfo.pk.pqc_encaps.ciphertext = ciphertext; + cryptoInfo.pk.pqc_encaps.ciphertextLen = ciphertextLen; + cryptoInfo.pk.pqc_encaps.sharedSecret = sharedSecret; + cryptoInfo.pk.pqc_encaps.sharedSecretLen = sharedSecretLen; + cryptoInfo.pk.pqc_encaps.rng = rng; + cryptoInfo.pk.pqc_encaps.key = key; + cryptoInfo.pk.pqc_encaps.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, word32 ciphertextLen, + byte* sharedSecret, word32 sharedSecretLen, int type, void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcKemGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_DECAPS; + cryptoInfo.pk.pqc_decaps.ciphertext = ciphertext; + cryptoInfo.pk.pqc_decaps.ciphertextLen = ciphertextLen; + cryptoInfo.pk.pqc_decaps.sharedSecret = sharedSecret; + cryptoInfo.pk.pqc_decaps.sharedSecretLen = sharedSecretLen; + cryptoInfo.pk.pqc_decaps.key = key; + cryptoInfo.pk.pqc_decaps.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* HAVE_PQC && WOLFSSL_HAVE_KYBER */ + +#if defined(HAVE_PQC) && (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)) +int wc_CryptoCb_PqcSigGetDevId(int type, void* key) +{ + int devId = INVALID_DEVID; + + if (key == NULL) + return devId; + + /* get devId */ +#if defined(HAVE_DILITHIUM) + if (type == WC_PQC_SIG_TYPE_DILITHIUM) { + devId = ((dilithium_key*) key)->devId; + } +#endif +#if defined(HAVE_FALCON) + if (type == WC_PQC_SIG_TYPE_FALCON) { + devId = ((falcon_key*) key)->devId; + } +#endif + + return devId; +} + +int wc_CryptoCb_MakePqcSignatureKey(WC_RNG* rng, int type, int keySize, + void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcSigGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_SIG_KEYGEN; + cryptoInfo.pk.pqc_sig_kg.rng = rng; + cryptoInfo.pk.pqc_sig_kg.size = keySize; + cryptoInfo.pk.pqc_sig_kg.key = key; + cryptoInfo.pk.pqc_sig_kg.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, word32 *outlen, + WC_RNG* rng, int type, void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcSigGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_SIG_SIGN; + cryptoInfo.pk.pqc_sign.in = in; + cryptoInfo.pk.pqc_sign.inlen = inlen; + cryptoInfo.pk.pqc_sign.out = out; + cryptoInfo.pk.pqc_sign.outlen = outlen; + cryptoInfo.pk.pqc_sign.rng = rng; + cryptoInfo.pk.pqc_sign.key = key; + cryptoInfo.pk.pqc_sign.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen, const byte* msg, + word32 msglen, int* res, int type, void* key) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcSigGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_SIG_VERIFY; + cryptoInfo.pk.pqc_verify.sig = sig; + cryptoInfo.pk.pqc_verify.siglen = siglen; + cryptoInfo.pk.pqc_verify.msg = msg; + cryptoInfo.pk.pqc_verify.msglen = msglen; + cryptoInfo.pk.pqc_verify.res = res; + cryptoInfo.pk.pqc_verify.key = key; + cryptoInfo.pk.pqc_verify.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_PqcSignatureCheckPrivKey(void* key, int type, + const byte* pubKey, word32 pubKeySz) +{ + int ret = CRYPTOCB_UNAVAILABLE; + int devId = INVALID_DEVID; + CryptoCb* dev; + + if (key == NULL) + return ret; + + /* get devId */ + devId = wc_CryptoCb_PqcSigGetDevId(type, key); + if (devId == INVALID_DEVID) + return ret; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_PQC_SIG_CHECK_PRIV_KEY; + cryptoInfo.pk.pqc_sig_check.key = key; + cryptoInfo.pk.pqc_sig_check.pubKey = pubKey; + cryptoInfo.pk.pqc_sig_check.pubKeySz = pubKeySz; + cryptoInfo.pk.pqc_sig_check.type = type; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* HAVE_PQC && (HAVE_FALCON || HAVE_DILITHIUM) */ + #ifndef NO_AES #ifdef HAVE_AESGCM int wc_CryptoCb_AesGcmEncrypt(Aes* aes, byte* out, diff --git a/wolfcrypt/src/dilithium.c b/wolfcrypt/src/dilithium.c index 9f8eda48a..f8968c561 100644 --- a/wolfcrypt/src/dilithium.c +++ b/wolfcrypt/src/dilithium.c @@ -62,15 +62,30 @@ int wc_dilithium_sign_msg(const byte* in, word32 inLen, dilithium_key* key, WC_RNG* rng) { int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - size_t localOutLen = 0; /* sanity check on arguments */ if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) { - ret = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcSign(in, inLen, out, outLen, rng, + WC_PQC_SIG_TYPE_DILITHIUM, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; + size_t localOutLen = 0; + if ((ret == 0) && (!key->prvKeySet)) { ret = BAD_FUNC_ARG; } @@ -90,6 +105,10 @@ int wc_dilithium_sign_msg(const byte* in, word32 inLen, } } + if ((ret == 0) && (oqssig == NULL)) { + ret = BUFFER_E; + } + /* check and set up out length */ if (ret == 0) { if ((key->level == 2) && (*outLen < DILITHIUM_LEVEL2_SIG_SIZE)) { @@ -148,13 +167,28 @@ int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key) { int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; if (key == NULL || sig == NULL || msg == NULL || res == NULL) { - ret = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, res, + WC_PQC_SIG_TYPE_DILITHIUM, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; + if ((ret == 0) && (!key->pubKeySet)) { ret = BAD_FUNC_ARG; } @@ -174,6 +208,10 @@ int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, } } + if ((ret == 0) && (oqssig == NULL)) { + ret = BUFFER_E; + } + if ((ret == 0) && (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p) == OQS_ERROR)) { @@ -200,15 +238,92 @@ int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, * returns BAD_FUNC_ARG when key is NULL */ int wc_dilithium_init(dilithium_key* key) +{ + return wc_dilithium_init_ex(key, NULL, INVALID_DEVID); +} + +/* Initialize the dilithium private/public key. + * + * key [in] Dilithium key. + * heap [in] Heap hint. + * devId[in] Device ID. + * returns BAD_FUNC_ARG when key is NULL + */ +int wc_dilithium_init_ex(dilithium_key* key, void* heap, int devId) { if (key == NULL) { return BAD_FUNC_ARG; } ForceZero(key, sizeof(*key)); + +#ifdef WOLF_CRYPTO_CB + key->devCtx = NULL; + key->devId = devId; +#endif +#ifdef WOLF_PRIVATE_KEY_ID + key->idLen = 0; + key->labelLen = 0; +#endif + + (void) heap; + (void) devId; + return 0; } +#ifdef WOLF_PRIVATE_KEY_ID +int wc_dilithium_init_id(dilithium_key* key, const unsigned char* id, int len, + void* heap, int devId) +{ + int ret = 0; + + if (key == NULL) + ret = BAD_FUNC_ARG; + if (ret == 0 && (len < 0 || len > DILITHIUM_MAX_ID_LEN)) + ret = BUFFER_E; + + if (ret == 0) + ret = wc_dilithium_init_ex(key, heap, devId); + if (ret == 0 && id != NULL && len != 0) { + XMEMCPY(key->id, id, (size_t)len); + key->idLen = len; + } + + /* Set the maxiumum level here */ + wc_dilithium_set_level(key, 5); + + return ret; +} + +int wc_dilithium_init_label(dilithium_key* key, const char* label, void* heap, + int devId) +{ + int ret = 0; + int labelLen = 0; + + if (key == NULL || label == NULL) + ret = BAD_FUNC_ARG; + if (ret == 0) { + labelLen = (int)XSTRLEN(label); + if (labelLen == 0 || labelLen > DILITHIUM_MAX_LABEL_LEN) + ret = BUFFER_E; + } + + if (ret == 0) + ret = wc_dilithium_init_ex(key, heap, devId); + if (ret == 0) { + XMEMCPY(key->label, label, (size_t)labelLen); + key->labelLen = labelLen; + } + + /* Set the maxiumum level here */ + wc_dilithium_set_level(key, 5); + + return ret; +} +#endif + /* Set the level of the dilithium private/public key. * * key [out] Dilithium key. @@ -422,15 +537,7 @@ int wc_dilithium_import_private_only(const byte* priv, word32 privSz, return ret; } - if (key->level == 2) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL2_KEY_SIZE); - } - else if (key->level == 3) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL3_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL5_KEY_SIZE); - } + XMEMCPY(key->k, newPriv, newPrivSz); key->prvKeySet = 1; return 0; @@ -494,15 +601,7 @@ int wc_dilithium_import_private_key(const byte* priv, word32 privSz, if (ret == 0) { /* make the private key (priv + pub) */ - if (key->level == 2) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL2_KEY_SIZE); - } - else if (key->level == 3) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL3_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, DILITHIUM_LEVEL5_KEY_SIZE); - } + XMEMCPY(key->k, newPriv, newPrivSz); key->prvKeySet = 1; } @@ -597,20 +696,20 @@ int wc_dilithium_export_private(dilithium_key* key, byte* out, word32* outLen) if (key->level == 2) { *outLen = DILITHIUM_LEVEL2_PRV_KEY_SIZE; - XMEMCPY(out, key->k, DILITHIUM_LEVEL2_PRV_KEY_SIZE); - XMEMCPY(out + DILITHIUM_LEVEL2_PRV_KEY_SIZE, key->p, + XMEMCPY(out, key->k, DILITHIUM_LEVEL2_KEY_SIZE); + XMEMCPY(out + DILITHIUM_LEVEL2_KEY_SIZE, key->p, DILITHIUM_LEVEL2_PUB_KEY_SIZE); } else if (key->level == 3) { *outLen = DILITHIUM_LEVEL3_PRV_KEY_SIZE; - XMEMCPY(out, key->k, DILITHIUM_LEVEL3_PRV_KEY_SIZE); - XMEMCPY(out + DILITHIUM_LEVEL3_PRV_KEY_SIZE, key->p, + XMEMCPY(out, key->k, DILITHIUM_LEVEL3_KEY_SIZE); + XMEMCPY(out + DILITHIUM_LEVEL3_KEY_SIZE, key->p, DILITHIUM_LEVEL3_PUB_KEY_SIZE); } else if (key->level == 5) { *outLen = DILITHIUM_LEVEL5_PRV_KEY_SIZE; - XMEMCPY(out, key->k, DILITHIUM_LEVEL5_PRV_KEY_SIZE); - XMEMCPY(out + DILITHIUM_LEVEL5_PRV_KEY_SIZE, key->p, + XMEMCPY(out, key->k, DILITHIUM_LEVEL5_KEY_SIZE); + XMEMCPY(out + DILITHIUM_LEVEL5_KEY_SIZE, key->p, DILITHIUM_LEVEL5_PUB_KEY_SIZE); } @@ -659,8 +758,29 @@ int wc_dilithium_check_key(dilithium_key* key) return BAD_FUNC_ARG; } - /* Assume everything is fine. */ - return 0; + int ret = 0; + + /* The public key is also decoded and stored within the private key buffer + * behind the private key. Hence, we can compare both stored public keys. */ + if (key->level == 2) { + ret = XMEMCMP(key->p, key->k + DILITHIUM_LEVEL2_KEY_SIZE, + DILITHIUM_LEVEL2_PUB_KEY_SIZE); + } + else if (key->level == 3) { + ret = XMEMCMP(key->p, key->k + DILITHIUM_LEVEL3_KEY_SIZE, + DILITHIUM_LEVEL3_PUB_KEY_SIZE); + } + else if (key->level == 5) { + ret = XMEMCMP(key->p, key->k + DILITHIUM_LEVEL5_KEY_SIZE, + DILITHIUM_LEVEL5_PUB_KEY_SIZE); + } + + if (ret != 0) { + ret = PUBLIC_KEY_E; + } + + return ret; + } /* Returns the size of a dilithium private key. @@ -767,7 +887,8 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx, dilithium_key* key, word32 inSz) { int ret = 0; - byte privKey[DILITHIUM_MAX_KEY_SIZE], pubKey[DILITHIUM_MAX_PUB_KEY_SIZE]; + byte privKey[DILITHIUM_MAX_PRV_KEY_SIZE]; + byte pubKey[DILITHIUM_MAX_PUB_KEY_SIZE]; word32 privKeyLen = (word32)sizeof(privKey); word32 pubKeyLen = (word32)sizeof(pubKey); int keytype = 0; diff --git a/wolfcrypt/src/ext_kyber.c b/wolfcrypt/src/ext_kyber.c index ea2ac83b1..0e694c097 100644 --- a/wolfcrypt/src/ext_kyber.c +++ b/wolfcrypt/src/ext_kyber.c @@ -101,10 +101,15 @@ int wc_KyberKey_Init(int type, KyberKey* key, void* heap, int devId) /* Keep type for parameters. */ key->type = type; + +#ifdef WOLF_CRYPTO_CB + key->devCtx = NULL; + key->devId = devId; +#endif } - (void)devId; (void)heap; + (void)devId; return ret; } @@ -312,13 +317,25 @@ int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng) OQS_KEM *kem = NULL; #endif - (void)rng; - /* Validate parameter. */ if (key == NULL) { return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_MakePqcKemKey(rng, WC_PQC_KEM_TYPE_KYBER, + key->type, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + #ifdef HAVE_LIBOQS if (ret == 0) { algName = OQS_ID2name(key->type); @@ -327,12 +344,6 @@ int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng) } } - if (ret == 0) { - algName = OQS_ID2name(key->type); - if (algName == NULL) { - ret = BAD_FUNC_ARG; - } - } if (ret == 0) { kem = OQS_KEM_new(algName); if (kem == NULL) { @@ -403,6 +414,9 @@ int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss, WC_RNG* rng) { int ret = 0; +#ifdef WOLF_CRYPTO_CB + word32 ctlen = 0; +#endif #ifdef HAVE_LIBOQS const char * algName = NULL; OQS_KEM *kem = NULL; @@ -415,6 +429,24 @@ int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss, ret = BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (ret == 0) { + ret = wc_KyberKey_CipherTextSize(key, &ctlen); + } + if ((ret == 0) + #ifndef WOLF_CRYPTO_CB_FIND + && (key->devId != INVALID_DEVID) + #endif + ) { + ret = wc_CryptoCb_PqcEncapsulate(ct, ctlen, ss, KYBER_SS_SZ, rng, + WC_PQC_KEM_TYPE_KYBER, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + #ifdef HAVE_LIBOQS if (ret == 0) { algName = OQS_ID2name(key->type); @@ -509,6 +541,21 @@ int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss, ret = BUFFER_E; } +#ifdef WOLF_CRYPTO_CB + if ((ret == 0) + #ifndef WOLF_CRYPTO_CB_FIND + && (key->devId != INVALID_DEVID) + #endif + ) { + ret = wc_CryptoCb_PqcDecapsulate(ct, ctlen, ss, KYBER_SS_SZ, + WC_PQC_KEM_TYPE_KYBER, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + #ifdef HAVE_LIBOQS if (ret == 0) { algName = OQS_ID2name(key->type); diff --git a/wolfcrypt/src/falcon.c b/wolfcrypt/src/falcon.c index 957e97c81..2645db639 100644 --- a/wolfcrypt/src/falcon.c +++ b/wolfcrypt/src/falcon.c @@ -62,15 +62,30 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen, falcon_key* key, WC_RNG* rng) { int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - size_t localOutLen = 0; /* sanity check on arguments */ if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) { - ret = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcSign(in, inLen, out, outLen, rng, + WC_PQC_SIG_TYPE_FALCON, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; + size_t localOutLen = 0; + if ((ret == 0) && (!key->prvKeySet)) { ret = BAD_FUNC_ARG; } @@ -88,6 +103,10 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen, } } + if ((ret == 0) && (oqssig == NULL)) { + ret = BUFFER_E; + } + /* check and set up out length */ if (ret == 0) { if ((key->level == 1) && (*outLen < FALCON_LEVEL1_SIG_SIZE)) { @@ -142,13 +161,28 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, falcon_key* key) { int ret = 0; -#ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; if (key == NULL || sig == NULL || msg == NULL || res == NULL) { - ret = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, res, + WC_PQC_SIG_TYPE_FALCON, key); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; + if ((ret == 0) && (!key->pubKeySet)) { ret = BAD_FUNC_ARG; } @@ -166,6 +200,10 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, } } + if ((ret == 0) && (oqssig == NULL)) { + ret = BUFFER_E; + } + if ((ret == 0) && (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p) == OQS_ERROR)) { @@ -192,15 +230,92 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, * returns BAD_FUNC_ARG when key is NULL */ int wc_falcon_init(falcon_key* key) +{ + return wc_falcon_init_ex(key, NULL, INVALID_DEVID); +} + +/* Initialize the falcon private/public key. + * + * key [in] Falcon key. + * heap [in] Heap hint. + * devId[in] Device ID. + * returns BAD_FUNC_ARG when key is NULL + */ +int wc_falcon_init_ex(falcon_key* key, void* heap, int devId) { if (key == NULL) { return BAD_FUNC_ARG; } ForceZero(key, sizeof(*key)); + +#ifdef WOLF_CRYPTO_CB + key->devCtx = NULL; + key->devId = devId; +#endif +#ifdef WOLF_PRIVATE_KEY_ID + key->idLen = 0; + key->labelLen = 0; +#endif + + (void) heap; + (void) devId; + return 0; } +#ifdef WOLF_PRIVATE_KEY_ID +int wc_falcon_init_id(falcon_key* key, const unsigned char* id, int len, + void* heap, int devId) +{ + int ret = 0; + + if (key == NULL) + ret = BAD_FUNC_ARG; + if (ret == 0 && (len < 0 || len > FALCON_MAX_ID_LEN)) + ret = BUFFER_E; + + if (ret == 0) + ret = wc_falcon_init_ex(key, heap, devId); + if (ret == 0 && id != NULL && len != 0) { + XMEMCPY(key->id, id, (size_t)len); + key->idLen = len; + } + + /* Set the maxiumum level here */ + wc_falcon_set_level(key, 5); + + return ret; +} + +int wc_falcon_init_label(falcon_key* key, const char* label, void* heap, + int devId) +{ + int ret = 0; + int labelLen = 0; + + if (key == NULL || label == NULL) + ret = BAD_FUNC_ARG; + if (ret == 0) { + labelLen = (int)XSTRLEN(label); + if (labelLen == 0 || labelLen > FALCON_MAX_LABEL_LEN) + ret = BUFFER_E; + } + + if (ret == 0) + ret = wc_falcon_init_ex(key, heap, devId); + if (ret == 0) { + XMEMCPY(key->label, label, (size_t)labelLen); + key->labelLen = labelLen; + } + + /* Set the maxiumum level here */ + wc_falcon_set_level(key, 5); + + return ret; +} +#endif + /* Set the level of the falcon private/public key. * * key [out] Falcon key. @@ -399,12 +514,7 @@ int wc_falcon_import_private_only(const byte* priv, word32 privSz, return ret; } - if (key->level == 1) { - XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE); - } + XMEMCPY(key->k, newPriv, newPrivSz); key->prvKeySet = 1; return 0; @@ -462,12 +572,7 @@ int wc_falcon_import_private_key(const byte* priv, word32 privSz, if (ret == 0) { /* make the private key (priv + pub) */ - if (key->level == 1) { - XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE); - } - else if (key->level == 5) { - XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE); - } + XMEMCPY(key->k, newPriv, newPrivSz); key->prvKeySet = 1; } @@ -550,14 +655,14 @@ int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen) if (key->level == 1) { *outLen = FALCON_LEVEL1_PRV_KEY_SIZE; - XMEMCPY(out, key->k, FALCON_LEVEL1_PRV_KEY_SIZE); - XMEMCPY(out + FALCON_LEVEL1_PRV_KEY_SIZE, key->p, + XMEMCPY(out, key->k, FALCON_LEVEL1_KEY_SIZE); + XMEMCPY(out + FALCON_LEVEL1_KEY_SIZE, key->p, FALCON_LEVEL1_PUB_KEY_SIZE); } else if (key->level == 5) { *outLen = FALCON_LEVEL5_PRV_KEY_SIZE; - XMEMCPY(out, key->k, FALCON_LEVEL5_PRV_KEY_SIZE); - XMEMCPY(out + FALCON_LEVEL5_PRV_KEY_SIZE, key->p, + XMEMCPY(out, key->k, FALCON_LEVEL5_KEY_SIZE); + XMEMCPY(out + FALCON_LEVEL5_KEY_SIZE, key->p, FALCON_LEVEL5_PUB_KEY_SIZE); } @@ -606,8 +711,24 @@ int wc_falcon_check_key(falcon_key* key) return BAD_FUNC_ARG; } - /* Assume everything is fine. */ - return 0; + int ret = 0; + + /* The public key is also decoded and stored within the private key buffer + * behind the private key. Hence, we can compare both stored public keys. */ + if (key->level == 1) { + ret = XMEMCMP(key->p, key->k + FALCON_LEVEL1_KEY_SIZE, + FALCON_LEVEL1_PUB_KEY_SIZE); + } + else if (key->level == 5) { + ret = XMEMCMP(key->p, key->k + FALCON_LEVEL5_KEY_SIZE, + FALCON_LEVEL5_PUB_KEY_SIZE); + } + + if (ret != 0) { + ret = PUBLIC_KEY_E; + } + + return ret; } /* Returns the size of a falcon private key. @@ -702,7 +823,7 @@ int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx, falcon_key* key, word32 inSz) { int ret = 0; - byte privKey[FALCON_MAX_KEY_SIZE], pubKey[FALCON_MAX_PUB_KEY_SIZE]; + byte privKey[FALCON_MAX_PRV_KEY_SIZE], pubKey[FALCON_MAX_PUB_KEY_SIZE]; word32 privKeyLen = (word32)sizeof(privKey); word32 pubKeyLen = (word32)sizeof(pubKey); int keytype = 0; diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 04548e386..8f6677750 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -71,6 +71,21 @@ #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #include #endif +#ifdef HAVE_PQC + #include +#ifdef WOLFSSL_WC_KYBER + #include +#elif defined(HAVE_LIBOQS) || defined(HAVE_PQM4) + #include +#endif +#endif +#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + #include +#endif +#if defined(HAVE_PQC) && defined(HAVE_FALCON) + #include +#endif + #ifdef WOLF_CRYPTO_CB_CMD /* CryptoCb Commands */ @@ -201,6 +216,64 @@ typedef struct wc_CryptoInfo { byte contextLen; } ed25519verify; #endif + #if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER) + struct { + WC_RNG* rng; + int size; + void* key; + int type; /* enum wc_PqcKemType */ + } pqc_kem_kg; + struct { + byte* ciphertext; + word32 ciphertextLen; + byte* sharedSecret; + word32 sharedSecretLen; + WC_RNG* rng; + void* key; + int type; /* enum wc_PqcKemType */ + } pqc_encaps; + struct { + const byte* ciphertext; + word32 ciphertextLen; + byte* sharedSecret; + word32 sharedSecretLen; + void* key; + int type; /* enum wc_PqcKemType */ + } pqc_decaps; + #endif + #if defined(HAVE_PQC) && \ + (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)) + struct { + WC_RNG* rng; + int size; + void* key; + int type; /* enum wc_PqcSignatureType */ + } pqc_sig_kg; + struct { + const byte* in; + word32 inlen; + byte* out; + word32* outlen; + WC_RNG* rng; + void* key; + int type; /* enum wc_PqcSignatureType */ + } pqc_sign; + struct { + const byte* sig; + word32 siglen; + const byte* msg; + word32 msglen; + int* res; + void* key; + int type; /* enum wc_PqcSignatureType */ + } pqc_verify; + struct { + void* key; + const byte* pubKey; + word32 pubKeySz; + int type; /* enum wc_PqcSignatureType */ + } pqc_sig_check; + #endif #if HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif @@ -452,6 +525,37 @@ WOLFSSL_LOCAL int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen, const byte* context, byte contextLen); #endif /* HAVE_ED25519 */ +#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER) +WOLFSSL_LOCAL int wc_CryptoCb_PqcKemGetDevId(int type, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_MakePqcKemKey(WC_RNG* rng, int type, + int keySize, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_PqcEncapsulate(byte* ciphertext, + word32 ciphertextLen, byte* sharedSecret, word32 sharedSecretLen, + WC_RNG* rng, int type, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, + word32 ciphertextLen, byte* sharedSecret, word32 sharedSecretLen, + int type, void* key); +#endif /* HAVE_PQC && WOLFSSL_HAVE_KYBER */ + +#if defined(HAVE_PQC) && (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)) +WOLFSSL_LOCAL int wc_CryptoCb_PqcSigGetDevId(int type, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_MakePqcSignatureKey(WC_RNG* rng, int type, + int keySize, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, + word32 *outlen, WC_RNG* rng, int type, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen, + const byte* msg, word32 msglen, int* res, int type, void* key); + +WOLFSSL_LOCAL int wc_CryptoCb_PqcSignatureCheckPrivKey(void* key, int type, + const byte* pubKey, word32 pubKeySz); +#endif /* HAVE_PQC && (HAVE_FALCON || HAVE_DILITHIUM) */ + #ifndef NO_AES #ifdef HAVE_AESGCM WOLFSSL_LOCAL int wc_CryptoCb_AesGcmEncrypt(Aes* aes, byte* out, diff --git a/wolfssl/wolfcrypt/dilithium.h b/wolfssl/wolfcrypt/dilithium.h index 2b5998ffd..5472d092e 100644 --- a/wolfssl/wolfcrypt/dilithium.h +++ b/wolfssl/wolfcrypt/dilithium.h @@ -31,6 +31,10 @@ #include +#ifdef WOLF_CRYPTO_CB + #include +#endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) #ifdef HAVE_LIBOQS @@ -61,17 +65,34 @@ #define DILITHIUM_LEVEL5_PRV_KEY_SIZE (DILITHIUM_LEVEL5_PUB_KEY_SIZE+DILITHIUM_LEVEL5_KEY_SIZE) #endif -#define DILITHIUM_MAX_KEY_SIZE DILITHIUM_LEVEL5_PRV_KEY_SIZE +#define DILITHIUM_MAX_KEY_SIZE DILITHIUM_LEVEL5_KEY_SIZE #define DILITHIUM_MAX_SIG_SIZE DILITHIUM_LEVEL5_SIG_SIZE #define DILITHIUM_MAX_PUB_KEY_SIZE DILITHIUM_LEVEL5_PUB_KEY_SIZE #define DILITHIUM_MAX_PRV_KEY_SIZE DILITHIUM_LEVEL5_PRV_KEY_SIZE +#ifdef WOLF_PRIVATE_KEY_ID +#define DILITHIUM_MAX_ID_LEN 32 +#define DILITHIUM_MAX_LABEL_LEN 32 +#endif + /* Structs */ struct dilithium_key { bool pubKeySet; bool prvKeySet; byte level; /* 2,3 or 5 */ + +#ifdef WOLF_CRYPTO_CB + void* devCtx; + int devId; +#endif +#ifdef WOLF_PRIVATE_KEY_ID + byte id[DILITHIUM_MAX_ID_LEN]; + int idLen; + char label[DILITHIUM_MAX_LABEL_LEN]; + int labelLen; +#endif + byte p[DILITHIUM_MAX_PUB_KEY_SIZE]; byte k[DILITHIUM_MAX_PRV_KEY_SIZE]; }; @@ -92,6 +113,19 @@ int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, WOLFSSL_API int wc_dilithium_init(dilithium_key* key); + +WOLFSSL_API +int wc_dilithium_init_ex(dilithium_key* key, void* heap, int devId); + +#ifdef WOLF_PRIVATE_KEY_ID +WOLFSSL_API +int wc_dilithium_init_id(dilithium_key* key, const unsigned char* id, int len, + void* heap, int devId); +WOLFSSL_API +int wc_dilithium_init_label(dilithium_key* key, const char* label, void* heap, + int devId); +#endif + WOLFSSL_API int wc_dilithium_set_level(dilithium_key* key, byte level); WOLFSSL_API diff --git a/wolfssl/wolfcrypt/ext_kyber.h b/wolfssl/wolfcrypt/ext_kyber.h index 53c175d77..0ea7108b1 100644 --- a/wolfssl/wolfcrypt/ext_kyber.h +++ b/wolfssl/wolfcrypt/ext_kyber.h @@ -22,6 +22,10 @@ #ifndef EXT_KYBER_H #define EXT_KYBER_H +#ifdef WOLF_CRYPTO_CB + #include +#endif + #ifdef WOLFSSL_HAVE_KYBER #include @@ -56,6 +60,12 @@ struct KyberKey { * Note we don't save the variant (SHAKE vs AES) as that is decided at * configuration time. */ int type; + +#ifdef WOLF_CRYPTO_CB + void* devCtx; + int devId; +#endif + byte priv[EXT_KYBER_MAX_PRIV_SZ]; byte pub[EXT_KYBER_MAX_PUB_SZ]; }; diff --git a/wolfssl/wolfcrypt/falcon.h b/wolfssl/wolfcrypt/falcon.h index c444a302b..9d4bff8be 100644 --- a/wolfssl/wolfcrypt/falcon.h +++ b/wolfssl/wolfcrypt/falcon.h @@ -31,6 +31,10 @@ #include +#ifdef WOLF_CRYPTO_CB + #include +#endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) #ifdef HAVE_LIBOQS @@ -56,17 +60,35 @@ #define FALCON_LEVEL5_PRV_KEY_SIZE (FALCON_LEVEL5_PUB_KEY_SIZE+FALCON_LEVEL5_KEY_SIZE) #endif -#define FALCON_MAX_KEY_SIZE FALCON_LEVEL5_PRV_KEY_SIZE +#define FALCON_MAX_KEY_SIZE FALCON_LEVEL5_KEY_SIZE #define FALCON_MAX_SIG_SIZE FALCON_LEVEL5_SIG_SIZE #define FALCON_MAX_PUB_KEY_SIZE FALCON_LEVEL5_PUB_KEY_SIZE #define FALCON_MAX_PRV_KEY_SIZE FALCON_LEVEL5_PRV_KEY_SIZE +#ifdef WOLF_PRIVATE_KEY_ID +#define FALCON_MAX_ID_LEN 32 +#define FALCON_MAX_LABEL_LEN 32 +#endif + + /* Structs */ struct falcon_key { bool pubKeySet; bool prvKeySet; byte level; + +#ifdef WOLF_CRYPTO_CB + void* devCtx; + int devId; +#endif +#ifdef WOLF_PRIVATE_KEY_ID + byte id[FALCON_MAX_ID_LEN]; + int idLen; + char label[FALCON_MAX_LABEL_LEN]; + int labelLen; +#endif + byte p[FALCON_MAX_PUB_KEY_SIZE]; byte k[FALCON_MAX_PRV_KEY_SIZE]; }; @@ -87,6 +109,19 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, WOLFSSL_API int wc_falcon_init(falcon_key* key); + +WOLFSSL_API +int wc_falcon_init_ex(falcon_key* key, void* heap, int devId); + +#ifdef WOLF_PRIVATE_KEY_ID +WOLFSSL_API +int wc_falcon_init_id(falcon_key* key, const unsigned char* id, int len, + void* heap, int devId); +WOLFSSL_API +int wc_falcon_init_label(falcon_key* key, const char* label, void* heap, + int devId); +#endif + WOLFSSL_API int wc_falcon_set_level(falcon_key* key, byte level); WOLFSSL_API diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 373f09b22..148b8a6d2 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -115,8 +115,7 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/Renesas/renesas_sync.h \ wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h \ wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h \ - wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h \ - wolfssl/wolfcrypt/port/liboqs/liboqs.h + wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h @@ -145,6 +144,10 @@ nobase_include_HEADERS+= wolfssl/wolfcrypt/port/aria/aria-crypt.h nobase_include_HEADERS+= wolfssl/wolfcrypt/port/aria/aria-cryptocb.h endif +if BUILD_LIBOQS +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/liboqs/liboqs.h +endif + if BUILD_ASYNCCRYPT nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h endif diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 53d022161..5db92f3d8 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1169,9 +1169,55 @@ typedef struct w64wrapper { WC_PK_TYPE_ED25519_KEYGEN = 15, WC_PK_TYPE_CURVE25519_KEYGEN = 16, WC_PK_TYPE_RSA_GET_SIZE = 17, - WC_PK_TYPE_MAX = WC_PK_TYPE_RSA_GET_SIZE + #define _WC_PK_TYPE_MAX WC_PK_TYPE_RSA_GET_SIZE + #if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER) + WC_PK_TYPE_PQC_KEM_KEYGEN = 18, + WC_PK_TYPE_PQC_KEM_ENCAPS = 19, + WC_PK_TYPE_PQC_KEM_DECAPS = 20, + #undef _WC_PK_TYPE_MAX + #define _WC_PK_TYPE_MAX WC_PK_TYPE_PQC_KEM_DECAPS + #endif + #if defined(HAVE_PQC) && (defined(HAVE_DILITHIUM) || defined(HAVE_FALCON)) + WC_PK_TYPE_PQC_SIG_KEYGEN = 21, + WC_PK_TYPE_PQC_SIG_SIGN = 22, + WC_PK_TYPE_PQC_SIG_VERIFY = 23, + WC_PK_TYPE_PQC_SIG_CHECK_PRIV_KEY = 24, + #undef _WC_PK_TYPE_MAX + #define _WC_PK_TYPE_MAX WC_PK_TYPE_PQC_SIG_CHECK_PRIV_KEY + #endif + WC_PK_TYPE_MAX = _WC_PK_TYPE_MAX }; + #if defined(HAVE_PQC) + /* Post quantum KEM algorithms */ + enum wc_PqcKemType { + WC_PQC_KEM_TYPE_NONE = 0, + #define _WC_PQC_KEM_TYPE_MAX WC_PQC_KEM_TYPE_NONE + #if defined(WOLFSSL_HAVE_KYBER) + WC_PQC_KEM_TYPE_KYBER = 1, + #undef _WC_PQC_KEM_TYPE_MAX + #define _WC_PQC_KEM_TYPE_MAX WC_PQC_KEM_TYPE_KYBER + #endif + WC_PQC_KEM_TYPE_MAX = _WC_PQC_KEM_TYPE_MAX + }; + + /* Post quantum signature algorithms */ + enum wc_PqcSignatureType { + WC_PQC_SIG_TYPE_NONE = 0, + #define _WC_PQC_SIG_TYPE_MAX WC_PQC_SIG_TYPE_NONE + #if defined(HAVE_DILITHIUM) + WC_PQC_SIG_TYPE_DILITHIUM = 1, + #undef _WC_PQC_SIG_TYPE_MAX + #define _WC_PQC_SIG_TYPE_MAX WC_PQC_SIG_TYPE_DILITHIUM + #endif + #if defined(HAVE_FALCON) + WC_PQC_SIG_TYPE_FALCON = 2, + #undef _WC_PQC_SIG_TYPE_MAX + #define _WC_PQC_SIG_TYPE_MAX WC_PQC_SIG_TYPE_FALCON + #endif + WC_PQC_SIG_TYPE_MAX = _WC_PQC_SIG_TYPE_MAX + }; + #endif /* settings detection for compile vs runtime math incompatibilities */ enum {