[PATCH] 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>
---
 crypto/lskcipher.c | 8 --------
 crypto/skcipher.c  | 8 +++++++-
 2 files changed, 7 insertions(+), 9 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);

base-commit: 8468516f9f93a41dc65158b6428a1a1039c68f20
-- 
2.42.0




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