Merge pull request #10132 from douzzer/20260404-default_rng_bank

20260404-default_rng_bank
This commit is contained in:
philljj
2026-04-06 22:54:20 -05:00
committed by GitHub
10 changed files with 640 additions and 120 deletions
+1
View File
@@ -649,6 +649,7 @@ WC_NO_VERBOSE_RNG
WC_PKCS11_FIND_WITH_ID_ONLY
WC_PKCS12_PBKDF_USING_MP_API
WC_PROTECT_ENCRYPTED_MEM
WC_RNG_BANK_NO_DEFAULT_SUPPORT
WC_RNG_BLOCKING
WC_RSA_NONBLOCK
WC_RSA_NONBLOCK_TIME
+248 -110
View File
@@ -997,7 +997,11 @@ struct wc_swallow_the_semicolon
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/rng_bank.h>
static volatile int wc_linuxkm_drbg_init_tfm_disable_vector_registers = 0;
#ifndef WC_RNG_BANK_DEFAULT_SUPPORT
#error LINUXKM_LKCAPI_REGISTER_HASH_DRBG requires WC_RNG_BANK_DEFAULT_SUPPORT.
#endif
static volatile int wc_linuxkm_rng_initing_default_bank_flag = 0;
#ifndef WC_LINUXKM_INITRNG_TIMEOUT_SEC
#define WC_LINUXKM_INITRNG_TIMEOUT_SEC 30
@@ -1032,13 +1036,12 @@ static int linuxkm_affinity_unlock(void *arg) {
return 0;
}
static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
static int wc_linuxkm_rng_bank_init(struct wc_rng_bank *ctx)
{
struct wc_rng_bank *ctx = (struct wc_rng_bank *)crypto_tfm_ctx(tfm);
int ret;
word32 flags = WC_RNG_BANK_FLAG_CAN_WAIT;
if (wc_linuxkm_drbg_init_tfm_disable_vector_registers)
if (wc_linuxkm_rng_initing_default_bank_flag)
flags |= WC_RNG_BANK_FLAG_NO_VECTOR_OPS;
ret = wc_rng_bank_init(
@@ -1052,14 +1055,24 @@ static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
linuxkm_affinity_get_id,
linuxkm_affinity_unlock,
NULL);
if (ret != 0) {
if (ret == 0) {
if (wc_linuxkm_rng_initing_default_bank_flag) {
ret = wc_rng_bank_default_set(ctx);
if (ret != 0) {
(void)wc_rng_bank_fini(ctx);
pr_err("ERROR: wc_rng_bank_default_set() in wc_linuxkm_rng_bank_init() returned err %d\n", ret);
WC_DUMP_BACKTRACE_NONDEBUG;
}
}
}
else {
(void)wc_rng_bank_fini(ctx);
pr_err("ERROR: wc_rng_bank_set_affinity_handlers() in wc_linuxkm_drbg_init_tfm() returned err %d\n", ret);
pr_err("ERROR: wc_rng_bank_set_affinity_handlers() in wc_linuxkm_rng_bank_init() returned err %d\n", ret);
WC_DUMP_BACKTRACE_NONDEBUG;
}
}
else {
pr_err("ERROR: wc_rng_bank_init() in wc_linuxkm_drbg_init_tfm() returned err %d\n", ret);
pr_err("ERROR: wc_rng_bank_init() in wc_linuxkm_rng_bank_init() returned err %d\n", ret);
if (ret == WC_NO_ERR_TRACE(MEMORY_E))
ret = -ENOMEM;
else if (ret == WC_NO_ERR_TRACE(WC_TIMEOUT_E))
@@ -1073,10 +1086,21 @@ static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
return ret;
}
static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
{
return wc_linuxkm_rng_bank_init((struct wc_rng_bank *)crypto_tfm_ctx(tfm));
}
static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
{
struct wc_rng_bank *ctx = (struct wc_rng_bank *)crypto_tfm_ctx(tfm);
int ret = wc_rng_bank_fini(ctx);
int ret;
ret = wc_rng_bank_default_clear(ctx);
if (ret && (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)))
pr_err("ERROR: wc_rng_bank_default_clear() in wc_linuxkm_drbg_exit_tfm() returned unexpected code %d\n", ret);
ret = wc_rng_bank_fini(ctx);
if (ret != 0)
pr_err("ERROR: wc_rng_bank_fini() in wc_linuxkm_drbg_exit_tfm() returned err %d\n", ret);
@@ -1086,8 +1110,7 @@ static void wc_linuxkm_drbg_exit_tfm(struct crypto_tfm *tfm)
static int wc_linuxkm_drbg_default_instance_registered = 0;
static struct wc_rng_bank_inst *linuxkm_get_drbg(struct crypto_rng *tfm) {
struct wc_rng_bank *ctx = (struct wc_rng_bank *)crypto_rng_ctx(tfm);
static struct wc_rng_bank_inst *linuxkm_get_drbg(struct wc_rng_bank *ctx) {
int err;
struct wc_rng_bank_inst *ret;
word32 flags =
@@ -1095,12 +1118,6 @@ static struct wc_rng_bank_inst *linuxkm_get_drbg(struct crypto_rng *tfm) {
WC_RNG_BANK_FLAG_CAN_WAIT |
WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST;
/* check for mismatched handler. */
if (tfm->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm) {
pr_err("BUG: linuxkm_get_drbg() called on foreign tfm.\n");
return NULL;
}
if (preempt_count() == 0)
flags |= WC_RNG_BANK_FLAG_AFFINITY_LOCK;
else
@@ -1117,8 +1134,7 @@ static struct wc_rng_bank_inst *linuxkm_get_drbg(struct crypto_rng *tfm) {
return ret;
}
static void linuxkm_put_drbg(struct crypto_rng *tfm, struct wc_rng_bank_inst **drbg) {
struct wc_rng_bank *ctx = (struct wc_rng_bank *)crypto_rng_ctx(tfm);
static void linuxkm_put_drbg(struct wc_rng_bank *ctx, struct wc_rng_bank_inst **drbg) {
int ret = wc_rng_bank_checkin(ctx, drbg);
if (ret != 0) {
pr_err("ERROR: wc_rng_bank_checkin() in linuxkm_put_drbg() returned err %d.\n", ret);
@@ -1140,48 +1156,22 @@ int wc_linux_kernel_rng_is_wolfcrypt(struct crypto_rng *rng) {
}
}
static inline struct crypto_rng *get_crypto_default_rng(void) {
struct crypto_rng *current_crypto_default_rng = crypto_default_rng;
if (unlikely(! current_crypto_default_rng)) {
pr_warn("BUG: get_default_drbg_ctx() called with NULL crypto_default_rng.");
return NULL;
}
if (unlikely(! wc_linuxkm_drbg_default_instance_registered)) {
pr_warn("BUG: get_default_drbg_ctx() called without wc_linuxkm_drbg_default_instance_registered.");
return NULL;
}
/* note we can't call crypto_get_default_rng(), because it uses a mutex
* (not allowed in interrupt handlers). we do however sanity-check the
* cra_init function pointer, and these handlers are protected by
* random_bytes_cb_refcnt in the patched drivers/char/random.c.
*/
if (current_crypto_default_rng->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm) {
pr_err("BUG: get_default_drbg_ctx() found wrong crypto_default_rng \"%s\"\n", crypto_tfm_alg_driver_name(&current_crypto_default_rng->base));
return NULL;
}
return current_crypto_default_rng;
}
#ifndef WC_DRBG_BANKREF
#error LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT requires WC_DRBG_BANKREF support.
#endif
WC_MAYBE_UNUSED static int linuxkm_InitRng_DefaultRef(WC_RNG* rng) {
int ret;
struct crypto_rng *current_crypto_default_rng = get_crypto_default_rng();
if (current_crypto_default_rng == NULL) {
pr_warn_once("WARNING: get_crypto_default_rng() failed in linuxkm_InitRng_DefaultRef(); falling through to wc_InitRng().\n");
return wc_InitRng(rng);
struct wc_rng_bank *ctx;
int ret = wc_rng_bank_default_checkout(&ctx);
if (ret == 0) {
ret = wc_InitRng_BankRef(ctx, rng);
(void)wc_rng_bank_default_checkin(&ctx);
return ret;
}
else {
struct wc_rng_bank *default_bank = (struct wc_rng_bank *)crypto_rng_ctx(current_crypto_default_rng);
ret = wc_InitRng_BankRef(default_bank, rng);
return ret;
pr_warn_once("WARNING: linuxkm_InitRng_DefaultRef() called with null default_wc_rng_bank; falling through to wc_InitRng().\n");
return wc_InitRng(rng);
}
__builtin_unreachable();
@@ -1190,12 +1180,12 @@ WC_MAYBE_UNUSED static int linuxkm_InitRng_DefaultRef(WC_RNG* rng) {
#endif /* LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT && HAVE_HASHDRBG */
static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int dlen)
static int wc_linuxkm_drbg_generate(struct wc_rng_bank *ctx,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int dlen)
{
int ret, retried = 0;
struct wc_rng_bank_inst *drbg = linuxkm_get_drbg(tfm);
struct wc_rng_bank_inst *drbg = linuxkm_get_drbg(ctx);
if (! drbg) {
pr_err_once("BUG: linuxkm_get_drbg() failed.");
@@ -1239,7 +1229,7 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
retried = 1;
ret = wc_rng_bank_inst_reinit((struct wc_rng_bank *)crypto_rng_ctx(tfm),
ret = wc_rng_bank_inst_reinit(ctx,
drbg,
WC_LINUXKM_INITRNG_TIMEOUT_SEC,
WC_RNG_BANK_FLAG_CAN_WAIT);
@@ -1263,23 +1253,30 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
out:
linuxkm_put_drbg(tfm, &drbg);
linuxkm_put_drbg(ctx, &drbg);
return ret;
}
static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
const u8 *seed, unsigned int slen)
static int wc_linuxkm_drbg_generate_tfm(struct crypto_rng *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int dlen)
{
struct wc_rng_bank *ctx = (struct wc_rng_bank *)crypto_rng_ctx(tfm);
int ret;
if (tfm->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm)
{
pr_err_once("BUG: mismatched tfm.");
return -EFAULT;
}
return wc_linuxkm_drbg_generate((struct wc_rng_bank *)crypto_rng_ctx(tfm),
src, slen, dst, dlen);
}
static int wc_linuxkm_drbg_seed(struct wc_rng_bank *ctx,
const u8 *seed, unsigned int slen)
{
int ret;
if (slen == 0)
return 0;
@@ -1292,9 +1289,22 @@ static int wc_linuxkm_drbg_seed(struct crypto_rng *tfm,
return ret;
}
static int wc_linuxkm_drbg_seed_tfm(struct crypto_rng *tfm,
const u8 *seed, unsigned int slen)
{
if (tfm->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm)
{
pr_err_once("BUG: mismatched tfm.");
return -EFAULT;
}
return wc_linuxkm_drbg_seed((struct wc_rng_bank *)crypto_rng_ctx(tfm),
seed, slen);
}
static struct rng_alg wc_linuxkm_drbg = {
.generate = wc_linuxkm_drbg_generate,
.seed = wc_linuxkm_drbg_seed,
.generate = wc_linuxkm_drbg_generate_tfm,
.seed = wc_linuxkm_drbg_seed_tfm,
.seedsize = 0,
.base = {
.cra_name = WOLFKM_STDRNG_NAME,
@@ -1329,26 +1339,22 @@ static int wc_linuxkm_drbg_loaded = 0;
#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
static inline struct wc_rng_bank *get_default_drbg_ctx(void) {
struct crypto_rng *current_crypto_default_rng = get_crypto_default_rng();
struct wc_rng_bank *ctx = (current_crypto_default_rng ? (struct wc_rng_bank *)crypto_rng_ctx(current_crypto_default_rng) : NULL);
if (ctx && (! ctx->rngs)) {
pr_err_once("BUG: get_default_drbg_ctx() found null ctx->rngs.");
return NULL;
}
else
return ctx;
}
static int wc__get_random_bytes(void *buf, size_t len)
{
struct crypto_rng *current_crypto_default_rng = get_crypto_default_rng();
if (! current_crypto_default_rng)
struct wc_rng_bank *current_default_wc_rng_bank;
int ret = wc_rng_bank_default_checkout(&current_default_wc_rng_bank);
if (ret) {
#ifdef WC_VERBOSE_RNG
pr_err_ratelimited("ERROR: wc_rng_bank_default_checkout() in wc__get_random_bytes() returned %d.\n", ret);
#endif
return -EFAULT;
}
else {
int ret = crypto_rng_get_bytes(current_crypto_default_rng, buf, len);
ret = wc_linuxkm_drbg_generate(current_default_wc_rng_bank,
NULL, 0, buf, len);
(void)wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
if (ret) {
pr_warn("BUG: wc_get_random_bytes falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.", ret);
pr_warn("BUG: wc__get_random_bytes falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.", ret);
}
return ret;
}
@@ -1357,21 +1363,27 @@ static int wc__get_random_bytes(void *buf, size_t len)
/* used by kernel >=5.14.0 */
static ssize_t wc_get_random_bytes_user(struct iov_iter *iter) {
struct crypto_rng *current_crypto_default_rng;
struct wc_rng_bank *current_default_wc_rng_bank;
int ret;
if (unlikely(!iov_iter_count(iter)))
return 0;
current_crypto_default_rng = get_crypto_default_rng();
if (! current_crypto_default_rng)
ret = wc_rng_bank_default_checkout(&current_default_wc_rng_bank);
if (ret) {
#ifdef WC_VERBOSE_RNG
pr_err_ratelimited("ERROR: wc_rng_bank_default_checkout() in wc_get_random_bytes_user() returned %d.\n", ret);
#endif
return -ECANCELED;
}
else {
ssize_t ret;
size_t this_copied, total_copied = 0;
byte block[WC_SHA256_BLOCK_SIZE];
for (;;) {
ret = (ssize_t)crypto_rng_get_bytes(current_crypto_default_rng, block, sizeof block);
ret = wc_linuxkm_drbg_generate(current_default_wc_rng_bank,
NULL, 0, block, sizeof block);
if (unlikely(ret != 0)) {
pr_err("ERROR: wc_get_random_bytes_user() crypto_rng_get_bytes() returned %ld.", ret);
pr_err("ERROR: wc_get_random_bytes_user() wc_linuxkm_drbg_generate() returned %d.", ret);
break;
}
@@ -1392,6 +1404,8 @@ static ssize_t wc_get_random_bytes_user(struct iov_iter *iter) {
}
}
(void)wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
ForceZero(block, sizeof(block));
if (total_copied == 0) {
@@ -1411,21 +1425,27 @@ static ssize_t wc_get_random_bytes_user(struct iov_iter *iter) {
/* used by kernel 4.9.0-5.13.x */
static ssize_t wc_extract_crng_user(void __user *buf, size_t nbytes) {
struct crypto_rng *current_crypto_default_rng;
int ret;
struct wc_rng_bank *current_default_wc_rng_bank;
if (unlikely(!nbytes))
return 0;
current_crypto_default_rng = get_crypto_default_rng();
if (! current_crypto_default_rng)
ret = wc_rng_bank_default_checkout(&current_default_wc_rng_bank);
if (ret) {
#ifdef WC_VERBOSE_RNG
pr_err_ratelimited("ERROR: wc_rng_bank_default_checkout() in wc_extract_crng_user() returned %d.\n", ret);
#endif
return -ECANCELED;
}
else {
ssize_t ret;
size_t this_copied, total_copied = 0;
byte block[WC_SHA256_BLOCK_SIZE];
for (;;) {
ret = (ssize_t)crypto_rng_get_bytes(current_crypto_default_rng, block, sizeof block);
ret = wc_linuxkm_drbg_generate(current_default_wc_rng_bank,
NULL, 0, block, sizeof block);
if (unlikely(ret != 0)) {
pr_err("ERROR: wc_extract_crng_user() crypto_rng_get_bytes() returned %ld.", ret);
pr_err("ERROR: wc_extract_crng_user() wc_linuxkm_drbg_generate() returned %d.", ret);
break;
}
@@ -1446,6 +1466,8 @@ static ssize_t wc_extract_crng_user(void __user *buf, size_t nbytes) {
}
}
(void)wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
ForceZero(block, sizeof(block));
if ((total_copied == 0) && (ret == 0)) {
@@ -1461,6 +1483,7 @@ static ssize_t wc_extract_crng_user(void __user *buf, size_t nbytes) {
}
static int wc_mix_pool_bytes(const void *buf, size_t len) {
int ret;
struct wc_rng_bank *ctx;
size_t i;
int n;
@@ -1469,8 +1492,15 @@ static int wc_mix_pool_bytes(const void *buf, size_t len) {
if (len == 0)
return 0;
if (! (ctx = get_default_drbg_ctx()))
ret = wc_rng_bank_default_checkout(&ctx);
if (ret) {
#ifdef WC_VERBOSE_RNG
pr_err_ratelimited("ERROR: wc_rng_bank_default_checkout() in wc_mix_pool_bytes() returned %d.\n", ret);
#endif
return -EFAULT;
}
ret = 0;
for (n = ctx->n_rngs - 1; n >= 0; --n) {
struct wc_rng_bank_inst *drbg;
@@ -1488,19 +1518,30 @@ static int wc_mix_pool_bytes(const void *buf, size_t len) {
wc_rng_bank_checkin(ctx, &drbg);
if (can_sleep) {
if (signal_pending(current))
return -EINTR;
if (signal_pending(current)) {
ret = -EINTR;
break;
}
cond_resched();
}
}
return 0;
(void)wc_rng_bank_default_checkin(&ctx);
return ret;
}
static int wc_crng_reseed(void) {
struct wc_rng_bank *ctx = get_default_drbg_ctx();
struct wc_rng_bank *ctx;
int can_sleep = (preempt_count() == 0);
int ret;
int ret = wc_rng_bank_default_checkout(&ctx);
if (ret) {
#ifdef WC_VERBOSE_RNG
pr_err_ratelimited("ERROR: wc_rng_bank_default_checkout() in wc_crng_reseed() returned %d.\n", ret);
#endif
return -EFAULT;
}
ret = wc_rng_bank_reseed(ctx, WC_LINUXKM_INITRNG_TIMEOUT_SEC,
can_sleep
@@ -1508,6 +1549,9 @@ static int wc_crng_reseed(void) {
WC_RNG_BANK_FLAG_CAN_WAIT
:
WC_RNG_BANK_FLAG_NONE);
(void)wc_rng_bank_default_checkin(&ctx);
if (ret != 0) {
pr_err("ERROR: wc_rng_bank_reseed() returned err %d.\n", ret);
return -EINVAL;
@@ -1710,12 +1754,15 @@ static int wc_get_random_bytes_user_kretprobe_installed = 0;
#endif /* LINUXKM_DRBG_GET_RANDOM_BYTES */
#if defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0))
static struct wc_rng_bank default_bank;
static int default_bank_inited;
#endif
static int wc_linuxkm_drbg_startup(void)
{
int ret;
#ifdef LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT
int cur_refcnt;
#endif
if (wc_linuxkm_drbg_loaded) {
pr_err("ERROR: wc_linuxkm_drbg_set_default called with wc_linuxkm_drbg_loaded.");
@@ -1824,27 +1871,33 @@ static int wc_linuxkm_drbg_startup(void)
/* for the default RNG, make sure we don't cache an underlying SHA256
* method that uses vector insns (forbidden from irq handlers).
*/
wc_linuxkm_drbg_init_tfm_disable_vector_registers = 1;
wc_linuxkm_rng_initing_default_bank_flag = 1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 1, 0)
ret = crypto_del_default_rng();
if (ret) {
wc_linuxkm_drbg_init_tfm_disable_vector_registers = 0;
wc_linuxkm_rng_initing_default_bank_flag = 0;
pr_err("ERROR: crypto_del_default_rng returned %d", ret);
return ret;
}
ret = crypto_get_default_rng();
wc_linuxkm_drbg_init_tfm_disable_vector_registers = 0;
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: crypto_get_default_rng returned %d", ret);
return ret;
}
cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
if (cur_refcnt < 2) {
pr_err("ERROR: wc_linuxkm_drbg refcnt = %d after crypto_get_default_rng()", cur_refcnt);
crypto_put_default_rng();
return -EINVAL;
{
int cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
if (cur_refcnt < 2) {
pr_err("ERROR: wc_linuxkm_drbg refcnt = %d after crypto_get_default_rng()", cur_refcnt);
crypto_put_default_rng();
return -EINVAL;
}
}
if (! crypto_default_rng) {
@@ -1860,6 +1913,66 @@ static int wc_linuxkm_drbg_startup(void)
}
crypto_put_default_rng();
#else /* >= 7.1.0 */
#ifdef CONFIG_CRYPTO_FIPS
if (fips_enabled) {
char buf[16];
ret = crypto_del_default_rng();
if (ret) {
wc_linuxkm_rng_initing_default_bank_flag = 0;
pr_err("ERROR: crypto_del_default_rng returned %d", ret);
return ret;
}
ret = __crypto_stdrng_get_bytes(buf, (unsigned int)sizeof buf);
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: __crypto_stdrng_get_bytes returned %d", ret);
return ret;
}
}
else
#endif /* CONFIG_CRYPTO_FIPS */
{
ret = wc_linuxkm_rng_bank_init(&default_bank);
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: wc_linuxkm_rng_bank_init returned %d", ret);
return ret;
}
default_bank_inited = 1;
}
#endif /* >= 7.1.0 */
{
struct wc_rng_bank *current_default_wc_rng_bank;
ret = wc_rng_bank_default_checkout(&current_default_wc_rng_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_checkout() after default stdrng registration returned %d", ret);
else {
ret = wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_checkin() after wc_rng_bank_default_checkout() returned %d", ret);
}
if (ret != 0) {
#if defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0))
if (default_bank_inited) {
(void)wc_rng_bank_default_clear(&default_bank);
(void)wc_rng_bank_fini(&default_bank);
default_bank_inited = 0;
}
#endif
return -ECANCELED;
}
}
wc_linuxkm_drbg_default_instance_registered = 1;
pr_info("%s registered as systemwide default stdrng.", wc_linuxkm_drbg.base.cra_driver_name);
pr_info("libwolfssl: to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs");
@@ -1999,11 +2112,36 @@ static int wc_linuxkm_drbg_cleanup(void) {
#endif /* LINUXKM_DRBG_GET_RANDOM_BYTES */
#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 1, 0)
ret = crypto_del_default_rng();
if (ret) {
pr_err("ERROR: crypto_del_default_rng failed: %d", ret);
return ret;
}
#else /* >= 7.1.0 */
#ifdef CONFIG_CRYPTO_FIPS
if (fips_enabled) {
ret = crypto_del_default_rng();
if (ret) {
pr_err("ERROR: crypto_del_default_rng failed: %d", ret);
return ret;
}
}
else
#endif /* CONFIG_CRYPTO_FIPS */
if (default_bank_inited) {
ret = wc_rng_bank_default_clear(&default_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_clear in wc_linuxkm_drbg_cleanup failed: %d", ret);
else {
ret = wc_rng_bank_fini(&default_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_fini in wc_linuxkm_drbg_cleanup failed: %d", ret);
}
default_bank_inited = 0;
}
#endif /* >= 7.1.0 */
wc_linuxkm_drbg_default_instance_registered = 0;
}
+1 -1
View File
@@ -27475,7 +27475,7 @@ static int error_test(void)
{
EXPECT_DECLS;
const char* errStr;
const char* unknownStr = wc_GetErrorString(0);
const char* unknownStr = wc_GetErrorString(WC_LAST_E - 1);
#ifdef NO_ERROR_STRINGS
/* Ensure a valid error code's string matches an invalid code's.
+3
View File
@@ -37,6 +37,9 @@ const char* wc_GetErrorString(int error)
{
switch ((enum wolfCrypt_ErrorCodes)error) {
case WC_SUCCESS:
return "wolfCrypt generic success";
case WC_FAILURE:
return "wolfCrypt generic failure";
+208 -7
View File
@@ -187,6 +187,8 @@ WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx) {
if (wolfSSL_RefCur(ctx->refcount) > 1)
return BUSY_E;
else if (wolfSSL_RefCur(ctx->refcount) < 1)
return BAD_STATE_E;
#ifndef WC_RNG_BANK_STATIC
if (ctx->rngs)
@@ -247,6 +249,123 @@ WOLFSSL_API int wc_rng_bank_free(struct wc_rng_bank **ctx) {
}
#endif /* !WC_RNG_BANK_STATIC */
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
/* The default_rng_bank facility is used by the Linux kernel module as a global
* resource for wc_rng_bank_checkout(),
* wc_local_rng_bank_checkout_for_bankref(), and wc_InitRng_BankRef(), and can
* be similarly used by any application, to cache DRBG seeding at application
* startup.
*/
static struct wc_rng_bank * volatile default_rng_bank;
WOLFSSL_API int wc_rng_bank_default_set(struct wc_rng_bank *bank) {
int ret;
struct wc_rng_bank *cur_default_rng_bank = NULL;
int new_refcount;
if (bank == NULL)
return BAD_FUNC_ARG;
if ((! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(wolfSSL_RefCur(bank->refcount) < 1))
{
return BAD_STATE_E;
}
wolfSSL_RefInc2(&bank->refcount, &new_refcount, &ret);
if (ret != 0)
return ret;
#ifdef WC_VERBOSE_RNG
if (new_refcount < 2)
WOLFSSL_DEBUG_PRINTF(
"BUG: wc_rng_bank_default_set() new_refcount %d.\n", new_refcount);
#else
(void)new_refcount;
#endif
if (wolfSSL_Atomic_Ptr_CompareExchange((void * volatile *)&default_rng_bank, (void **)&cur_default_rng_bank, bank))
return 0;
else {
wolfSSL_RefDec2(&bank->refcount, &new_refcount, &ret);
#ifdef WC_VERBOSE_RNG
if (new_refcount <= 0)
WOLFSSL_DEBUG_PRINTF(
"BUG: wc_rng_bank_default_set() cleanup popped refcount to %d.\n", new_refcount);
#else
(void)new_refcount;
#endif
return BUSY_E;
}
}
/* Note wc_rng_bank_default_checkout() must not be called before
* wc_rng_bank_default_set() returns, or after wc_rng_bank_default_clear() is
* called -- it is the caller's responsibility to assure this.
*/
WOLFSSL_API int wc_rng_bank_default_checkout(struct wc_rng_bank **bank) {
int ret;
struct wc_rng_bank *cur_default_rng_bank = default_rng_bank;
if (bank == NULL)
return BAD_FUNC_ARG;
if (cur_default_rng_bank == NULL)
return BAD_STATE_E;
wolfSSL_RefInc(&cur_default_rng_bank->refcount, &ret);
if (ret == 0)
*bank = cur_default_rng_bank;
return ret;
}
WOLFSSL_API int wc_rng_bank_default_checkin(struct wc_rng_bank **bank) {
int ret;
int new_refcount;
if ((bank == NULL) || (*bank == NULL))
return BAD_FUNC_ARG;
wolfSSL_RefDec2(&(*bank)->refcount, &new_refcount, &ret);
#ifdef WC_VERBOSE_RNG
if (new_refcount <= 0)
WOLFSSL_DEBUG_PRINTF(
"BUG: wc_rng_bank_default_checkin() popped refcount to %d.\n", new_refcount);
#else
(void)new_refcount;
#endif
*bank = NULL;
return ret;
}
/* Note, wc_rng_bank_default_clear() should only be called at module or
* application shutdown to avoid races with wc_rng_bank_default_checkout(), and
* must be called before wc_rng_bank_fini() on a bank previously passed to
* wc_rng_bank_default_set().
*/
WOLFSSL_API int wc_rng_bank_default_clear(struct wc_rng_bank *bank) {
if ((bank != default_rng_bank) || (bank == NULL))
return BAD_FUNC_ARG;
if (wolfSSL_Atomic_Ptr_CompareExchange((void * volatile *)&default_rng_bank, (void **)&bank, NULL)) {
int ret;
int new_refcount;
wolfSSL_RefDec2(&bank->refcount, &new_refcount, &ret);
#ifdef WC_VERBOSE_RNG
/* wc_rng_bank_fini() is the sole responsibility of the context that
* called wc_rng_bank_default_set() for this wc_rng_bank.
*/
if (new_refcount < 1)
WOLFSSL_DEBUG_PRINTF(
"BUG: wc_rng_bank_default_clear() popped refcount to %d.\n", new_refcount);
if (! (bank->flags & WC_RNG_BANK_FLAG_INITED))
WOLFSSL_DEBUG_PRINTF(
"BUG: wc_rng_bank_default_clear() bank is already uninited.\n");
#else
(void)new_refcount;
#endif
return ret;
}
else
return BUSY_E;
}
#endif /* WC_RNG_BANK_DEFAULT_SUPPORT */
/* wc_rng_bank_checkout() uses atomic operations to get exclusive ownership of a
* DRBG without delay. It expects to be called in uninterruptible context,
* though works fine in any context. When _PREFER_AFFINITY_INST, it starts by
@@ -268,13 +387,23 @@ WOLFSSL_API int wc_rng_bank_checkout(
time_t ts1, ts2;
int n_rngs_tried = 0;
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
if ((bank == NULL) ||
(! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(rng_inst == NULL))
{
return BAD_FUNC_ARG;
}
if ((! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(wolfSSL_RefCur(bank->refcount) < 1))
{
return BAD_STATE_E;
}
if ((flags & WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST) &&
(bank->affinity_get_id_cb == NULL))
{
@@ -446,15 +575,46 @@ WOLFSSL_LOCAL int wc_local_rng_bank_checkout_for_bankref(
}
#endif /* WC_DRBG_BANKREF */
static WC_INLINE int rng_inst_matches_bank(
struct wc_rng_bank *bank,
struct wc_rng_bank_inst *rng_inst)
{
if ((bank == NULL) || (rng_inst == NULL))
return BAD_FUNC_ARG;
#ifdef WC_RNG_BANK_STATIC
if ((rng_inst >= &bank->rngs[0]) &&
(rng_inst <= &bank->rngs[WC_RNG_BANK_STATIC_SIZE - 1]))
return 1;
else
return BAD_FUNC_ARG;
#else
if ((rng_inst >= bank->rngs) &&
(rng_inst <= bank->rngs + bank->n_rngs - 1))
return 1;
else
return BAD_FUNC_ARG;
#endif
}
WOLFSSL_API int wc_rng_bank_checkin(
struct wc_rng_bank *bank,
struct wc_rng_bank_inst **rng_inst)
{
int lockval;
int ret;
if ((bank == NULL) || (rng_inst == NULL) || (*rng_inst == NULL))
if (rng_inst == NULL)
return BAD_FUNC_ARG;
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
ret = rng_inst_matches_bank(bank, *rng_inst);
if (ret < 0)
return ret;
lockval = (int)WOLFSSL_ATOMIC_LOAD((*rng_inst)->lock);
WOLFSSL_ATOMIC_STORE((*rng_inst)->lock, WC_RNG_BANK_INST_LOCK_FREE);
@@ -483,8 +643,16 @@ WOLFSSL_API int wc_rng_bank_inst_reinit(
time_t ts1 = 0;
int devId;
if ((rng_inst == NULL) ||
(rng_inst->rng.drbg == NULL))
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
ret = rng_inst_matches_bank(bank, rng_inst);
if (ret < 0)
return BAD_FUNC_ARG;
if (rng_inst->rng.drbg == NULL)
{
return BAD_FUNC_ARG;
}
@@ -538,6 +706,11 @@ WOLFSSL_API int wc_rng_bank_seed(struct wc_rng_bank *bank,
int ret = 0;
int n;
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
if ((bank == NULL) ||
(! (bank->flags & WC_RNG_BANK_FLAG_INITED)))
{
@@ -595,8 +768,16 @@ WOLFSSL_API int wc_rng_bank_reseed(struct wc_rng_bank *bank,
int ret;
time_t ts1 = 0;
if (! bank)
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
if ((bank == NULL) ||
(! (bank->flags & WC_RNG_BANK_FLAG_INITED)))
{
return BAD_FUNC_ARG;
}
if (flags & (WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST |
WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST))
@@ -667,13 +848,23 @@ WOLFSSL_API int wc_InitRng_BankRef(struct wc_rng_bank *bank, WC_RNG *rng)
{
int ret;
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
if ((bank == NULL) ||
(! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(rng == NULL))
{
return BAD_FUNC_ARG;
}
if ((! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(wolfSSL_RefCur(bank->refcount) < 1))
{
return BAD_STATE_E;
}
XMEMSET(rng, 0, sizeof(*rng));
wolfSSL_RefInc(&bank->refcount, &ret);
@@ -712,13 +903,23 @@ WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng)
WOLFSSL_API int wc_rng_new_bankref(struct wc_rng_bank *bank, WC_RNG **rng) {
int ret;
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
if (bank == NULL)
bank = default_rng_bank;
#endif
if ((bank == NULL) ||
(! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(rng == NULL))
{
return BAD_FUNC_ARG;
}
if ((! (bank->flags & WC_RNG_BANK_FLAG_INITED)) ||
(wolfSSL_RefCur(bank->refcount) < 1))
{
return BAD_STATE_E;
}
*rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), bank->heap, DYNAMIC_TYPE_RNG);
if (*rng == NULL) {
return MEMORY_E;
+33
View File
@@ -1835,6 +1835,21 @@ void wolfSSL_RefWithMutexInc(wolfSSL_RefWithMutex* ref, int* err)
*err = ret;
}
void wolfSSL_RefWithMutexInc2(wolfSSL_RefWithMutex* ref, int *new_count,
int* err)
{
int ret = wc_LockMutex(&ref->mutex);
if (ret != 0) {
WOLFSSL_MSG("Failed to lock mutex for reference increment!");
*new_count = -1;
}
else {
*new_count = ++ref->count;
wc_UnLockMutex(&ref->mutex);
}
*err = ret;
}
int wolfSSL_RefWithMutexLock(wolfSSL_RefWithMutex* ref)
{
return wc_LockMutex(&ref->mutex);
@@ -1862,6 +1877,24 @@ void wolfSSL_RefWithMutexDec(wolfSSL_RefWithMutex* ref, int* isZero, int* err)
}
*err = ret;
}
void wolfSSL_RefWithMutexDec2(wolfSSL_RefWithMutex* ref, int* new_count,
int* err)
{
int ret = wc_LockMutex(&ref->mutex);
if (ret != 0) {
WOLFSSL_MSG("Failed to lock mutex for reference decrement!");
*new_count = -1;
}
else {
if (ref->count > 0) {
ref->count--;
}
*new_count = ref->count;
wc_UnLockMutex(&ref->mutex);
}
*err = ret;
}
#endif /* ! SINGLE_THREADED */
#if WOLFSSL_CRYPT_HW_MUTEX
+113 -1
View File
@@ -3682,7 +3682,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void)
{
const char* errStr;
char out[WOLFSSL_MAX_ERROR_SZ]; /* test fails if too small, < 64 */
const char* unknownStr = wc_GetErrorString(0);
const char* unknownStr = wc_GetErrorString((int)WC_LAST_E - 1);
#ifdef NO_ERROR_STRINGS
/* Ensure a valid error code's string matches an invalid code's.
@@ -21066,6 +21066,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
{
struct wc_rng_bank_inst *bogus_inst = (struct wc_rng_bank_inst *)(wc_ptr_t)bank;
ret = wc_rng_bank_checkin(bank, &bogus_inst);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
ret = wc_rng_bank_checkin(bank, &rng_inst);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
@@ -21104,6 +21111,14 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WC_DRBG_BANKREF
ret = wc_InitRng_BankRef(NULL, rng);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_InitRng_BankRef(bank, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_InitRng_BankRef(bank, rng);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
@@ -21117,6 +21132,10 @@ 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(NULL, 10, WC_RNG_BANK_FLAG_NONE);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_reseed(bank, 10, WC_RNG_BANK_FLAG_NONE);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
@@ -21180,6 +21199,10 @@ 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_seed(NULL, (byte *)bank_arg, (word32)sizeof(bank_arg), 10, WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
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);
@@ -21199,6 +21222,15 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
ret = wc_rng_bank_inst_reinit(NULL, rng_inst, 10, WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
/* bogus pointer test */
ret = wc_rng_bank_inst_reinit(bank, (struct wc_rng_bank_inst *)(wc_ptr_t)bank, 10, WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_inst_reinit(bank, rng_inst, 10, WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
@@ -21210,10 +21242,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
if (XMEMCMP(outbuf1, outbuf2, sizeof(outbuf1)) == 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
ret = wc_rng_bank_checkin(NULL, &rng_inst);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), 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_checkout(NULL, &rng_inst, -1, 10, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST | WC_RNG_BANK_FLAG_AFFINITY_LOCK);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
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);
@@ -21228,6 +21268,70 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#endif
#ifdef WC_RNG_BANK_DEFAULT_SUPPORT
ret = wc_rng_bank_default_clear(NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_default_clear(bank);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_default_set(bank);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
/* When gated in, passing a NULL bank arg to wc_rng_bank_checkout(),
* wc_rng_bank_checkin(), wc_rng_bank_inst_reinit(), wc_rng_bank_seed(),
* wc_rng_bank_reseed(), wc_InitRng_BankRef(), or wc_rng_new_bankref()
* implicitly designates the default bank.
*/
ret = wc_rng_bank_checkout(NULL, &rng_inst, 3, 10, WC_RNG_BANK_FLAG_NONE);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
if (rng_inst != bank->rngs + 3)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
ret = wc_rng_bank_inst_reinit(NULL, rng_inst, 10, WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
#ifdef WC_DRBG_BANKREF
ret = wc_InitRng_BankRef(NULL, rng);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
wc_FreeRng(rng);
#ifndef WC_RNG_BANK_STATIC
ret = wc_rng_new_bankref(NULL, &rng2);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
wc_rng_free(rng2);
rng2 = NULL;
#endif
#endif
ret = wc_rng_bank_checkin(NULL, &rng_inst);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_seed(NULL, (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_reseed(NULL, 10, WC_RNG_BANK_FLAG_NONE);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_bank_default_clear(bank);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
#endif /* WC_RNG_BANK_DEFAULT_SUPPORT */
#ifdef WC_RNG_BANK_STATIC
ret = 0;
@@ -21319,6 +21423,14 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
#ifdef WC_DRBG_BANKREF
ret = wc_rng_new_bankref(NULL, &rng2);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_new_bankref(bank2, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_rng_new_bankref(bank2, &rng2);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
+1
View File
@@ -46,6 +46,7 @@ enum wolfCrypt_ErrorCodes {
/* note that WOLFSSL_FATAL_ERROR is defined as -1 in error-ssl.h, for
* reasons of backward compatibility.
*/
WC_SUCCESS = 0,
WC_FAILURE = -1, /* Generic but traceable back compat errcode.
* Note, not reflected in MAX_CODE_E or
* WC_FIRST_E.
+12
View File
@@ -121,6 +121,18 @@ WOLFSSL_API int wc_rng_bank_fini(struct wc_rng_bank *ctx);
WOLFSSL_API int wc_rng_bank_free(struct wc_rng_bank **ctx);
#endif
#ifdef WC_RNG_BANK_NO_DEFAULT_SUPPORT
#undef WC_RNG_BANK_DEFAULT_SUPPORT
#else /* !WC_RNG_BANK_NO_DEFAULT_SUPPORT */
#ifndef WC_RNG_BANK_DEFAULT_SUPPORT
#define WC_RNG_BANK_DEFAULT_SUPPORT
#endif
WOLFSSL_API int wc_rng_bank_default_set(struct wc_rng_bank *bank);
WOLFSSL_API int wc_rng_bank_default_checkout(struct wc_rng_bank **bank);
WOLFSSL_API int wc_rng_bank_default_checkin(struct wc_rng_bank **bank);
WOLFSSL_API int wc_rng_bank_default_clear(struct wc_rng_bank *bank);
#endif /* !WC_RNG_BANK_NO_DEFAULT_SUPPORT */
WOLFSSL_API int wc_rng_bank_checkout(
struct wc_rng_bank *bank,
struct wc_rng_bank_inst **rng_inst,
+20 -1
View File
@@ -675,7 +675,7 @@
}
}
static WC_INLINE int wolfSSL_Atomic_Ptr_CompareExchange(
void * volatile *c, void *expected_ptr, void *new_ptr)
void * volatile *c, void **expected_ptr, void *new_ptr)
{
if (*(char * volatile *)c == *(char **)expected_ptr) {
*(char * volatile *)c = (char *)new_ptr;
@@ -758,6 +758,11 @@ typedef struct wolfSSL_RefWithMutex wolfSSL_Ref;
(void)wolfSSL_Atomic_Int_FetchAdd(&(ref)->count, 1); \
*(err) = 0; \
} while(0)
#define wolfSSL_RefInc2(ref, new_count, err) \
do { \
*(new_count) = wolfSSL_Atomic_Int_AddFetch(&(ref)->count, 1); \
*(err) = 0; \
} while(0)
#define wolfSSL_RefDec(ref, isZero, err) \
do { \
int __prev = wolfSSL_Atomic_Int_FetchSub(&(ref)->count, 1); \
@@ -765,6 +770,11 @@ typedef struct wolfSSL_RefWithMutex wolfSSL_Ref;
*(isZero) = (__prev == 1); \
*(err) = 0; \
} while(0)
#define wolfSSL_RefDec2(ref, new_count, err) \
do { \
*(new_count) = wolfSSL_Atomic_Int_SubFetch(&(ref)->count, 1); \
*(err) = 0; \
} while(0)
#else
@@ -773,7 +783,9 @@ typedef struct wolfSSL_RefWithMutex wolfSSL_Ref;
#define wolfSSL_RefInit wolfSSL_RefWithMutexInit
#define wolfSSL_RefFree wolfSSL_RefWithMutexFree
#define wolfSSL_RefInc wolfSSL_RefWithMutexInc
#define wolfSSL_RefInc2 wolfSSL_RefWithMutexInc2
#define wolfSSL_RefDec wolfSSL_RefWithMutexDec
#define wolfSSL_RefDec2 wolfSSL_RefWithMutexDec2
#endif
@@ -782,9 +794,11 @@ typedef struct wolfSSL_RefWithMutex wolfSSL_Ref;
#define wolfSSL_RefWithMutexInit wolfSSL_RefInit
#define wolfSSL_RefWithMutexFree wolfSSL_RefFree
#define wolfSSL_RefWithMutexInc wolfSSL_RefInc
#define wolfSSL_RefWithMutexInc2 wolfSSL_RefInc2
#define wolfSSL_RefWithMutexLock(ref) 0
#define wolfSSL_RefWithMutexUnlock(ref) 0
#define wolfSSL_RefWithMutexDec wolfSSL_RefDec
#define wolfSSL_RefWithMutexDec2 wolfSSL_RefDec2
#else
@@ -793,10 +807,15 @@ WOLFSSL_LOCAL void wolfSSL_RefWithMutexInit(wolfSSL_RefWithMutex* ref,
WOLFSSL_LOCAL void wolfSSL_RefWithMutexFree(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexInc(wolfSSL_RefWithMutex* ref,
int* err);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexInc2(wolfSSL_RefWithMutex* ref,
int *new_count,
int* err);
WOLFSSL_LOCAL int wolfSSL_RefWithMutexLock(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL int wolfSSL_RefWithMutexUnlock(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexDec(wolfSSL_RefWithMutex* ref,
int* isZero, int* err);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexDec2(wolfSSL_RefWithMutex* ref,
int* new_count, int* err);
#endif