De-globalize crypto_default_rng and make it accessible only through the crypto_get_default_rng()/crypto_put_default_rng() API instead. The users need to call these functions anyway so there is really no point in having it as a global. I opted to take double pointers as arguments (and return an error code) so we can do basic API misuse checking. Reported-by: Sriharsha Yadagudde <sriharsha.devdas@xxxxxxxxxx> Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx> --- crypto/dh.c | 8 ++++---- crypto/ecc.c | 8 ++++---- crypto/geniv.c | 8 ++++---- crypto/rng.c | 9 +++++---- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 8 ++++---- drivers/crypto/intel/keembay/keembay-ocs-ecc.c | 14 ++++++++------ include/crypto/rng.h | 6 ++---- net/tipc/crypto.c | 8 ++++---- 8 files changed, 35 insertions(+), 34 deletions(-) diff --git a/crypto/dh.c b/crypto/dh.c index 8250eeeebd0f..1d80213574b3 100644 --- a/crypto/dh.c +++ b/crypto/dh.c @@ -352,6 +352,7 @@ static void *dh_safe_prime_gen_privkey(const struct dh_safe_prime *safe_prime, { unsigned int n, oversampling_size; __be64 *key; + struct crypto_rng *rng; int err; u64 h, o; @@ -389,12 +390,11 @@ static void *dh_safe_prime_gen_privkey(const struct dh_safe_prime *safe_prime, * random bits and interpret them as a big endian integer. */ err = -EFAULT; - if (crypto_get_default_rng()) + if (crypto_get_default_rng(&rng)) goto out_err; - err = crypto_rng_get_bytes(crypto_default_rng, (u8 *)key, - oversampling_size); - crypto_put_default_rng(); + err = crypto_rng_get_bytes(rng, (u8 *)key, oversampling_size); + crypto_put_default_rng(&rng); if (err) goto out_err; diff --git a/crypto/ecc.c b/crypto/ecc.c index 6cf9a945fc6c..c9f82626177b 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -1525,6 +1525,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, const struct ecc_curve *curve = ecc_get_curve(curve_id); unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; unsigned int nbits = vli_num_bits(curve->n, ndigits); + struct crypto_rng *rng; int err; /* @@ -1545,13 +1546,12 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, * This condition is met by the default RNG because it selects a favored * DRBG with a security strength of 256. */ - if (crypto_get_default_rng()) + if (crypto_get_default_rng(&rng)) return -EFAULT; /* Step 3: obtain N returned_bits from the DRBG. */ - err = crypto_rng_get_bytes(crypto_default_rng, - (u8 *)private_key, nbytes); - crypto_put_default_rng(); + err = crypto_rng_get_bytes(rng, (u8 *)private_key, nbytes); + crypto_put_default_rng(&rng); if (err) return err; diff --git a/crypto/geniv.c b/crypto/geniv.c index 42eff6a7387c..0b18240ac813 100644 --- a/crypto/geniv.c +++ b/crypto/geniv.c @@ -109,18 +109,18 @@ int aead_init_geniv(struct crypto_aead *aead) { struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead); struct aead_instance *inst = aead_alg_instance(aead); + struct crypto_rng *rng; struct crypto_aead *child; int err; spin_lock_init(&ctx->lock); - err = crypto_get_default_rng(); + err = crypto_get_default_rng(&rng); if (err) goto out; - err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, - crypto_aead_ivsize(aead)); - crypto_put_default_rng(); + err = crypto_rng_get_bytes(rng, ctx->salt, crypto_aead_ivsize(aead)); + crypto_put_default_rng(&rng); if (err) goto out; diff --git a/crypto/rng.c b/crypto/rng.c index b8ae6ebc091d..2a246e1a0918 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -24,8 +24,7 @@ #include "internal.h" static DEFINE_MUTEX(crypto_default_rng_lock); -struct crypto_rng *crypto_default_rng; -EXPORT_SYMBOL_GPL(crypto_default_rng); +static struct crypto_rng *crypto_default_rng; static int crypto_default_rng_refcnt; int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen) @@ -107,7 +106,7 @@ struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask) } EXPORT_SYMBOL_GPL(crypto_alloc_rng); -int crypto_get_default_rng(void) +int crypto_get_default_rng(struct crypto_rng **result) { struct crypto_rng *rng; int err; @@ -128,6 +127,7 @@ int crypto_get_default_rng(void) crypto_default_rng = rng; } + *result = crypto_default_rng; crypto_default_rng_refcnt++; err = 0; @@ -138,9 +138,10 @@ int crypto_get_default_rng(void) } EXPORT_SYMBOL_GPL(crypto_get_default_rng); -void crypto_put_default_rng(void) +void crypto_put_default_rng(struct crypto_rng **rng) { mutex_lock(&crypto_default_rng_lock); + *rng = NULL; crypto_default_rng_refcnt--; mutex_unlock(&crypto_default_rng_lock); } diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c index 1550c3818383..48872721214c 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -1380,17 +1380,17 @@ static bool hpre_key_is_zero(char *key, unsigned short key_sz) static int ecdh_gen_privkey(struct hpre_ctx *ctx, struct ecdh *params) { struct device *dev = ctx->dev; + struct crypto_rng *rng; int ret; - ret = crypto_get_default_rng(); + ret = crypto_get_default_rng(&rng); if (ret) { dev_err(dev, "failed to get default rng, ret = %d!\n", ret); return ret; } - ret = crypto_rng_get_bytes(crypto_default_rng, (u8 *)params->key, - params->key_size); - crypto_put_default_rng(); + ret = crypto_rng_get_bytes(rng, (u8 *)params->key, params->key_size); + crypto_put_default_rng(&rng); if (ret) dev_err(dev, "failed to get rng, ret = %d!\n", ret); diff --git a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c index 59308926399d..a79e6549740f 100644 --- a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c +++ b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c @@ -223,6 +223,7 @@ static int kmb_ecc_point_mult(struct ocs_ecc_dev *ecc_dev, u64 *scalar, const struct ecc_curve *curve) { + struct crypto_rng *rng; u8 sca[KMB_ECC_VLI_MAX_BYTES]; /* Use the maximum data size. */ u32 op_size = (curve->g.ndigits > ECC_CURVE_NIST_P256_DIGITS) ? OCS_ECC_OP_SIZE_384 : OCS_ECC_OP_SIZE_256; @@ -230,12 +231,12 @@ static int kmb_ecc_point_mult(struct ocs_ecc_dev *ecc_dev, int rc = 0; /* Generate random nbytes for Simple and Differential SCA protection. */ - rc = crypto_get_default_rng(); + rc = crypto_get_default_rng(&rng); if (rc) return rc; - rc = crypto_rng_get_bytes(crypto_default_rng, sca, nbytes); - crypto_put_default_rng(); + rc = crypto_rng_get_bytes(rng, sca, nbytes); + crypto_put_default_rng(&rng); if (rc) return rc; @@ -490,6 +491,7 @@ static int kmb_ecc_is_key_valid(const struct ecc_curve *curve, */ static int kmb_ecc_gen_privkey(const struct ecc_curve *curve, u64 *privkey) { + struct crypto_rng *rng; size_t nbytes = digits_to_bytes(curve->g.ndigits); u64 priv[KMB_ECC_VLI_MAX_DIGITS]; size_t nbits; @@ -512,11 +514,11 @@ static int kmb_ecc_gen_privkey(const struct ecc_curve *curve, u64 *privkey) * This condition is met by the default RNG because it selects a favored * DRBG with a security strength of 256. */ - if (crypto_get_default_rng()) + if (crypto_get_default_rng(&rng)) return -EFAULT; - rc = crypto_rng_get_bytes(crypto_default_rng, (u8 *)priv, nbytes); - crypto_put_default_rng(); + rc = crypto_rng_get_bytes(rng, (u8 *)priv, nbytes); + crypto_put_default_rng(&rng); if (rc) goto cleanup; diff --git a/include/crypto/rng.h b/include/crypto/rng.h index f8224cc390f8..816f255adcd3 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -57,10 +57,8 @@ struct crypto_rng { struct crypto_tfm base; }; -extern struct crypto_rng *crypto_default_rng; - -int crypto_get_default_rng(void); -void crypto_put_default_rng(void); +int crypto_get_default_rng(struct crypto_rng **rng); +void crypto_put_default_rng(struct crypto_rng **rng); /** * DOC: Random number generator API diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index ea5bb131ebd0..6b085fd383b0 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -368,13 +368,13 @@ int tipc_aead_key_validate(struct tipc_aead_key *ukey, struct genl_info *info) static int tipc_aead_key_generate(struct tipc_aead_key *skey) { int rc = 0; + struct crypto_rng *rng; /* Fill the key's content with a random value via RNG cipher */ - rc = crypto_get_default_rng(); + rc = crypto_get_default_rng(&rng); if (likely(!rc)) { - rc = crypto_rng_get_bytes(crypto_default_rng, skey->key, - skey->keylen); - crypto_put_default_rng(); + rc = crypto_rng_get_bytes(rng, skey->key, skey->keylen); + crypto_put_default_rng(&rng); } return rc; -- 2.39.3