summaryrefslogtreecommitdiff
path: root/crypto/ablkcipher.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-02-18 20:33:55 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2009-02-18 21:20:06 +0800
commitb170a137f467ea951c3f256da1b911545acf3ffd (patch)
treeb8f65dc4e1b5b6cd9bb144698c7007b7483a7c80 /crypto/ablkcipher.c
parent3f683d6175748ef9daf4698d9ef5a488dd037063 (diff)
downloadlwn-b170a137f467ea951c3f256da1b911545acf3ffd.tar.gz
lwn-b170a137f467ea951c3f256da1b911545acf3ffd.zip
crypto: skcipher - Avoid infinite loop when cipher fails selftest
When an skcipher constructed through crypto_givcipher_default fails its selftest, we'll loop forever trying to construct new skcipher objects but failing because it already exists. The crux of the issue is that once a givcipher fails the selftest, we'll ignore it on the next run through crypto_skcipher_lookup and attempt to construct a new givcipher. We should instead return an error to the caller if we find a givcipher that has failed the test. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/ablkcipher.c')
-rw-r--r--crypto/ablkcipher.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 94140b3756fc..e11ce37c7104 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -282,6 +282,25 @@ static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
alg->cra_ablkcipher.ivsize))
return alg;
+ crypto_mod_put(alg);
+ alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED,
+ mask & ~CRYPTO_ALG_TESTED);
+ if (IS_ERR(alg))
+ return alg;
+
+ if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_GIVCIPHER) {
+ if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) {
+ crypto_mod_put(alg);
+ alg = ERR_PTR(-ENOENT);
+ }
+ return alg;
+ }
+
+ BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+ alg->cra_ablkcipher.ivsize));
+
return ERR_PTR(crypto_givcipher_default(alg, type, mask));
}