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 <[email protected]>
Signed-off-by: Vegard Nossum <[email protected]>
---
 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


Reply via email to