Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 541

kernel-2.6.18-238.el5.src.rpm

From: Jarod Wilson <jarod@redhat.com>
Date: Thu, 23 Apr 2009 14:37:47 -0400
Subject: [crypto] fix rfc4309 deadlocks
Message-id: 49F0B57B.90606@redhat.com
O-Subject: [RHEL5.4 PATCH 1/3 v2] crypto: fix rfc4309 deadlocks
Bugzilla: 472386
RH-Acked-by: Neil Horman <nhorman@redhat.com>

Bugzilla #472386: fips crypto: self-test needed for rfc4309(ccm(aes))
https://bugzilla.redhat.com/show_bug.cgi?id=472386

Part 1 of 3

Backport fixes from cryptodev-2.6 tree to remedy rfc4309(ccm(aes)) deadlocks.

Roll-up of:

crypto: api - Fix algorithm test race that broke aead initialisation:
http://git.kernel.org/?p=linux/kernel/git/herbert/cryptodev-2.6.git;a=commitdiff;h=b8e15992b420d09dae831125a623c474c8637cee

crypto: api - crypto_alg_mod_lookup either tested or untested:
http://git.kernel.org/?p=linux/kernel/git/herbert/cryptodev-2.6.git;a=commitdiff;h=ff753308d2f70f210ba468492cd9a01274d9d7ce

crypto: testmgr - Test skciphers with no IVs:
http://git.kernel.org/?p=linux/kernel/git/herbert/cryptodev-2.6.git;a=commitdiff;h=6fe4a28d8855e072036f36ee22f0a8f43f44918f

diff --git a/crypto/algapi.c b/crypto/algapi.c
index 23b5bc8..82e86c7 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -151,6 +151,9 @@ static struct crypto_larval *__crypto_register_alg(struct ncrypto_alg *alg)
 		if (q == alg)
 			goto err;
 
+		if (crypto_is_moribund(q))
+			continue;
+
 		if (crypto_is_larval(q)) {
 			if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
 				goto err;
@@ -199,7 +202,7 @@ void crypto_alg_tested(const char *name, int err)
 
 	down_write(&ncrypto_alg_sem);
 	list_for_each_entry(q, &ncrypto_alg_list, cra_list) {
-		if (!crypto_is_larval(q))
+		if (crypto_is_moribund(q) || !crypto_is_larval(q))
 			continue;
 
 		test = (struct crypto_larval *)q;
@@ -212,6 +215,7 @@ void crypto_alg_tested(const char *name, int err)
 	goto unlock;
 
 found:
+	q->cra_flags |= NCRYPTO_ALG_DEAD;
 	alg = test->adult;
 	if (err || list_empty(&alg->cra_list))
 		goto complete;
diff --git a/crypto/crypto_api.c b/crypto/crypto_api.c
index 1f9a034..c789ea3 100644
--- a/crypto/crypto_api.c
+++ b/crypto/crypto_api.c
@@ -247,7 +247,7 @@ struct ncrypto_alg *ncrypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
 	struct ncrypto_alg *larval;
 	int ok;
 
-	if (!(mask & NCRYPTO_ALG_TESTED)) {
+	if (!((type | mask) & NCRYPTO_ALG_TESTED)) {
 		type |= NCRYPTO_ALG_TESTED;
 		mask |= NCRYPTO_ALG_TESTED;
 	}
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 2393aaf..bf3afa3 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -24,6 +24,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <crypto/internal/aead.h>
 
 #include "ninternal.h"
 #include "testmgr.h"
@@ -1357,8 +1358,7 @@ static int cryptomgr_test(void *data)
 	u32 type = param->type;
 	int err = 0;
 
-	if (!((type ^ NCRYPTO_ALG_TYPE_BLKCIPHER) &
-	      NCRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & NCRYPTO_ALG_GENIV))
+	if (type & NCRYPTO_ALG_TESTED)
 		goto skiptest;
 
 	err = alg_test(param->driver, param->alg, type, NCRYPTO_ALG_TESTED);
@@ -1374,6 +1374,7 @@ static int cryptomgr_schedule_test(struct ncrypto_alg *alg)
 {
 	struct task_struct *thread;
 	struct crypto_test_param *param;
+	u32 type;
 
 	if (!try_module_get(THIS_MODULE))
 		goto err;
@@ -1384,7 +1385,20 @@ static int cryptomgr_schedule_test(struct ncrypto_alg *alg)
 
 	memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver));
 	memcpy(param->alg, alg->cra_name, sizeof(param->alg));
-	param->type = alg->cra_flags;
+	type = alg->cra_flags;
+
+	/* This piece of crap needs to disappear into per-type test hooks. */
+	if ((!((type ^ NCRYPTO_ALG_TYPE_BLKCIPHER) &
+	       NCRYPTO_ALG_TYPE_BLKCIPHER_MASK) &&
+	     !(type & NCRYPTO_ALG_GENIV) &&
+	     ((alg->cra_flags & NCRYPTO_ALG_TYPE_MASK) ==
+	      NCRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+					   alg->cra_ablkcipher.ivsize)) ||
+	    (!((type ^ NCRYPTO_ALG_TYPE_AEAD) & NCRYPTO_ALG_TYPE_MASK) &&
+	     alg->cra_type == &crypto_nivaead_type && alg->cra_aead.ivsize))
+		type |= NCRYPTO_ALG_TESTED;
+
+	param->type = type;
 
 	thread = kthread_run(cryptomgr_test, param, "cryptomgr_test");
 	if (IS_ERR(thread))