X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;ds=inline;f=crypto%2Ftestmgr.c;h=c494d7610be14336262e126434cde7b8b530fae4;hb=7a65004bbaa6a21a0438aac9c64814e46084dc3f;hp=e76af78d2fa02d7e9177a413f38b65347052d84e;hpb=29ecd4ab3d3aa8bb231361937165dfbbbc534e9a;p=safe%2Fjmp%2Flinux-2.6 diff --git a/crypto/testmgr.c b/crypto/testmgr.c index e76af78..c494d76 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -94,6 +94,7 @@ struct alg_test_desc { const char *alg; int (*test)(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask); + int fips_allowed; /* set if alg is allowed in fips mode */ union { struct aead_test_suite aead; @@ -107,9 +108,6 @@ struct alg_test_desc { static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; -static char *xbuf[XBUFSIZE]; -static char *axbuf[XBUFSIZE]; - static void hexdump(unsigned char *buf, unsigned int len) { print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, @@ -128,6 +126,33 @@ static void tcrypt_complete(struct crypto_async_request *req, int err) complete(&res->completion); } +static int testmgr_alloc_buf(char *buf[XBUFSIZE]) +{ + int i; + + for (i = 0; i < XBUFSIZE; i++) { + buf[i] = (void *)__get_free_page(GFP_KERNEL); + if (!buf[i]) + goto err_free_buf; + } + + return 0; + +err_free_buf: + while (i-- > 0) + free_page((unsigned long)buf[i]); + + return -ENOMEM; +} + +static void testmgr_free_buf(char *buf[XBUFSIZE]) +{ + int i; + + for (i = 0; i < XBUFSIZE; i++) + free_page((unsigned long)buf[i]); +} + static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, unsigned int tcount) { @@ -137,8 +162,12 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, char result[64]; struct ahash_request *req; struct tcrypt_result tresult; - int ret; void *hash_buff; + char *xbuf[XBUFSIZE]; + int ret = -ENOMEM; + + if (testmgr_alloc_buf(xbuf)) + goto out_nobuf; init_completion(&tresult.completion); @@ -146,13 +175,17 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, if (!req) { printk(KERN_ERR "alg: hash: Failed to allocate request for " "%s\n", algo); - ret = -ENOMEM; goto out_noreq; } ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &tresult); + j = 0; for (i = 0; i < tcount; i++) { + if (template[i].np) + continue; + + j++; memset(result, 0, 64); hash_buff = xbuf[0]; @@ -166,7 +199,7 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, template[i].ksize); if (ret) { printk(KERN_ERR "alg: hash: setkey failed on " - "test %d for %s: ret=%d\n", i + 1, algo, + "test %d for %s: ret=%d\n", j, algo, -ret); goto out; } @@ -188,14 +221,14 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, /* fall through */ default: printk(KERN_ERR "alg: hash: digest failed on test %d " - "for %s: ret=%d\n", i + 1, algo, -ret); + "for %s: ret=%d\n", j, algo, -ret); goto out; } if (memcmp(result, template[i].digest, crypto_ahash_digestsize(tfm))) { printk(KERN_ERR "alg: hash: Test %d failed for %s\n", - i + 1, algo); + j, algo); hexdump(result, crypto_ahash_digestsize(tfm)); ret = -EINVAL; goto out; @@ -210,7 +243,11 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, temp = 0; sg_init_table(sg, template[i].np); + ret = -EINVAL; for (k = 0; k < template[i].np; k++) { + if (WARN_ON(offset_in_page(IDX[k]) + + template[i].tap[k] > PAGE_SIZE)) + goto out; sg_set_buf(&sg[k], memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]), @@ -272,6 +309,8 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, out: ahash_request_free(req); out_noreq: + testmgr_free_buf(xbuf); +out_nobuf: return ret; } @@ -280,7 +319,7 @@ static int test_aead(struct crypto_aead *tfm, int enc, { const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); unsigned int i, j, k, n, temp; - int ret = 0; + int ret = -ENOMEM; char *q; char *key; struct aead_request *req; @@ -292,6 +331,13 @@ static int test_aead(struct crypto_aead *tfm, int enc, void *input; void *assoc; char iv[MAX_IVLEN]; + char *xbuf[XBUFSIZE]; + char *axbuf[XBUFSIZE]; + + if (testmgr_alloc_buf(xbuf)) + goto out_noxbuf; + if (testmgr_alloc_buf(axbuf)) + goto out_noaxbuf; if (enc == ENCRYPT) e = "encryption"; @@ -304,7 +350,6 @@ static int test_aead(struct crypto_aead *tfm, int enc, if (!req) { printk(KERN_ERR "alg: aead: Failed to allocate request for " "%s\n", algo); - ret = -ENOMEM; goto out; } @@ -321,6 +366,11 @@ static int test_aead(struct crypto_aead *tfm, int enc, input = xbuf[0]; assoc = axbuf[0]; + ret = -EINVAL; + if (WARN_ON(template[i].ilen > PAGE_SIZE || + template[i].alen > PAGE_SIZE)) + goto out; + memcpy(input, template[i].input, template[i].ilen); memcpy(assoc, template[i].assoc, template[i].alen); if (template[i].iv) @@ -480,7 +530,11 @@ static int test_aead(struct crypto_aead *tfm, int enc, } sg_init_table(asg, template[i].anp); + ret = -EINVAL; for (k = 0, temp = 0; k < template[i].anp; k++) { + if (WARN_ON(offset_in_page(IDX[k]) + + template[i].atap[k] > PAGE_SIZE)) + goto out; sg_set_buf(&asg[k], memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]), @@ -581,6 +635,10 @@ static int test_aead(struct crypto_aead *tfm, int enc, out: aead_request_free(req); + testmgr_free_buf(axbuf); +out_noaxbuf: + testmgr_free_buf(xbuf); +out_noxbuf: return ret; } @@ -589,10 +647,14 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, { const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); unsigned int i, j, k; - int ret; char *q; const char *e; void *data; + char *xbuf[XBUFSIZE]; + int ret = -ENOMEM; + + if (testmgr_alloc_buf(xbuf)) + goto out_nobuf; if (enc == ENCRYPT) e = "encryption"; @@ -606,6 +668,10 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, j++; + ret = -EINVAL; + if (WARN_ON(template[i].ilen > PAGE_SIZE)) + goto out; + data = xbuf[0]; memcpy(data, template[i].input, template[i].ilen); @@ -646,6 +712,8 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, ret = 0; out: + testmgr_free_buf(xbuf); +out_nobuf: return ret; } @@ -655,7 +723,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, const char *algo = crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); unsigned int i, j, k, n, temp; - int ret; char *q; struct ablkcipher_request *req; struct scatterlist sg[8]; @@ -663,6 +730,11 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, struct tcrypt_result result; void *data; char iv[MAX_IVLEN]; + char *xbuf[XBUFSIZE]; + int ret = -ENOMEM; + + if (testmgr_alloc_buf(xbuf)) + goto out_nobuf; if (enc == ENCRYPT) e = "encryption"; @@ -675,7 +747,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, if (!req) { printk(KERN_ERR "alg: skcipher: Failed to allocate request " "for %s\n", algo); - ret = -ENOMEM; goto out; } @@ -692,6 +763,10 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, if (!(template[i].np)) { j++; + ret = -EINVAL; + if (WARN_ON(template[i].ilen > PAGE_SIZE)) + goto out; + data = xbuf[0]; memcpy(data, template[i].input, template[i].ilen); @@ -860,6 +935,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, out: ablkcipher_request_free(req); + testmgr_free_buf(xbuf); +out_nobuf: return ret; } @@ -951,24 +1028,25 @@ static int test_pcomp(struct crypto_pcomp *tfm, const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); unsigned int i; char result[COMP_BUF_SIZE]; - int error; + int res; for (i = 0; i < ctcount; i++) { struct comp_request req; + unsigned int produced = 0; - error = crypto_compress_setup(tfm, ctemplate[i].params, - ctemplate[i].paramsize); - if (error) { + res = crypto_compress_setup(tfm, ctemplate[i].params, + ctemplate[i].paramsize); + if (res) { pr_err("alg: pcomp: compression setup failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } - error = crypto_compress_init(tfm); - if (error) { + res = crypto_compress_init(tfm); + if (res) { pr_err("alg: pcomp: compression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } memset(result, 0, sizeof(result)); @@ -978,32 +1056,37 @@ static int test_pcomp(struct crypto_pcomp *tfm, req.next_out = result; req.avail_out = ctemplate[i].outlen / 2; - error = crypto_compress_update(tfm, &req); - if (error && (error != -EAGAIN || req.avail_in)) { + res = crypto_compress_update(tfm, &req); + if (res < 0 && (res != -EAGAIN || req.avail_in)) { pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } + if (res > 0) + produced += res; /* Add remaining input data */ req.avail_in += (ctemplate[i].inlen + 1) / 2; - error = crypto_compress_update(tfm, &req); - if (error && (error != -EAGAIN || req.avail_in)) { + res = crypto_compress_update(tfm, &req); + if (res < 0 && (res != -EAGAIN || req.avail_in)) { pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } + if (res > 0) + produced += res; /* Provide remaining output space */ req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; - error = crypto_compress_final(tfm, &req); - if (error) { + res = crypto_compress_final(tfm, &req); + if (res < 0) { pr_err("alg: pcomp: compression final failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } + produced += res; if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { pr_err("alg: comp: Compression test %d failed for %s: " @@ -1013,6 +1096,13 @@ static int test_pcomp(struct crypto_pcomp *tfm, return -EINVAL; } + if (produced != ctemplate[i].outlen) { + pr_err("alg: comp: Compression test %d failed for %s: " + "returned len = %u (expected %d)\n", i + 1, + algo, produced, ctemplate[i].outlen); + return -EINVAL; + } + if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { pr_err("alg: pcomp: Compression test %d failed for " "%s\n", i + 1, algo); @@ -1023,21 +1113,21 @@ static int test_pcomp(struct crypto_pcomp *tfm, for (i = 0; i < dtcount; i++) { struct comp_request req; + unsigned int produced = 0; - error = crypto_decompress_setup(tfm, dtemplate[i].params, - dtemplate[i].paramsize); - if (error) { + res = crypto_decompress_setup(tfm, dtemplate[i].params, + dtemplate[i].paramsize); + if (res) { pr_err("alg: pcomp: decompression setup failed on " - "test %d for %s: error=%d\n", i + 1, algo, - error); - return error; + "test %d for %s: error=%d\n", i + 1, algo, res); + return res; } - error = crypto_decompress_init(tfm); - if (error) { + res = crypto_decompress_init(tfm); + if (res) { pr_err("alg: pcomp: decompression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, error); - return error; + "%d for %s: error=%d\n", i + 1, algo, res); + return res; } memset(result, 0, sizeof(result)); @@ -1047,35 +1137,38 @@ static int test_pcomp(struct crypto_pcomp *tfm, req.next_out = result; req.avail_out = dtemplate[i].outlen / 2; - error = crypto_decompress_update(tfm, &req); - if (error && (error != -EAGAIN || req.avail_in)) { + res = crypto_decompress_update(tfm, &req); + if (res < 0 && (res != -EAGAIN || req.avail_in)) { pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, - error); - return error; + "test %d for %s: error=%d\n", i + 1, algo, res); + return res; } + if (res > 0) + produced += res; /* Add remaining input data */ req.avail_in += (dtemplate[i].inlen + 1) / 2; - error = crypto_decompress_update(tfm, &req); - if (error && (error != -EAGAIN || req.avail_in)) { + res = crypto_decompress_update(tfm, &req); + if (res < 0 && (res != -EAGAIN || req.avail_in)) { pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, - error); - return error; + "test %d for %s: error=%d\n", i + 1, algo, res); + return res; } + if (res > 0) + produced += res; /* Provide remaining output space */ req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; - error = crypto_decompress_final(tfm, &req); - if (error && (error != -EAGAIN || req.avail_in)) { + res = crypto_decompress_final(tfm, &req); + if (res < 0 && (res != -EAGAIN || req.avail_in)) { pr_err("alg: pcomp: decompression final failed on " - "test %d for %s: error=%d\n", i + 1, algo, - error); - return error; + "test %d for %s: error=%d\n", i + 1, algo, res); + return res; } + if (res > 0) + produced += res; if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { pr_err("alg: comp: Decompression test %d failed for " @@ -1085,6 +1178,13 @@ static int test_pcomp(struct crypto_pcomp *tfm, return -EINVAL; } + if (produced != dtemplate[i].outlen) { + pr_err("alg: comp: Decompression test %d failed for " + "%s: returned len = %u (expected %d)\n", i + 1, + algo, produced, dtemplate[i].outlen); + return -EINVAL; + } + if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { pr_err("alg: pcomp: Decompression test %d failed for " "%s\n", i + 1, algo); @@ -1101,7 +1201,7 @@ static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template, unsigned int tcount) { const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); - int err, i, j, seedsize; + int err = 0, i, j, seedsize; u8 *seed; char result[32]; @@ -1377,11 +1477,57 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, return err; } +static int alg_test_null(const struct alg_test_desc *desc, + const char *driver, u32 type, u32 mask) +{ + return 0; +} + /* Please keep this list sorted by algorithm name. */ static const struct alg_test_desc alg_test_descs[] = { { + .alg = "__driver-cbc-aes-aesni", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "__driver-ecb-aes-aesni", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "__ghash-pclmulqdqni", + .test = alg_test_null, + .suite = { + .hash = { + .vecs = NULL, + .count = 0 + } + } + }, { .alg = "ansi_cprng", .test = alg_test_cprng, + .fips_allowed = 1, .suite = { .cprng = { .vecs = ansi_cprng_aes_tv_template, @@ -1391,6 +1537,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "cbc(aes)", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { @@ -1466,6 +1613,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "cbc(des3_ede)", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { @@ -1496,6 +1644,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ccm(aes)", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -1511,6 +1660,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "crc32c", .test = alg_test_crc32c, + .fips_allowed = 1, .suite = { .hash = { .vecs = crc32c_tv_template, @@ -1518,6 +1668,46 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "cryptd(__driver-ecb-aes-aesni)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "cryptd(__ghash-pclmulqdqni)", + .test = alg_test_null, + .suite = { + .hash = { + .vecs = NULL, + .count = 0 + } + } + }, { + .alg = "ctr(aes)", + .test = alg_test_skcipher, + .fips_allowed = 1, + .suite = { + .cipher = { + .enc = { + .vecs = aes_ctr_enc_tv_template, + .count = AES_CTR_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_ctr_dec_tv_template, + .count = AES_CTR_DEC_TEST_VECTORS + } + } + } + }, { .alg = "cts(cbc(aes))", .test = alg_test_skcipher, .suite = { @@ -1548,8 +1738,24 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "ecb(__aes-aesni)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { .alg = "ecb(aes)", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { @@ -1655,6 +1861,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ecb(des)", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { @@ -1670,6 +1877,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ecb(des3_ede)", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { @@ -1805,6 +2013,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "gcm(aes)", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -1818,6 +2027,15 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "ghash", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = ghash_tv_template, + .count = GHASH_TEST_VECTORS + } + } + }, { .alg = "hmac(md5)", .test = alg_test_hash, .suite = { @@ -1847,6 +2065,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "hmac(sha1)", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = hmac_sha1_tv_template, @@ -1856,6 +2075,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "hmac(sha224)", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = hmac_sha224_tv_template, @@ -1865,6 +2085,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "hmac(sha256)", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = hmac_sha256_tv_template, @@ -1874,6 +2095,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "hmac(sha384)", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = hmac_sha384_tv_template, @@ -1883,6 +2105,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "hmac(sha512)", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = hmac_sha512_tv_template, @@ -1964,21 +2187,23 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "rfc3686(ctr(aes))", .test = alg_test_skcipher, + .fips_allowed = 1, .suite = { .cipher = { .enc = { - .vecs = aes_ctr_enc_tv_template, - .count = AES_CTR_ENC_TEST_VECTORS + .vecs = aes_ctr_rfc3686_enc_tv_template, + .count = AES_CTR_3686_ENC_TEST_VECTORS }, .dec = { - .vecs = aes_ctr_dec_tv_template, - .count = AES_CTR_DEC_TEST_VECTORS + .vecs = aes_ctr_rfc3686_dec_tv_template, + .count = AES_CTR_3686_DEC_TEST_VECTORS } } } }, { .alg = "rfc4309(ccm(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2041,6 +2266,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "sha1", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = sha1_tv_template, @@ -2050,6 +2276,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "sha224", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = sha224_tv_template, @@ -2059,6 +2286,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "sha256", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = sha256_tv_template, @@ -2068,6 +2296,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "sha384", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = sha384_tv_template, @@ -2077,6 +2306,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "sha512", .test = alg_test_hash, + .fips_allowed = 1, .suite = { .hash = { .vecs = sha512_tv_template, @@ -2111,6 +2341,15 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "vmac(aes)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = aes_vmac128_tv_template, + .count = VMAC_AES_TEST_VECTORS + } + } + }, { .alg = "wp256", .test = alg_test_hash, .suite = { @@ -2207,6 +2446,7 @@ static int alg_find_test(const char *alg) int alg_test(const char *driver, const char *alg, u32 type, u32 mask) { int i; + int j; int rc; if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { @@ -2220,16 +2460,30 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) if (i < 0) goto notest; + if (fips_enabled && !alg_test_descs[i].fips_allowed) + goto non_fips_alg; + rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); goto test_done; } i = alg_find_test(alg); - if (i < 0) + j = alg_find_test(driver); + if (i < 0 && j < 0) goto notest; - rc = alg_test_descs[i].test(alg_test_descs + i, driver, - type, mask); + if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) || + (j >= 0 && !alg_test_descs[j].fips_allowed))) + goto non_fips_alg; + + rc = 0; + if (i >= 0) + rc |= alg_test_descs[i].test(alg_test_descs + i, driver, + type, mask); + if (j >= 0) + rc |= alg_test_descs[j].test(alg_test_descs + j, driver, + type, mask); + test_done: if (fips_enabled && rc) panic("%s: %s alg self test failed in fips mode!\n", driver, alg); @@ -2243,43 +2497,7 @@ test_done: notest: printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); return 0; +non_fips_alg: + return -EINVAL; } EXPORT_SYMBOL_GPL(alg_test); - -int __init testmgr_init(void) -{ - int i; - - for (i = 0; i < XBUFSIZE; i++) { - xbuf[i] = (void *)__get_free_page(GFP_KERNEL); - if (!xbuf[i]) - goto err_free_xbuf; - } - - for (i = 0; i < XBUFSIZE; i++) { - axbuf[i] = (void *)__get_free_page(GFP_KERNEL); - if (!axbuf[i]) - goto err_free_axbuf; - } - - return 0; - -err_free_axbuf: - for (i = 0; i < XBUFSIZE && axbuf[i]; i++) - free_page((unsigned long)axbuf[i]); -err_free_xbuf: - for (i = 0; i < XBUFSIZE && xbuf[i]; i++) - free_page((unsigned long)xbuf[i]); - - return -ENOMEM; -} - -void testmgr_exit(void) -{ - int i; - - for (i = 0; i < XBUFSIZE; i++) - free_page((unsigned long)axbuf[i]); - for (i = 0; i < XBUFSIZE; i++) - free_page((unsigned long)xbuf[i]); -}