diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-02-18 07:33:55 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-02-18 08:20:06 -0500 |
commit | b170a137f467ea951c3f256da1b911545acf3ffd (patch) | |
tree | b8f65dc4e1b5b6cd9bb144698c7007b7483a7c80 | |
parent | 3f683d6175748ef9daf4698d9ef5a488dd037063 (diff) |
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>
-rw-r--r-- | crypto/ablkcipher.c | 19 | ||||
-rw-r--r-- | crypto/blkcipher.c | 2 |
2 files changed, 20 insertions, 1 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, | |||
282 | alg->cra_ablkcipher.ivsize)) | 282 | alg->cra_ablkcipher.ivsize)) |
283 | return alg; | 283 | return alg; |
284 | 284 | ||
285 | crypto_mod_put(alg); | ||
286 | alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED, | ||
287 | mask & ~CRYPTO_ALG_TESTED); | ||
288 | if (IS_ERR(alg)) | ||
289 | return alg; | ||
290 | |||
291 | if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
292 | CRYPTO_ALG_TYPE_GIVCIPHER) { | ||
293 | if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) { | ||
294 | crypto_mod_put(alg); | ||
295 | alg = ERR_PTR(-ENOENT); | ||
296 | } | ||
297 | return alg; | ||
298 | } | ||
299 | |||
300 | BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
301 | CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : | ||
302 | alg->cra_ablkcipher.ivsize)); | ||
303 | |||
285 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); | 304 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); |
286 | } | 305 | } |
287 | 306 | ||
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index d70a41c002df..90d26c91f4e9 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
@@ -521,7 +521,7 @@ static int crypto_grab_nivcipher(struct crypto_skcipher_spawn *spawn, | |||
521 | int err; | 521 | int err; |
522 | 522 | ||
523 | type = crypto_skcipher_type(type); | 523 | type = crypto_skcipher_type(type); |
524 | mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV; | 524 | mask = crypto_skcipher_mask(mask)| CRYPTO_ALG_GENIV; |
525 | 525 | ||
526 | alg = crypto_alg_mod_lookup(name, type, mask); | 526 | alg = crypto_alg_mod_lookup(name, type, mask); |
527 | if (IS_ERR(alg)) | 527 | if (IS_ERR(alg)) |