Skip to content

Commit 4d259da

Browse files
committed
PQC: CryptoCb support for KEM algorithm Kyber
Add support for crypto callback and device id for all three Kyber PQC KEM function calls. Signed-off-by: Tobias Frauenschläger <t.frauenschlaeger@me.com>
1 parent 8e6d151 commit 4d259da

7 files changed

Lines changed: 266 additions & 17 deletions

File tree

src/internal.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27462,7 +27462,8 @@ int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType,
2746227462
}
2746327463

2746427464
if (label) {
27465-
ret = wc_dilithium_init_label(dilithiumKey, (char*)data, heap, devId);
27465+
ret = wc_dilithium_init_label(dilithiumKey, (char*)data,
27466+
heap, devId);
2746627467
}
2746727468
else if (id) {
2746827469
ret = wc_dilithium_init_id(dilithiumKey, data, length, heap, devId);
@@ -27654,7 +27655,8 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
2765427655
}
2765527656

2765627657
/* Return the maximum signature length. */
27657-
*length = (word16)wc_dilithium_sig_size((dilithium_key*)ssl->hsKey);
27658+
*length = (word16)wc_dilithium_sig_size(
27659+
(dilithium_key*)ssl->hsKey);
2765827660
}
2765927661
#else
2766027662
ret = NOT_COMPILED_IN;

src/tls.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8415,7 +8415,7 @@ static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
84158415
return BAD_FUNC_ARG;
84168416
}
84178417

8418-
ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
8418+
ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
84198419
if (ret != 0) {
84208420
wc_ecc_free(&eccpubkey);
84218421
WOLFSSL_MSG("Error creating Kyber KEM");
@@ -8907,7 +8907,7 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
89078907
return MEMORY_E;
89088908
}
89098909

8910-
ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
8910+
ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
89118911
if (ret != 0) {
89128912
wc_ecc_free(&eccpubkey);
89138913
WOLFSSL_MSG("Error creating Kyber KEM");

wolfcrypt/src/cryptocb.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,129 @@ int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen,
785785
}
786786
#endif /* HAVE_ED25519 */
787787

788+
#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER)
789+
int wc_CryptoCb_PqcKemGetDevId(int type, void* key)
790+
{
791+
int devId = INVALID_DEVID;
792+
793+
if (key == NULL)
794+
return devId;
795+
796+
/* get devId */
797+
#if defined(WOLFSSL_HAVE_KYBER)
798+
if (type == WC_PQC_KEM_TYPE_KYBER) {
799+
devId = ((KyberKey*) key)->devId;
800+
}
801+
#endif
802+
803+
return devId;
804+
}
805+
806+
int wc_CryptoCb_MakePqcKemKey(WC_RNG* rng, int type, int keySize, void* key)
807+
{
808+
int ret = CRYPTOCB_UNAVAILABLE;
809+
int devId = INVALID_DEVID;
810+
CryptoCb* dev;
811+
812+
if (key == NULL)
813+
return ret;
814+
815+
/* get devId */
816+
devId = wc_CryptoCb_PqcKemGetDevId(type, key);
817+
if (devId == INVALID_DEVID)
818+
return ret;
819+
820+
/* locate registered callback */
821+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK);
822+
if (dev && dev->cb) {
823+
wc_CryptoInfo cryptoInfo;
824+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
825+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
826+
cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_KEYGEN;
827+
cryptoInfo.pk.pqc_kem_kg.rng = rng;
828+
cryptoInfo.pk.pqc_kem_kg.size = keySize;
829+
cryptoInfo.pk.pqc_kem_kg.key = key;
830+
cryptoInfo.pk.pqc_kem_kg.type = type;
831+
832+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
833+
}
834+
835+
return wc_CryptoCb_TranslateErrorCode(ret);
836+
}
837+
838+
int wc_CryptoCb_PqcEncapsulate(byte* ciphertext, word32 ciphertextLen,
839+
byte* sharedSecret, word32 sharedSecretLen, WC_RNG* rng, int type,
840+
void* key)
841+
{
842+
int ret = CRYPTOCB_UNAVAILABLE;
843+
int devId = INVALID_DEVID;
844+
CryptoCb* dev;
845+
846+
if (key == NULL)
847+
return ret;
848+
849+
/* get devId */
850+
devId = wc_CryptoCb_PqcKemGetDevId(type, key);
851+
if (devId == INVALID_DEVID)
852+
return ret;
853+
854+
/* locate registered callback */
855+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK);
856+
if (dev && dev->cb) {
857+
wc_CryptoInfo cryptoInfo;
858+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
859+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
860+
cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_ENCAPS;
861+
cryptoInfo.pk.pqc_encaps.ciphertext = ciphertext;
862+
cryptoInfo.pk.pqc_encaps.ciphertextLen = ciphertextLen;
863+
cryptoInfo.pk.pqc_encaps.sharedSecret = sharedSecret;
864+
cryptoInfo.pk.pqc_encaps.sharedSecretLen = sharedSecretLen;
865+
cryptoInfo.pk.pqc_encaps.rng = rng;
866+
cryptoInfo.pk.pqc_encaps.key = key;
867+
cryptoInfo.pk.pqc_encaps.type = type;
868+
869+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
870+
}
871+
872+
return wc_CryptoCb_TranslateErrorCode(ret);
873+
}
874+
875+
int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, word32 ciphertextLen,
876+
byte* sharedSecret, word32 sharedSecretLen, int type, void* key)
877+
{
878+
int ret = CRYPTOCB_UNAVAILABLE;
879+
int devId = INVALID_DEVID;
880+
CryptoCb* dev;
881+
882+
if (key == NULL)
883+
return ret;
884+
885+
/* get devId */
886+
devId = wc_CryptoCb_PqcKemGetDevId(type, key);
887+
if (devId == INVALID_DEVID)
888+
return ret;
889+
890+
/* locate registered callback */
891+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK);
892+
if (dev && dev->cb) {
893+
wc_CryptoInfo cryptoInfo;
894+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
895+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
896+
cryptoInfo.pk.type = WC_PK_TYPE_PQC_KEM_DECAPS;
897+
cryptoInfo.pk.pqc_decaps.ciphertext = ciphertext;
898+
cryptoInfo.pk.pqc_decaps.ciphertextLen = ciphertextLen;
899+
cryptoInfo.pk.pqc_decaps.sharedSecret = sharedSecret;
900+
cryptoInfo.pk.pqc_decaps.sharedSecretLen = sharedSecretLen;
901+
cryptoInfo.pk.pqc_decaps.key = key;
902+
cryptoInfo.pk.pqc_decaps.type = type;
903+
904+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
905+
}
906+
907+
return wc_CryptoCb_TranslateErrorCode(ret);
908+
}
909+
#endif /* HAVE_PQC && WOLFSSL_HAVE_KYBER */
910+
788911
#if defined(HAVE_PQC) && (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM))
789912
int wc_CryptoCb_PqcSigGetDevId(int type, void* key)
790913
{

wolfcrypt/src/ext_kyber.c

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,15 @@ int wc_KyberKey_Init(int type, KyberKey* key, void* heap, int devId)
101101

102102
/* Keep type for parameters. */
103103
key->type = type;
104+
105+
#ifdef WOLF_CRYPTO_CB
106+
key->devCtx = NULL;
107+
key->devId = devId;
108+
#endif
104109
}
105110

106-
(void)devId;
107111
(void)heap;
112+
(void)devId;
108113

109114
return ret;
110115
}
@@ -312,27 +317,33 @@ int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng)
312317
OQS_KEM *kem = NULL;
313318
#endif
314319

315-
(void)rng;
316-
317320
/* Validate parameter. */
318321
if (key == NULL) {
319322
return BAD_FUNC_ARG;
320323
}
321324

322-
#ifdef HAVE_LIBOQS
323-
if (ret == 0) {
324-
algName = OQS_ID2name(key->type);
325-
if (algName == NULL) {
326-
ret = BAD_FUNC_ARG;
327-
}
325+
#ifdef WOLF_CRYPTO_CB
326+
#ifndef WOLF_CRYPTO_CB_FIND
327+
if (key->devId != INVALID_DEVID)
328+
#endif
329+
{
330+
ret = wc_CryptoCb_MakePqcKemKey(rng, WC_PQC_KEM_TYPE_KYBER,
331+
key->type, key);
332+
if (ret != CRYPTOCB_UNAVAILABLE)
333+
return ret;
334+
/* fall-through when unavailable */
335+
ret = 0;
328336
}
337+
#endif
329338

339+
#ifdef HAVE_LIBOQS
330340
if (ret == 0) {
331341
algName = OQS_ID2name(key->type);
332342
if (algName == NULL) {
333343
ret = BAD_FUNC_ARG;
334344
}
335345
}
346+
336347
if (ret == 0) {
337348
kem = OQS_KEM_new(algName);
338349
if (kem == NULL) {
@@ -403,6 +414,9 @@ int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss,
403414
WC_RNG* rng)
404415
{
405416
int ret = 0;
417+
#ifdef WOLF_CRYPTO_CB
418+
word32 ctlen = 0;
419+
#endif
406420
#ifdef HAVE_LIBOQS
407421
const char * algName = NULL;
408422
OQS_KEM *kem = NULL;
@@ -415,6 +429,24 @@ int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss,
415429
ret = BAD_FUNC_ARG;
416430
}
417431

432+
#ifdef WOLF_CRYPTO_CB
433+
if (ret == 0) {
434+
ret = wc_KyberKey_CipherTextSize(key, &ctlen);
435+
}
436+
if ((ret == 0)
437+
#ifndef WOLF_CRYPTO_CB_FIND
438+
&& (key->devId != INVALID_DEVID)
439+
#endif
440+
) {
441+
ret = wc_CryptoCb_PqcEncapsulate(ct, ctlen, ss, KYBER_SS_SZ, rng,
442+
WC_PQC_KEM_TYPE_KYBER, key);
443+
if (ret != CRYPTOCB_UNAVAILABLE)
444+
return ret;
445+
/* fall-through when unavailable */
446+
ret = 0;
447+
}
448+
#endif
449+
418450
#ifdef HAVE_LIBOQS
419451
if (ret == 0) {
420452
algName = OQS_ID2name(key->type);
@@ -509,6 +541,21 @@ int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss,
509541
ret = BUFFER_E;
510542
}
511543

544+
#ifdef WOLF_CRYPTO_CB
545+
if ((ret == 0)
546+
#ifndef WOLF_CRYPTO_CB_FIND
547+
&& (key->devId != INVALID_DEVID)
548+
#endif
549+
) {
550+
ret = wc_CryptoCb_PqcDecapsulate(ct, ctlen, ss, KYBER_SS_SZ,
551+
WC_PQC_KEM_TYPE_KYBER, key);
552+
if (ret != CRYPTOCB_UNAVAILABLE)
553+
return ret;
554+
/* fall-through when unavailable */
555+
ret = 0;
556+
}
557+
#endif
558+
512559
#ifdef HAVE_LIBOQS
513560
if (ret == 0) {
514561
algName = OQS_ID2name(key->type);

wolfssl/wolfcrypt/cryptocb.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@
7171
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
7272
#include <wolfssl/wolfcrypt/sha512.h>
7373
#endif
74+
#ifdef HAVE_PQC
75+
#include <wolfssl/wolfcrypt/kyber.h>
76+
#ifdef WOLFSSL_WC_KYBER
77+
#include <wolfssl/wolfcrypt/wc_kyber.h>
78+
#elif defined(HAVE_LIBOQS) || defined(HAVE_PQM4)
79+
#include <wolfssl/wolfcrypt/ext_kyber.h>
80+
#endif
81+
#endif
7482
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
7583
#include <wolfssl/wolfcrypt/dilithium.h>
7684
#endif
@@ -208,6 +216,31 @@ typedef struct wc_CryptoInfo {
208216
byte contextLen;
209217
} ed25519verify;
210218
#endif
219+
#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER)
220+
struct {
221+
WC_RNG* rng;
222+
int size;
223+
void* key;
224+
int type; /* enum wc_PqcKemType */
225+
} pqc_kem_kg;
226+
struct {
227+
byte* ciphertext;
228+
word32 ciphertextLen;
229+
byte* sharedSecret;
230+
word32 sharedSecretLen;
231+
WC_RNG* rng;
232+
void* key;
233+
int type; /* enum wc_PqcKemType */
234+
} pqc_encaps;
235+
struct {
236+
const byte* ciphertext;
237+
word32 ciphertextLen;
238+
byte* sharedSecret;
239+
word32 sharedSecretLen;
240+
void* key;
241+
int type; /* enum wc_PqcKemType */
242+
} pqc_decaps;
243+
#endif
211244
#if defined(HAVE_PQC) && \
212245
(defined(HAVE_FALCON) || defined(HAVE_DILITHIUM))
213246
struct {
@@ -492,6 +525,21 @@ WOLFSSL_LOCAL int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen,
492525
const byte* context, byte contextLen);
493526
#endif /* HAVE_ED25519 */
494527

528+
#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_KYBER)
529+
WOLFSSL_LOCAL int wc_CryptoCb_PqcKemGetDevId(int type, void* key);
530+
531+
WOLFSSL_LOCAL int wc_CryptoCb_MakePqcKemKey(WC_RNG* rng, int type,
532+
int keySize, void* key);
533+
534+
WOLFSSL_LOCAL int wc_CryptoCb_PqcEncapsulate(byte* ciphertext,
535+
word32 ciphertextLen, byte* sharedSecret, word32 sharedSecretLen,
536+
WC_RNG* rng, int type, void* key);
537+
538+
WOLFSSL_LOCAL int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext,
539+
word32 ciphertextLen, byte* sharedSecret, word32 sharedSecretLen,
540+
int type, void* key);
541+
#endif /* HAVE_PQC && WOLFSSL_HAVE_KYBER */
542+
495543
#if defined(HAVE_PQC) && (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM))
496544
WOLFSSL_LOCAL int wc_CryptoCb_PqcSigGetDevId(int type, void* key);
497545

wolfssl/wolfcrypt/ext_kyber.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#ifndef EXT_KYBER_H
2323
#define EXT_KYBER_H
2424

25+
#ifdef WOLF_CRYPTO_CB
26+
#include <wolfssl/wolfcrypt/cryptocb.h>
27+
#endif
28+
2529
#ifdef WOLFSSL_HAVE_KYBER
2630
#include <wolfssl/wolfcrypt/kyber.h>
2731

@@ -56,6 +60,12 @@ struct KyberKey {
5660
* Note we don't save the variant (SHAKE vs AES) as that is decided at
5761
* configuration time. */
5862
int type;
63+
64+
#ifdef WOLF_CRYPTO_CB
65+
void* devCtx;
66+
int devId;
67+
#endif
68+
5969
byte priv[EXT_KYBER_MAX_PRIV_SZ];
6070
byte pub[EXT_KYBER_MAX_PUB_SZ];
6171
};

0 commit comments

Comments
 (0)