diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 62e65dba7..0c60a7b5e 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -468,6 +468,29 @@ int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz) return ret; } + +int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz) +{ + int ret = NOT_COMPILED_IN; + CryptoCb* dev; + + /* locate registered callback */ + dev = wc_CryptoCb_FindDevice(os->devId); + if (dev) { + if (dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_SEED; + cryptoInfo.seed.os = os; + cryptoInfo.seed.seed = seed; + cryptoInfo.seed.sz = sz; + + ret = dev->cb(os->devId, &cryptoInfo, dev->ctx); + } + } + + return ret; +} #endif /* !WC_NO_RNG */ #endif /* WOLF_CRYPTO_CB */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 3a4159ad3..c317e505a 100755 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -703,6 +703,7 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, #endif #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) rng->devId = devId; + rng->seed.devId = devId; #else (void)devId; #endif @@ -1479,6 +1480,16 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { +#ifdef WOLF_CRYPTO_CB + int ret; + + if (os != NULL && os->devId != INVALID_DEVID) { + ret = wc_CryptoCb_RandomSeed(os, output, sz); + if (ret != NOT_COMPILED_IN) + return ret; + } +#endif + #ifdef HAVE_INTEL_RDSEED if (IS_INTEL_RDSEED(intel_flags)) { if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) { @@ -2126,6 +2137,14 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int ret = 0; +#ifdef WOLF_CRYPTO_CB + if (os != NULL && os->devId != INVALID_DEVID) { + ret = wc_CryptoCb_RandomSeed(os, output, sz); + if (ret != NOT_COMPILED_IN) + return ret; + } +#endif + #ifdef HAVE_INTEL_RDSEED if (IS_INTEL_RDSEED(intel_flags)) { ret = wc_GenerateSeed_IntelRD(NULL, output, sz); @@ -2199,6 +2218,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) } #endif + /* End wc_GenerateSeed */ #endif /* WC_NO_RNG */ #endif /* HAVE_FIPS */ diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index 6b67d8396..26c807059 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -1923,6 +1923,50 @@ static int Pkcs11AesGcmDecrypt(Pkcs11Session* session, wc_CryptoInfo* info) } #endif +#ifndef WC_NO_RNG +#ifndef HAVE_HASHDRBG +/** + * Performs random number generation. + * + * @param session [in] Session object. + * @param info [in] Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * 0 on success. + */ +static int Pkcs11RandomBlock(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + + rv = session->func->C_GenerateRandom(session->handle, info->rng.out, + info->rng.sz); + if (rv != CKR_OK) + ret = WC_HW_E; + return ret; +} +#endif + +/** + * Generates entropy (seed) data. + * + * @param session [in] Session object. + * @param info [in] Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * 0 on success. + */ +static int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + + rv = session->func->C_GenerateRandom(session->handle, info->seed.seed, + info->seed.sz); + if (rv != CKR_OK) + ret = WC_HW_E; + return ret; +} +#endif + /** * Perform a cryptographic operation using PKCS#11 device. * @@ -1986,8 +2030,25 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) ret = Pkcs11AesGcmDecrypt(&session, info); break; #endif - } } + } + else if (info->algo_type == WC_ALGO_TYPE_HASH) { + ret = NOT_COMPILED_IN; + } + else if (info->algo_type == WC_ALGO_TYPE_RNG) { + #if !defined(WC_NO_RNG) && !defined(HAVE_HASHDRBG) + ret = Pkcs11RandomBlock(&session, info); + #else + ret = NOT_COMPILED_IN; + #endif + } + else if (info->algo_type == WC_ALGO_TYPE_SEED) { + #ifndef WC_NO_RNG + ret = Pkcs11RandomSeed(&session, info); + #else + ret = NOT_COMPILED_IN; + #endif + } Pkcs11CloseSession(token, &session); } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 2142364c3..a54d421ab 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22837,6 +22837,26 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->rng.rng->devId = devIdArg; #endif } + else if (info->algo_type == WC_ALGO_TYPE_SEED) { + #ifndef WC_NO_RNG + static byte seed[] = { 0x00, 0x00, 0x00, 0x01 }; + word32 len; + int i; + + /* wc_GenerateSeed is a local symbol so we need to fake the entropy. */ + while (info->seed.sz > 0) { + len = (word32)sizeof(seed); + if (info->seed.sz < len) + len = info->seed.sz; + XMEMCPY(info->seed.seed, seed, sizeof(seed)); + info->seed.seed += len; + info->seed.sz -= len; + (*((word32*)seed))++; + } + + ret = 0; + #endif + } else if (info->algo_type == WC_ALGO_TYPE_PK) { #ifdef DEBUG_WOLFSSL printf("CryptoDevCb: Pk Type %d\n", info->pk.type); diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 1f9061047..79cf5b35b 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -169,6 +169,11 @@ typedef struct wc_CryptoInfo { byte* out; word32 sz; } rng; + struct { + OS_Seed* os; + byte* seed; + word32 sz; + } seed; #endif } wc_CryptoInfo; @@ -240,6 +245,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in, #ifndef WC_NO_RNG WOLFSSL_LOCAL int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz); +WOLFSSL_LOCAL int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz); #endif #endif /* WOLF_CRYPTO_CB */ diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 2286ff59c..28d6fc851 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -138,6 +138,9 @@ typedef struct OS_Seed { #else int fd; #endif + #if defined(WOLF_CRYPTO_CB) + int devId; + #endif } OS_Seed; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index abceaa604..1abab4378 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -525,8 +525,9 @@ WC_ALGO_TYPE_CIPHER = 2, WC_ALGO_TYPE_PK = 3, WC_ALGO_TYPE_RNG = 4, + WC_ALGO_TYPE_SEED = 5, - WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_RNG + WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_SEED }; /* hash types */