diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 7b6630508..af62eac39 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4272,6 +4272,38 @@ static void wc_ecc_dump_oids(void) } #endif /* ECC_DUMP_OID */ + +WOLFSSL_ABI +ecc_key* wc_ecc_key_new(void* heap) +{ + ecc_key* key; + + key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); + if (key) { + if (wc_ecc_init_ex(key, heap, INVALID_DEVID) != 0) { + XFREE(key, heap, DYNAMIC_TYPE_ECC); + key = NULL; + } + } + + return key; +} + + +WOLFSSL_ABI +void wc_ecc_key_free(ecc_key* key) +{ + if (key) { + void* heap = key->heap; + + wc_ecc_free(key); + ForceZero(key, sizeof(ecc_key)); + XFREE(key, heap, DYNAMIC_TYPE_ECC); + (void)heap; + } +} + + /** Make a new ECC key rng An active RNG state diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 6f78b8bb1..5bdb9c5c8 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -830,6 +830,38 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, } +WOLFSSL_ABI +WC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, void* heap) +{ + WC_RNG* rng; + + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG); + if (rng) { + int error = _InitRng(rng, nonce, nonceSz, heap, INVALID_DEVID) != 0; + if (error) { + XFREE(rng, heap, DYNAMIC_TYPE_RNG); + rng = NULL; + } + } + + return rng; +} + + +WOLFSSL_ABI +void wc_rng_free(WC_RNG* rng) +{ + if (rng) { + void* heap = rng->heap; + + wc_FreeRng(rng); + ForceZero(rng, sizeof(WC_RNG)); + XFREE(rng, heap, DYNAMIC_TYPE_RNG); + (void)heap; + } +} + + int wc_InitRng(WC_RNG* rng) { return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d2ff1f381..5e2a0f00d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8728,24 +8728,16 @@ int idea_test(void) #ifndef WC_NO_RNG -static int random_rng_test(void) +static int _rng_test(WC_RNG* rng, int errorOffset) { - WC_RNG rng; byte block[32]; int ret, i; -#ifndef HAVE_FIPS - ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); -#else - ret = wc_InitRng(&rng); -#endif - if (ret != 0) return -6300; - XMEMSET(block, 0, sizeof(block)); - ret = wc_RNG_GenerateBlock(&rng, block, sizeof(block)); + ret = wc_RNG_GenerateBlock(rng, block, sizeof(block)); if (ret != 0) { - ret = -6301; + ret = -1; goto exit; } @@ -8757,43 +8749,79 @@ static int random_rng_test(void) } /* All zeros count check */ if (ret >= (int)sizeof(block)) { - ret = -6302; + ret = -2; goto exit; } - ret = wc_RNG_GenerateByte(&rng, block); + ret = wc_RNG_GenerateByte(rng, block); if (ret != 0) { - ret = -6303; + ret = -3; goto exit; } /* Parameter validation testing. */ ret = wc_RNG_GenerateBlock(NULL, block, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -6304; + ret = -4; goto exit; } - ret = wc_RNG_GenerateBlock(&rng, NULL, sizeof(block)); + ret = wc_RNG_GenerateBlock(rng, NULL, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -6305; + ret = -5; goto exit; } ret = wc_RNG_GenerateByte(NULL, block); if (ret != BAD_FUNC_ARG) { - ret = -6306; + ret = -6; goto exit; } - ret = wc_RNG_GenerateByte(&rng, NULL); + ret = wc_RNG_GenerateByte(rng, NULL); if (ret != BAD_FUNC_ARG) { - ret = -6307; + ret = -7; goto exit; } ret = 0; + exit: + if (ret != 0) + ret += errorOffset; + + return ret; +} + + +static int random_rng_test(void) +{ + byte nonce[8] = { 0 }; + WC_RNG localRng; + WC_RNG* rng; + int ret; + + rng = &localRng; + /* Test stack based RNG. */ +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(rng); +#endif + if (ret != 0) return -6300; + + ret = _rng_test(rng, -6300); + /* Make sure and free RNG */ - wc_FreeRng(&rng); + wc_FreeRng(rng); + + if (ret != 0) return ret; + + /* Test dynamic RNG. */ + rng = wc_rng_new(nonce, (word32)sizeof(nonce), HEAP_HINT); + if (rng == NULL) return -6310; + + ret = _rng_test(rng, -6310); + + wc_rng_free(rng); return ret; } @@ -18374,6 +18402,27 @@ exit: } #endif /* WOLFSSL_CERT_GEN */ +/* Test for the wc_ecc_key_new() and wc_ecc_key_free() functions. */ +static int ecc_test_allocator(WC_RNG* rng) +{ + ecc_key* key; + int ret; + + key = wc_ecc_key_new(HEAP_HINT); + if (key == NULL) { + ERROR_OUT(-8532, exit); + } + + ret = wc_ecc_make_key(rng, 32, key); + if (ret != 0) { + ERROR_OUT(-8533, exit); + } + +exit: + wc_ecc_key_free(key); + return ret; +} + int ecc_test(void) { int ret; @@ -18502,6 +18551,11 @@ int ecc_test(void) } #endif + ret = ecc_test_allocator(&rng); + if (ret != 0) { + printf("ecc_test_allocator failed!: %d\n", ret); + } + done: wc_FreeRng(&rng); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index ac34e2bd0..a7124991a 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -403,6 +403,10 @@ struct ecc_key { }; +WOLFSSL_ABI WOLFSSL_API ecc_key* wc_ecc_key_new(void*); +WOLFSSL_ABI WOLFSSL_API void wc_ecc_key_free(ecc_key*); + + /* ECC predefined curve sets */ extern const ecc_set_type ecc_sets[]; diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 62eb25979..e6ecf19a3 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -199,6 +199,11 @@ int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz); WOLFSSL_API int wc_FreeNetRandom(void); #endif /* HAVE_WNR */ + +WOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte*, word32, void*); +WOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG*); + + #ifndef WC_NO_RNG WOLFSSL_API int wc_InitRng(WC_RNG*); WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 483c6a2ce..16d7bb01e 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -34,6 +34,10 @@ #endif + #define WOLFSSL_ABI + /* Tag for all the APIs that are a part of the fixed ABI. */ + + #if defined(WORDS_BIGENDIAN) #define BIG_ENDIAN_ORDER #endif