crypto: tcrypt - Do not exit on success in fips mode

At present, the tcrypt module always exits with an -EAGAIN upon
successfully completing all the tests its been asked to run. In fips
mode, integrity checking is done by running all self-tests from the
initrd, and its much simpler to check the ret from modprobe for
success than to scrape dmesg and/or /proc/crypto. Simply stay
loaded, giving modprobe a retval of 0, if self-tests all pass and
we're in fips mode.

A side-effect of tracking success/failure for fips mode is that in
non-fips mode, self-test failures will return the actual failure
return codes, rather than always returning -EAGAIN, which seems more
correct anyway.

The tcrypt_test() portion of the patch is dependent on my earlier
pair of patches that skip non-fips algs in fips mode, at least to
achieve the fully intended behavior.

Nb: testing this patch against the cryptodev tree revealed a test
failure for sha384, which I have yet to look into...

Signed-off-by: Jarod Wilson <jarod@redhat.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Jarod Wilson 2009-05-27 15:10:21 +10:00 committed by Herbert Xu
parent 3ce858cb04
commit 4e033a6bc7

View file

@ -27,6 +27,7 @@
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "tcrypt.h" #include "tcrypt.h"
#include "internal.h"
/* /*
* Need slab memory for testing (size in number of pages). * Need slab memory for testing (size in number of pages).
@ -468,248 +469,255 @@ static void test_available(void)
static inline int tcrypt_test(const char *alg) static inline int tcrypt_test(const char *alg)
{ {
return alg_test(alg, alg, 0, 0); int ret;
ret = alg_test(alg, alg, 0, 0);
/* non-fips algs return -EINVAL in fips mode */
if (fips_enabled && ret == -EINVAL)
ret = 0;
return ret;
} }
static void do_test(int m) static int do_test(int m)
{ {
int i; int i;
int ret = 0;
switch (m) { switch (m) {
case 0: case 0:
for (i = 1; i < 200; i++) for (i = 1; i < 200; i++)
do_test(i); ret += do_test(i);
break; break;
case 1: case 1:
tcrypt_test("md5"); ret += tcrypt_test("md5");
break; break;
case 2: case 2:
tcrypt_test("sha1"); ret += tcrypt_test("sha1");
break; break;
case 3: case 3:
tcrypt_test("ecb(des)"); ret += tcrypt_test("ecb(des)");
tcrypt_test("cbc(des)"); ret += tcrypt_test("cbc(des)");
break; break;
case 4: case 4:
tcrypt_test("ecb(des3_ede)"); ret += tcrypt_test("ecb(des3_ede)");
tcrypt_test("cbc(des3_ede)"); ret += tcrypt_test("cbc(des3_ede)");
break; break;
case 5: case 5:
tcrypt_test("md4"); ret += tcrypt_test("md4");
break; break;
case 6: case 6:
tcrypt_test("sha256"); ret += tcrypt_test("sha256");
break; break;
case 7: case 7:
tcrypt_test("ecb(blowfish)"); ret += tcrypt_test("ecb(blowfish)");
tcrypt_test("cbc(blowfish)"); ret += tcrypt_test("cbc(blowfish)");
break; break;
case 8: case 8:
tcrypt_test("ecb(twofish)"); ret += tcrypt_test("ecb(twofish)");
tcrypt_test("cbc(twofish)"); ret += tcrypt_test("cbc(twofish)");
break; break;
case 9: case 9:
tcrypt_test("ecb(serpent)"); ret += tcrypt_test("ecb(serpent)");
break; break;
case 10: case 10:
tcrypt_test("ecb(aes)"); ret += tcrypt_test("ecb(aes)");
tcrypt_test("cbc(aes)"); ret += tcrypt_test("cbc(aes)");
tcrypt_test("lrw(aes)"); ret += tcrypt_test("lrw(aes)");
tcrypt_test("xts(aes)"); ret += tcrypt_test("xts(aes)");
tcrypt_test("ctr(aes)"); ret += tcrypt_test("ctr(aes)");
tcrypt_test("rfc3686(ctr(aes))"); ret += tcrypt_test("rfc3686(ctr(aes))");
break; break;
case 11: case 11:
tcrypt_test("sha384"); ret += tcrypt_test("sha384");
break; break;
case 12: case 12:
tcrypt_test("sha512"); ret += tcrypt_test("sha512");
break; break;
case 13: case 13:
tcrypt_test("deflate"); ret += tcrypt_test("deflate");
break; break;
case 14: case 14:
tcrypt_test("ecb(cast5)"); ret += tcrypt_test("ecb(cast5)");
break; break;
case 15: case 15:
tcrypt_test("ecb(cast6)"); ret += tcrypt_test("ecb(cast6)");
break; break;
case 16: case 16:
tcrypt_test("ecb(arc4)"); ret += tcrypt_test("ecb(arc4)");
break; break;
case 17: case 17:
tcrypt_test("michael_mic"); ret += tcrypt_test("michael_mic");
break; break;
case 18: case 18:
tcrypt_test("crc32c"); ret += tcrypt_test("crc32c");
break; break;
case 19: case 19:
tcrypt_test("ecb(tea)"); ret += tcrypt_test("ecb(tea)");
break; break;
case 20: case 20:
tcrypt_test("ecb(xtea)"); ret += tcrypt_test("ecb(xtea)");
break; break;
case 21: case 21:
tcrypt_test("ecb(khazad)"); ret += tcrypt_test("ecb(khazad)");
break; break;
case 22: case 22:
tcrypt_test("wp512"); ret += tcrypt_test("wp512");
break; break;
case 23: case 23:
tcrypt_test("wp384"); ret += tcrypt_test("wp384");
break; break;
case 24: case 24:
tcrypt_test("wp256"); ret += tcrypt_test("wp256");
break; break;
case 25: case 25:
tcrypt_test("ecb(tnepres)"); ret += tcrypt_test("ecb(tnepres)");
break; break;
case 26: case 26:
tcrypt_test("ecb(anubis)"); ret += tcrypt_test("ecb(anubis)");
tcrypt_test("cbc(anubis)"); ret += tcrypt_test("cbc(anubis)");
break; break;
case 27: case 27:
tcrypt_test("tgr192"); ret += tcrypt_test("tgr192");
break; break;
case 28: case 28:
tcrypt_test("tgr160"); ret += tcrypt_test("tgr160");
break; break;
case 29: case 29:
tcrypt_test("tgr128"); ret += tcrypt_test("tgr128");
break; break;
case 30: case 30:
tcrypt_test("ecb(xeta)"); ret += tcrypt_test("ecb(xeta)");
break; break;
case 31: case 31:
tcrypt_test("pcbc(fcrypt)"); ret += tcrypt_test("pcbc(fcrypt)");
break; break;
case 32: case 32:
tcrypt_test("ecb(camellia)"); ret += tcrypt_test("ecb(camellia)");
tcrypt_test("cbc(camellia)"); ret += tcrypt_test("cbc(camellia)");
break; break;
case 33: case 33:
tcrypt_test("sha224"); ret += tcrypt_test("sha224");
break; break;
case 34: case 34:
tcrypt_test("salsa20"); ret += tcrypt_test("salsa20");
break; break;
case 35: case 35:
tcrypt_test("gcm(aes)"); ret += tcrypt_test("gcm(aes)");
break; break;
case 36: case 36:
tcrypt_test("lzo"); ret += tcrypt_test("lzo");
break; break;
case 37: case 37:
tcrypt_test("ccm(aes)"); ret += tcrypt_test("ccm(aes)");
break; break;
case 38: case 38:
tcrypt_test("cts(cbc(aes))"); ret += tcrypt_test("cts(cbc(aes))");
break; break;
case 39: case 39:
tcrypt_test("rmd128"); ret += tcrypt_test("rmd128");
break; break;
case 40: case 40:
tcrypt_test("rmd160"); ret += tcrypt_test("rmd160");
break; break;
case 41: case 41:
tcrypt_test("rmd256"); ret += tcrypt_test("rmd256");
break; break;
case 42: case 42:
tcrypt_test("rmd320"); ret += tcrypt_test("rmd320");
break; break;
case 43: case 43:
tcrypt_test("ecb(seed)"); ret += tcrypt_test("ecb(seed)");
break; break;
case 44: case 44:
tcrypt_test("zlib"); ret += tcrypt_test("zlib");
break; break;
case 45: case 45:
tcrypt_test("rfc4309(ccm(aes))"); ret += tcrypt_test("rfc4309(ccm(aes))");
break; break;
case 100: case 100:
tcrypt_test("hmac(md5)"); ret += tcrypt_test("hmac(md5)");
break; break;
case 101: case 101:
tcrypt_test("hmac(sha1)"); ret += tcrypt_test("hmac(sha1)");
break; break;
case 102: case 102:
tcrypt_test("hmac(sha256)"); ret += tcrypt_test("hmac(sha256)");
break; break;
case 103: case 103:
tcrypt_test("hmac(sha384)"); ret += tcrypt_test("hmac(sha384)");
break; break;
case 104: case 104:
tcrypt_test("hmac(sha512)"); ret += tcrypt_test("hmac(sha512)");
break; break;
case 105: case 105:
tcrypt_test("hmac(sha224)"); ret += tcrypt_test("hmac(sha224)");
break; break;
case 106: case 106:
tcrypt_test("xcbc(aes)"); ret += tcrypt_test("xcbc(aes)");
break; break;
case 107: case 107:
tcrypt_test("hmac(rmd128)"); ret += tcrypt_test("hmac(rmd128)");
break; break;
case 108: case 108:
tcrypt_test("hmac(rmd160)"); ret += tcrypt_test("hmac(rmd160)");
break; break;
case 150: case 150:
tcrypt_test("ansi_cprng"); ret += tcrypt_test("ansi_cprng");
break; break;
case 200: case 200:
@ -873,6 +881,8 @@ static void do_test(int m)
test_available(); test_available();
break; break;
} }
return ret;
} }
static int __init tcrypt_mod_init(void) static int __init tcrypt_mod_init(void)
@ -886,15 +896,21 @@ static int __init tcrypt_mod_init(void)
goto err_free_tv; goto err_free_tv;
} }
do_test(mode); err = do_test(mode);
if (err) {
printk(KERN_ERR "tcrypt: one or more tests failed!\n");
goto err_free_tv;
}
/* We intentionaly return -EAGAIN to prevent keeping /* We intentionaly return -EAGAIN to prevent keeping the module,
* the module. It does all its work from init() * unless we're running in fips mode. It does all its work from
* and doesn't offer any runtime functionality * init() and doesn't offer any runtime functionality, but in
* the fips case, checking for a successful load is helpful.
* => we don't need it in the memory, do we? * => we don't need it in the memory, do we?
* -- mludvig * -- mludvig
*/ */
err = -EAGAIN; if (!fips_enabled)
err = -EAGAIN;
err_free_tv: err_free_tv:
for (i = 0; i < TVMEMSIZE && tvmem[i]; i++) for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)