[PATCH RFC 005/104] crypto: hide crypto_default_rng variable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux