mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 21:32:26 +01:00
wolfcrypt/src/rng_bank.c, wolfssl/wolfcrypt/rng_bank.h, wolfcrypt/test/test.c:
* add WC_RNG_BANK_STATIC to WC_RNG_BANK_SUPPORT, supporting WOLFSSL_NO_MALLOC; * in random_bank_test(), fix gate around _NO_VECTOR_OPS sha256.sha_method test (WOLFSSL_SMALL_STACK_CACHE, and USE_INTEL_SPEEDUP not WC_HAVE_VECTOR_SPEEDUPS); * in definition of struct wc_rng_bank_inst, accommodate WOLFSSL_NO_ATOMICS builds; wolfssl/wolfcrypt/random.h: in definition of struct WC_RNG, add gate to avoid empty union in !HAVE_HASHDRBG configs.
This commit is contained in:
@@ -50,11 +50,16 @@ WOLFSSL_API int wc_rng_bank_init(
|
||||
ctx->flags = flags | WC_RNG_BANK_FLAG_INITED;
|
||||
ctx->heap = heap;
|
||||
|
||||
#ifdef WC_RNG_BANK_STATIC
|
||||
if (n_rngs > WC_RNG_BANK_STATIC_SIZE)
|
||||
return BAD_LENGTH_E;
|
||||
#else
|
||||
ctx->rngs = (struct wc_rng_bank_inst *)
|
||||
XMALLOC(sizeof(*ctx->rngs) * (size_t)n_rngs,
|
||||
heap, DYNAMIC_TYPE_RNG);
|
||||
if (! ctx->rngs)
|
||||
ret = MEMORY_E;
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
XMEMSET(ctx->rngs, 0, sizeof(*ctx->rngs) * (size_t)n_rngs);
|
||||
@@ -116,6 +121,7 @@ WOLFSSL_API int wc_rng_bank_init(
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_bank_new(
|
||||
struct wc_rng_bank **ctx,
|
||||
int n_rngs,
|
||||
@@ -142,6 +148,7 @@ WOLFSSL_API int wc_rng_bank_new(
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WC_RNG_BANK_STATIC */
|
||||
|
||||
WOLFSSL_API int wc_rng_bank_set_affinity_handlers(
|
||||
struct wc_rng_bank *ctx,
|
||||
@@ -181,7 +188,10 @@ WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx) {
|
||||
if (wolfSSL_RefCur(ctx->refcount) > 1)
|
||||
return BUSY_E;
|
||||
|
||||
if (ctx->rngs) {
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
if (ctx->rngs)
|
||||
#endif
|
||||
{
|
||||
for (i = 0; i < ctx->n_rngs; ++i) {
|
||||
if (ctx->rngs[i].lock != 0) {
|
||||
/* better to leak than to crash. */
|
||||
@@ -198,8 +208,10 @@ WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx) {
|
||||
wc_FreeRng(&ctx->rngs[i].rng);
|
||||
}
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
XFREE(ctx->rngs, ctx->heap, DYNAMIC_TYPE_RNG);
|
||||
ctx->rngs = NULL;
|
||||
#endif
|
||||
ctx->n_rngs = 0;
|
||||
}
|
||||
|
||||
@@ -211,6 +223,7 @@ WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_bank_free(struct wc_rng_bank **ctx) {
|
||||
int ret;
|
||||
void *heap;
|
||||
@@ -232,6 +245,7 @@ WOLFSSL_API int wc_rng_bank_free(struct wc_rng_bank **ctx) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WC_RNG_BANK_STATIC */
|
||||
|
||||
/* wc_rng_bank_checkout() uses atomic operations to get exclusive ownership of a
|
||||
* DRBG without delay. It expects to be called in uninterruptible context,
|
||||
@@ -694,6 +708,7 @@ WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_new_bankref(struct wc_rng_bank *bank, WC_RNG **rng) {
|
||||
int ret;
|
||||
|
||||
@@ -717,6 +732,7 @@ WOLFSSL_API int wc_rng_new_bankref(struct wc_rng_bank *bank, WC_RNG **rng) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WC_RNG_BANK_STATIC */
|
||||
|
||||
#endif /* WC_DRBG_BANKREF */
|
||||
|
||||
|
||||
@@ -20170,15 +20170,19 @@ static int rng_bank_affinity_unlock(void *arg) {
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
{
|
||||
|
||||
int ret;
|
||||
WC_DECLARE_VAR(bank, struct wc_rng_bank, 1, HEAP_HINT);
|
||||
struct wc_rng_bank_inst *rng_inst = NULL;
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
WC_DECLARE_VAR(rng, WC_RNG, 1, HEAP_HINT);
|
||||
#endif
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
struct wc_rng_bank *bank2 = NULL;
|
||||
struct wc_rng_bank_inst *rng_inst2 = NULL;
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
WC_RNG *rng = NULL, *rng2 = NULL;
|
||||
WC_RNG *rng2 = NULL;
|
||||
#endif
|
||||
#endif /* !WC_RNG_BANK_STATIC */
|
||||
static const char bank_arg[] = "hi";
|
||||
byte outbuf1[16], outbuf2[16];
|
||||
int i;
|
||||
@@ -20188,11 +20192,22 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
return WC_TEST_RET_ENC_EC(MEMORY_E));
|
||||
XMEMSET(bank, 0, sizeof(*bank));
|
||||
|
||||
ret = wc_rng_bank_init(NULL, 4, WC_RNG_BANK_FLAG_CAN_WAIT, 10, HEAP_HINT, INVALID_DEVID);
|
||||
WC_ALLOC_VAR_EX(rng, WC_RNG, 1, HEAP_HINT,
|
||||
DYNAMIC_TYPE_TMP_BUFFER,
|
||||
return WC_TEST_RET_ENC_EC(MEMORY_E));
|
||||
XMEMSET(rng, 0, sizeof(*rng));
|
||||
|
||||
ret = wc_rng_bank_init(NULL, WC_RNG_BANK_STATIC_SIZE, WC_RNG_BANK_FLAG_CAN_WAIT, 10, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_init(bank, 4, WC_RNG_BANK_FLAG_CAN_WAIT, 10, HEAP_HINT, INVALID_DEVID);
|
||||
#ifdef WC_RNG_BANK_STATIC
|
||||
ret = wc_rng_bank_init(bank, WC_RNG_BANK_STATIC_SIZE + 1, WC_RNG_BANK_FLAG_CAN_WAIT, 10, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_LENGTH_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
#endif
|
||||
|
||||
ret = wc_rng_bank_init(bank, WC_RNG_BANK_STATIC_SIZE, WC_RNG_BANK_FLAG_CAN_WAIT, 10, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
@@ -20205,91 +20220,79 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_new(&bank2, 4, WC_RNG_BANK_FLAG_NO_VECTOR_OPS, 10, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_set_affinity_handlers(
|
||||
bank2,
|
||||
rng_bank_affinity_lock,
|
||||
rng_bank_affinity_get_id,
|
||||
rng_bank_affinity_unlock,
|
||||
(char *)bank_arg);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 4;
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_INDEX_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 2;
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != bank2->rngs + 2)
|
||||
if (rng_inst != bank->rngs + 2)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (rng_bank_affinity_lock_lock != bank_arg + 1)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
/* if we can, confirm that WC_RNG_BANK_FLAG_NO_VECTOR_OPS worked. */
|
||||
#if defined(WC_HAVE_VECTOR_SPEEDUPS) && \
|
||||
#if defined(USE_INTEL_SPEEDUP) && \
|
||||
defined(WOLFSSL_KERNEL_MODE) && \
|
||||
defined(WOLFSSL_SMALL_STACK_CACHE) && \
|
||||
defined(WC_C_DYNAMIC_FALLBACK) && \
|
||||
defined(HAVE_HASHDRBG) && \
|
||||
defined(HAVE_HASHDRBG) && \
|
||||
defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
|
||||
if (((struct DRBG_internal *)rng_inst2->rng.drbg)->sha256.sha_method != 7 /* SHA256_C */)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(((struct DRBG_internal *)rng_inst2->rng.drbg)->sha256.sha_method), out);
|
||||
if (((struct DRBG_internal *)rng_inst->rng.drbg)->sha256.sha_method != 7 /* SHA256_C */)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(((struct DRBG_internal *)rng_inst->rng.drbg)->sha256.sha_method), out);
|
||||
#endif
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf1, sizeof(outbuf1));
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != NULL)
|
||||
if (rng_inst != NULL)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (rng_bank_affinity_lock_lock != bank_arg + 2)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, 3, 10, WC_RNG_BANK_FLAG_NONE);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, 3, 10, WC_RNG_BANK_FLAG_NONE);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != bank2->rngs + 3)
|
||||
if (rng_inst != bank->rngs + 3)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 3;
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != bank2->rngs + 3)
|
||||
if (rng_inst != bank->rngs + 3)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf2, sizeof(outbuf2));
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf2, sizeof(outbuf2));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != NULL)
|
||||
if (rng_inst != NULL)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
ret = wc_rng_new_bankref(bank2, &rng2);
|
||||
ret = wc_InitRng_BankRef(bank, rng);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 1;
|
||||
ret = wc_RNG_GenerateBlock(rng2, outbuf1, sizeof(outbuf1));
|
||||
ret = wc_RNG_GenerateBlock(rng, outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
@@ -20297,12 +20300,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif
|
||||
|
||||
ret = wc_rng_bank_reseed(bank2, 10, WC_RNG_BANK_FLAG_NONE);
|
||||
ret = wc_rng_bank_reseed(bank, 10, WC_RNG_BANK_FLAG_NONE);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
for (i = 0; i < bank2->n_rngs; ++i) {
|
||||
if (((struct DRBG_internal *)bank2->rngs[i].rng.drbg)
|
||||
for (i = 0; i < bank->n_rngs; ++i) {
|
||||
if (((struct DRBG_internal *)bank->rngs[i].rng.drbg)
|
||||
->reseedCtr != WC_RESEED_INTERVAL)
|
||||
{
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
|
||||
@@ -20313,53 +20316,35 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
/* WC_RNG_BANK_FLAG_CAN_WAIT needed to avoiding warning message that the
|
||||
* instance needs reseed.
|
||||
*/
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_CAN_WAIT | WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_CAN_WAIT | WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf1, sizeof(outbuf1));
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 1;
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_CAN_WAIT | WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_CAN_WAIT | WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf2, sizeof(outbuf2));
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf2, sizeof(outbuf2));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
if (wolfSSL_RefCur(bank2->refcount) != 2)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_free(&bank2);
|
||||
if (ret != WC_NO_ERR_TRACE(BUSY_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
wc_rng_free(rng2);
|
||||
rng2 = NULL;
|
||||
|
||||
if (wolfSSL_RefCur(bank2->refcount) != 1)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif
|
||||
|
||||
ret = wc_rng_bank_free(&bank2);
|
||||
ret = wc_rng_bank_seed(bank, (byte *)bank_arg, (word32)sizeof(bank_arg), 10, WC_RNG_BANK_FLAG_CAN_WAIT);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (bank2 != NULL)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 0;
|
||||
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
@@ -20368,8 +20353,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
/* can't wc_rng_bank_seed() with _FLAG_CAN_WAIT while holding an inst --
|
||||
* deadlocks then times out.
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
/* can't wc_rng_bank_seed() while holding an inst (deadlock/timeout) --
|
||||
* check in then check back out.
|
||||
*/
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
@@ -20387,25 +20375,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_seed(bank, (byte *)bank_arg, (word32)sizeof(bank_arg), 10, WC_RNG_BANK_FLAG_CAN_WAIT);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_checkout(bank, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
/* even though we passed in the same seed, the state is different, because
|
||||
* Hash_DRBG_Reseed() chains in the previous state, and also churns in the
|
||||
* "type" only on reseed.
|
||||
@@ -20428,24 +20397,160 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
if (wolfSSL_RefCur(bank->refcount) != 2)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_fini(bank);
|
||||
if (ret != WC_NO_ERR_TRACE(BUSY_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
wc_FreeRng(rng);
|
||||
|
||||
if (wolfSSL_RefCur(bank->refcount) != 1)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif
|
||||
|
||||
#ifdef WC_RNG_BANK_STATIC
|
||||
|
||||
ret = 0;
|
||||
|
||||
#else /* !WC_RNG_BANK_STATIC */
|
||||
|
||||
ret = wc_rng_bank_new(&bank2, WC_RNG_BANK_STATIC_SIZE + 1, WC_RNG_BANK_FLAG_NO_VECTOR_OPS, 10, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_set_affinity_handlers(
|
||||
bank2,
|
||||
rng_bank_affinity_lock,
|
||||
rng_bank_affinity_get_id,
|
||||
rng_bank_affinity_unlock,
|
||||
(char *)bank_arg);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
rng_bank_affinity_get_id_id = WC_RNG_BANK_STATIC_SIZE;
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng_inst2 != bank2->rngs + WC_RNG_BANK_STATIC_SIZE)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
/* can't wc_rng_bank_seed() while holding an inst (deadlock/timeout) --
|
||||
* check in then check back out.
|
||||
*/
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_seed(bank2, (byte *)bank_arg, (word32)sizeof(bank_arg), 10, WC_RNG_BANK_FLAG_CAN_WAIT);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf2, sizeof(outbuf2));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_seed(bank2, (byte *)bank_arg, (word32)sizeof(bank_arg), 10, WC_RNG_BANK_FLAG_CAN_WAIT);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_rng_bank_checkout(bank2, &rng_inst2, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
/* even though we passed in the same seed, the state is different, because
|
||||
* Hash_DRBG_Reseed() chains in the previous state, and also churns in the
|
||||
* "type" only on reseed.
|
||||
*/
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_inst_reinit(bank2, rng_inst2, 10, WC_RNG_BANK_FLAG_CAN_WAIT);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(rng_inst2), outbuf1, sizeof(outbuf1));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
ret = wc_rng_new_bankref(bank2, &rng2);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (rng2 == NULL)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
rng_bank_affinity_get_id_id = 1;
|
||||
ret = wc_RNG_GenerateBlock(rng2, outbuf2, sizeof(outbuf2));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
|
||||
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
if (wolfSSL_RefCur(bank2->refcount) != 2)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = wc_rng_bank_free(&bank2);
|
||||
if (ret != WC_NO_ERR_TRACE(BUSY_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
wc_FreeRng(rng2);
|
||||
|
||||
if (wolfSSL_RefCur(bank2->refcount) != 1)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
#endif /* WC_DRBG_BANKREF */
|
||||
|
||||
ret = wc_rng_bank_free(&bank2);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (bank2 != NULL)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
#endif /* WC_RNG_BANK_STATIC */
|
||||
|
||||
out:
|
||||
|
||||
{
|
||||
int cleanup_ret;
|
||||
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
if (rng) {
|
||||
cleanup_ret = wc_FreeRng(rng);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
}
|
||||
if (rng2) {
|
||||
cleanup_ret = wc_FreeRng(rng2);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup_ret = wc_FreeRng(rng);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
{
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
}
|
||||
WC_FREE_VAR_EX(rng, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif /* WC_DRBG_BANKREF */
|
||||
if (rng_inst) {
|
||||
cleanup_ret = wc_rng_bank_checkin(bank, &rng_inst);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
@@ -20453,6 +20558,16 @@ out:
|
||||
if ((rng_inst != NULL) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
cleanup_ret = wc_rng_bank_fini(bank);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
WC_FREE_VAR_EX(bank, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
#ifdef WC_DRBG_BANKREF
|
||||
if (rng2)
|
||||
wc_rng_free(rng2);
|
||||
#endif
|
||||
if (rng_inst2) {
|
||||
cleanup_ret = wc_rng_bank_checkin(bank2, &rng_inst2);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
@@ -20460,15 +20575,12 @@ out:
|
||||
if ((rng_inst2 != NULL) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
cleanup_ret = wc_rng_bank_fini(bank);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
WC_FREE_VAR_EX(bank, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
cleanup_ret = wc_rng_bank_free(&bank2);
|
||||
if ((cleanup_ret != 0) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_EC(cleanup_ret);
|
||||
if ((bank2 != NULL) && (ret == 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
#endif /* !WC_RNG_BANK_STATIC */
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -284,6 +284,8 @@ struct WC_RNG {
|
||||
void* heap;
|
||||
byte status;
|
||||
|
||||
#if defined(WC_RNG_BANK_SUPPORT) || defined(HAVE_HASHDRBG)
|
||||
|
||||
#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES
|
||||
union {
|
||||
#endif
|
||||
@@ -316,6 +318,8 @@ struct WC_RNG {
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WC_RNG_BANK_SUPPORT || HAVE_HASHDRBG */
|
||||
|
||||
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID)
|
||||
pid_t pid;
|
||||
#endif
|
||||
|
||||
@@ -57,10 +57,23 @@ typedef int (*wc_affinity_get_id_fn_t)(void *arg, int *id);
|
||||
typedef int (*wc_affinity_unlock_fn_t)(void *arg);
|
||||
|
||||
struct wc_rng_bank_inst {
|
||||
#ifdef WOLFSSL_NO_ATOMICS
|
||||
int lock;
|
||||
#else
|
||||
wolfSSL_Atomic_Int lock;
|
||||
#endif
|
||||
WC_RNG rng;
|
||||
};
|
||||
|
||||
#if defined(WOLFSSL_NO_MALLOC) && defined(NO_WOLFSSL_MEMORY) && \
|
||||
!defined(WC_RNG_BANK_STATIC)
|
||||
#define WC_RNG_BANK_STATIC
|
||||
#endif
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC_SIZE
|
||||
#define WC_RNG_BANK_STATIC_SIZE 4
|
||||
#endif
|
||||
|
||||
struct wc_rng_bank {
|
||||
wolfSSL_Ref refcount;
|
||||
void *heap;
|
||||
@@ -70,9 +83,14 @@ struct wc_rng_bank {
|
||||
wc_affinity_unlock_fn_t affinity_unlock_cb;
|
||||
void *cb_arg; /* if mutable, caller is responsible for thread safety. */
|
||||
int n_rngs;
|
||||
#ifdef WC_RNG_BANK_STATIC
|
||||
struct wc_rng_bank_inst rngs[WC_RNG_BANK_STATIC_SIZE];
|
||||
#else
|
||||
struct wc_rng_bank_inst *rngs; /* typically one per CPU ID, plus a few */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_bank_new(
|
||||
struct wc_rng_bank **ctx,
|
||||
int n_rngs,
|
||||
@@ -80,6 +98,7 @@ WOLFSSL_API int wc_rng_bank_new(
|
||||
int timeout_secs,
|
||||
void *heap,
|
||||
int devId);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wc_rng_bank_init(
|
||||
struct wc_rng_bank *ctx,
|
||||
@@ -98,7 +117,9 @@ WOLFSSL_API int wc_rng_bank_set_affinity_handlers(
|
||||
|
||||
WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx);
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_bank_free(struct wc_rng_bank **ctx);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wc_rng_bank_checkout(
|
||||
struct wc_rng_bank *bank,
|
||||
@@ -135,7 +156,9 @@ WOLFSSL_API int wc_InitRng_BankRef(struct wc_rng_bank *bank, WC_RNG *rng);
|
||||
|
||||
WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng);
|
||||
|
||||
#ifndef WC_RNG_BANK_STATIC
|
||||
WOLFSSL_API int wc_rng_new_bankref(struct wc_rng_bank *bank, WC_RNG **rng);
|
||||
#endif
|
||||
#endif /* WC_DRBG_BANKREF */
|
||||
|
||||
#define WC_RNG_BANK_INST_TO_RNG(rng_inst) (&(rng_inst)->rng)
|
||||
|
||||
Reference in New Issue
Block a user