[PATCH v2] crypto: skcipher - fix weak key check for lskciphers

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

 



From: Eric Biggers <ebiggers@xxxxxxxxxx>

When an algorithm of the new "lskcipher" type is exposed through the
"skcipher" API, calls to crypto_skcipher_setkey() don't pass on the
CRYPTO_TFM_REQ_FORBID_WEAK_KEYS flag to the lskcipher.  This causes
self-test failures for ecb(des), as weak keys are not rejected anymore.
Fix this.

Fixes: 31865c4c4db2 ("crypto: skcipher - Add lskcipher")
Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx>
---

v2: remove prototype for crypto_lskcipher_setkey_sg()

 crypto/lskcipher.c | 8 --------
 crypto/skcipher.c  | 8 +++++++-
 crypto/skcipher.h  | 2 --
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/crypto/lskcipher.c b/crypto/lskcipher.c
index 9be3c04bc62a3..6e11badaa1035 100644
--- a/crypto/lskcipher.c
+++ b/crypto/lskcipher.c
@@ -187,28 +187,20 @@ int crypto_lskcipher_decrypt(struct crypto_lskcipher *tfm, const u8 *src,
 		struct crypto_istat_cipher *istat = lskcipher_get_stat(alg);
 
 		atomic64_inc(&istat->decrypt_cnt);
 		atomic64_add(len, &istat->decrypt_tlen);
 	}
 
 	return crypto_lskcipher_crypt(tfm, src, dst, len, iv, alg->decrypt);
 }
 EXPORT_SYMBOL_GPL(crypto_lskcipher_decrypt);
 
-int crypto_lskcipher_setkey_sg(struct crypto_skcipher *tfm, const u8 *key,
-			       unsigned int keylen)
-{
-	struct crypto_lskcipher **ctx = crypto_skcipher_ctx(tfm);
-
-	return crypto_lskcipher_setkey(*ctx, key, keylen);
-}
-
 static int crypto_lskcipher_crypt_sg(struct skcipher_request *req,
 				     int (*crypt)(struct crypto_lskcipher *tfm,
 						  const u8 *src, u8 *dst,
 						  unsigned len, u8 *iv,
 						  bool final))
 {
 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
 	struct crypto_lskcipher **ctx = crypto_skcipher_ctx(skcipher);
 	struct crypto_lskcipher *tfm = *ctx;
 	struct skcipher_walk walk;
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index b9496dc8a609f..ac8b8c0426542 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -614,21 +614,27 @@ static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm,
 }
 
 int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
 			   unsigned int keylen)
 {
 	struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
 	unsigned long alignmask = crypto_skcipher_alignmask(tfm);
 	int err;
 
 	if (cipher->co.base.cra_type != &crypto_skcipher_type) {
-		err = crypto_lskcipher_setkey_sg(tfm, key, keylen);
+		struct crypto_lskcipher **ctx = crypto_skcipher_ctx(tfm);
+
+		crypto_lskcipher_clear_flags(*ctx, CRYPTO_TFM_REQ_MASK);
+		crypto_lskcipher_set_flags(*ctx,
+					   crypto_skcipher_get_flags(tfm) &
+					   CRYPTO_TFM_REQ_MASK);
+		err = crypto_lskcipher_setkey(*ctx, key, keylen);
 		goto out;
 	}
 
 	if (keylen < cipher->min_keysize || keylen > cipher->max_keysize)
 		return -EINVAL;
 
 	if ((unsigned long)key & alignmask)
 		err = skcipher_setkey_unaligned(tfm, key, keylen);
 	else
 		err = cipher->setkey(tfm, key, keylen);
diff --git a/crypto/skcipher.h b/crypto/skcipher.h
index 6f1295f0fef24..16c9484360dab 100644
--- a/crypto/skcipher.h
+++ b/crypto/skcipher.h
@@ -13,18 +13,16 @@
 static inline struct crypto_istat_cipher *skcipher_get_stat_common(
 	struct skcipher_alg_common *alg)
 {
 #ifdef CONFIG_CRYPTO_STATS
 	return &alg->stat;
 #else
 	return NULL;
 #endif
 }
 
-int crypto_lskcipher_setkey_sg(struct crypto_skcipher *tfm, const u8 *key,
-			       unsigned int keylen);
 int crypto_lskcipher_encrypt_sg(struct skcipher_request *req);
 int crypto_lskcipher_decrypt_sg(struct skcipher_request *req);
 int crypto_init_lskcipher_ops_sg(struct crypto_tfm *tfm);
 int skcipher_prepare_alg_common(struct skcipher_alg_common *alg);
 
 #endif	/* _LOCAL_CRYPTO_SKCIPHER_H */

base-commit: 30febae71c6182e0762dc7744737012b4f8e6a6d
-- 
2.42.0




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