From: Herbert Xu <herbert@gondor.apana.org.au> Date: Wed, 27 Aug 2008 10:18:34 +1000 Subject: [CRYPTO] tcrypt - Add alg_test interface Message-id: E1KY8k6-0002HQ-00@gondolin.me.apana.org.au O-Subject: [PATCH 12/19] crypto: tcrypt - Add alg_test interface Bugzilla: 446522 RHEL5 bugzilla #446522 crypto: tcrypt - Add alg_test interface This patch creates a new interface algorithm testing. A test can be requested for a particular implementation of an algorithm. This is achieved by taking both the name of the algorithm and that of the implementation. The all-inclusive test has also been rewritten to no longer require a duplicate listing of all algorithms with tests. In that process a number of missing tests have also been discovered and rectified. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index ef38458..5f03f3d 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -62,6 +62,45 @@ struct tcrypt_result { int err; }; +struct aead_test_suite { + struct { + struct aead_testvec *vecs; + unsigned int count; + } enc, dec; +}; + +struct cipher_test_suite { + struct { + struct cipher_testvec *vecs; + unsigned int count; + } enc, dec; +}; + +struct comp_test_suite { + struct { + struct comp_testvec *vecs; + unsigned int count; + } comp, decomp; +}; + +struct hash_test_suite { + struct hash_testvec *vecs; + unsigned int count; +}; + +struct alg_test_desc { + const char *alg; + int (*test)(const struct alg_test_desc *desc, const char *driver, + u32 type, u32 mask); + + union { + struct aead_test_suite aead; + struct cipher_test_suite cipher; + struct comp_test_suite comp; + struct hash_test_suite hash; + } suite; +}; + static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; /* @@ -100,7 +139,7 @@ static void tcrypt_complete(struct crypto_async_request *req, int err) complete(&res->completion); } -static int test_hash(char *algo, struct hash_testvec *template, +static int test_hash(const char *algo, struct hash_testvec *template, unsigned int tcount) { unsigned int i, j, k, temp; @@ -112,8 +151,8 @@ static int test_hash(char *algo, struct hash_testvec *template, tfm = crypto_alloc_tfm(algo, 0); if (tfm == NULL) { - printk(KERN_ERR "alg: digest: Failed to load transform for " - "%s\n", algo); + printk(KERN_ERR "alg: digest: Failed to load transform for %s\n", + algo); return -ENOENT; } @@ -151,20 +190,21 @@ static int test_hash(char *algo, struct hash_testvec *template, temp = 0; for (k = 0; k < template[i].np; k++) { - memcpy(&xbuf[IDX[k]], - template[i].plaintext + temp, - template[i].tap[k]); + sg_set_buf(&sg[k], + memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + + offset_in_page(IDX[k]), + template[i].plaintext + temp, + template[i].tap[k]), + template[i].tap[k]); temp += template[i].tap[k]; - sg_set_buf(&sg[k], &xbuf[IDX[k]], - template[i].tap[k]); } crypto_digest_digest(tfm, sg, template[i].np, result); if (memcmp(result, template[i].digest, crypto_tfm_alg_digestsize(tfm))) { - printk(KERN_ERR "alg: digest: Chunking test " - "%d failed for %s\n", j, algo); + printk(KERN_ERR "alg: digest: Chunking test %d " + "failed for %s\n", j, algo); hexdump(result, crypto_tfm_alg_digestsize(tfm)); ret = -EINVAL; goto out; @@ -172,29 +212,24 @@ static int test_hash(char *algo, struct hash_testvec *template, } } + ret = 0; + out: crypto_free_tfm(tfm); return ret; } -static int test_nhash(char *algo, struct hash_testvec *template, +static int test_nhash(struct crypto_hash *tfm, struct hash_testvec *template, unsigned int tcount) { + const char *algo = ncrypto_tfm_alg_driver_name(crypto_hash_tfm(tfm)); unsigned int i, j, k, temp; struct scatterlist sg[8]; char result[64]; - struct crypto_hash *tfm; struct hash_desc desc; int ret; void *hash_buff; - tfm = crypto_alloc_hash(algo, 0, NCRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: hash: Failed to load transform for %s: " - "%ld\n", algo, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - desc.tfm = tfm; desc.flags = 0; @@ -285,18 +320,19 @@ static int test_nhash(char *algo, struct hash_testvec *template, } } + ret = 0; + out: - crypto_free_hash(tfm); return ret; } -static int test_aead(char *algo, int enc, struct aead_testvec *template, - unsigned int tcount) +static int test_aead(struct crypto_aead *tfm, int enc, + struct aead_testvec *template, unsigned int tcount) { + const char *algo = ncrypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); unsigned int i, j, k, n, temp; int ret = 0; char *q; - struct crypto_aead *tfm; char *key; struct aead_request *req; struct scatterlist sg[8]; @@ -315,14 +351,6 @@ static int test_aead(char *algo, int enc, struct aead_testvec *template, init_completion(&result.completion); - tfm = crypto_alloc_aead(algo, 0, 0); - - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: aead: Failed to load transform for %s: " - "%ld\n", algo, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - req = aead_request_alloc(tfm, GFP_KERNEL); if (!req) { printk(KERN_ERR "alg: aead: Failed to allocate request for " @@ -578,18 +606,18 @@ static int test_aead(char *algo, int enc, struct aead_testvec *template, ret = 0; out: - crypto_free_aead(tfm); aead_request_free(req); return ret; } -static int test_cipher(char *algo, int enc, +static int test_cipher(struct crypto_ablkcipher *tfm, int enc, struct cipher_testvec *template, unsigned int tcount) { + const char *algo = + ncrypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); unsigned int i, j, k, n, temp; int ret; char *q; - struct crypto_ablkcipher *tfm; struct ablkcipher_request *req; struct scatterlist sg[8]; const char *e; @@ -603,13 +631,6 @@ static int test_cipher(char *algo, int enc, e = "decryption"; init_completion(&result.completion); - tfm = crypto_alloc_ablkcipher(algo, 0, 0); - - if (IS_ERR(tfm)) { - printk(KERN_ERR "alg: cipher: Failed to load transform for " - "%s: %ld\n", algo, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } req = ablkcipher_request_alloc(tfm, GFP_KERNEL); if (!req) { @@ -801,7 +822,6 @@ static int test_cipher(char *algo, int enc, ret = 0; out: - crypto_free_ablkcipher(tfm); ablkcipher_request_free(req); return ret; } @@ -880,7 +900,7 @@ out: static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 }; -static void test_cipher_speed(char *algo, int enc, unsigned int sec, +static void test_cipher_speed(const char *algo, int enc, unsigned int sec, struct cipher_testvec *template, unsigned int tcount, u8 *keysize) { @@ -1045,7 +1065,7 @@ static void test_digest_cycles(struct crypto_tfm *tfm, struct scatterlist *sg, return; } -static void test_digest_speed(char *algo, unsigned int sec, +static void test_digest_speed(const char *algo, unsigned int sec, struct digest_speed *speed) { struct scatterlist sg[TVMEMSIZE]; @@ -1272,261 +1292,721 @@ static void test_available(void) } } -static void do_test(void) +static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, + u32 type, u32 mask) { - switch (mode) { + struct crypto_aead *tfm; + int err = 0; - case 0: - test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); - - test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); - - //DES - test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template, - DES_ENC_TEST_VECTORS); - test_cipher("ecb(des)", DECRYPT, des_dec_tv_template, - DES_DEC_TEST_VECTORS); - test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template, - DES_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template, - DES_CBC_DEC_TEST_VECTORS); - - //DES3_EDE - test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template, - DES3_EDE_ENC_TEST_VECTORS); - test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template, - DES3_EDE_DEC_TEST_VECTORS); - - test_cipher("cbc(des3_ede)", ENCRYPT, - des3_ede_cbc_enc_tv_template, - DES3_EDE_CBC_ENC_TEST_VECTORS); - - test_cipher("cbc(des3_ede)", DECRYPT, - des3_ede_cbc_dec_tv_template, - DES3_EDE_CBC_DEC_TEST_VECTORS); - - test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); - - test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); - - //BLOWFISH - test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template, - BF_ENC_TEST_VECTORS); - test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template, - BF_DEC_TEST_VECTORS); - test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template, - BF_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template, - BF_CBC_DEC_TEST_VECTORS); - - //TWOFISH - test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template, - TF_ENC_TEST_VECTORS); - test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template, - TF_DEC_TEST_VECTORS); - test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template, - TF_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template, - TF_CBC_DEC_TEST_VECTORS); - - //SERPENT - test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template, - SERPENT_ENC_TEST_VECTORS); - test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template, - SERPENT_DEC_TEST_VECTORS); - - //TNEPRES - test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template, - TNEPRES_ENC_TEST_VECTORS); - test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template, - TNEPRES_DEC_TEST_VECTORS); - - //AES - test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template, - AES_ENC_TEST_VECTORS); - test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template, - AES_DEC_TEST_VECTORS); - test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template, - AES_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template, - AES_CBC_DEC_TEST_VECTORS); - test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template, - AES_CTR_ENC_TEST_VECTORS); - test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template, - AES_CTR_DEC_TEST_VECTORS); - test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template, - AES_CCM_ENC_TEST_VECTORS); - test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template, - AES_CCM_DEC_TEST_VECTORS); - - //CAST5 - test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template, - CAST5_ENC_TEST_VECTORS); - test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template, - CAST5_DEC_TEST_VECTORS); - - //CAST6 - test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template, - CAST6_ENC_TEST_VECTORS); - test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template, - CAST6_DEC_TEST_VECTORS); - - //ARC4 - test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template, - ARC4_ENC_TEST_VECTORS); - test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template, - ARC4_DEC_TEST_VECTORS); - - //TEA - test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template, - TEA_ENC_TEST_VECTORS); - test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template, - TEA_DEC_TEST_VECTORS); - - - //XTEA - test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template, - XTEA_ENC_TEST_VECTORS); - test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template, - XTEA_DEC_TEST_VECTORS); - - //KHAZAD - test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template, - KHAZAD_ENC_TEST_VECTORS); - test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template, - KHAZAD_DEC_TEST_VECTORS); - - //ANUBIS - test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template, - ANUBIS_ENC_TEST_VECTORS); - test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template, - ANUBIS_DEC_TEST_VECTORS); - test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template, - ANUBIS_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template, - ANUBIS_CBC_ENC_TEST_VECTORS); - - //XETA - test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template, - XETA_ENC_TEST_VECTORS); - test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template, - XETA_DEC_TEST_VECTORS); - - test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); - test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); - test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); - test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS); - test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS); - test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS); - test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); - test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); - test_deflate(); - test_crc32c(); - test_nhash("hmac(md5)", hmac_md5_tv_template, - HMAC_MD5_TEST_VECTORS); - test_nhash("hmac(sha1)", hmac_sha1_tv_template, - HMAC_SHA1_TEST_VECTORS); - test_nhash("hmac(sha256)", hmac_sha256_tv_template, - HMAC_SHA256_TEST_VECTORS); + tfm = crypto_alloc_aead(driver, type, mask); + if (IS_ERR(tfm)) { + printk(KERN_ERR "alg: aead: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } - test_hash("xcbc(aes)", aes_xcbc128_tv_template, - XCBC_AES_TEST_VECTORS); + if (desc->suite.aead.enc.vecs) { + err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs, + desc->suite.aead.enc.count); + if (err) + goto out; + } - test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); - break; + if (!err && desc->suite.aead.dec.vecs) + err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs, + desc->suite.aead.dec.count); + +out: + crypto_free_aead(tfm); + return err; +} + +static int alg_test_cipher(const struct alg_test_desc *desc, + const char *driver, u32 type, u32 mask) +{ + struct crypto_ablkcipher *tfm; + int err = 0; + + tfm = crypto_alloc_ablkcipher(driver, type, mask); + if (IS_ERR(tfm)) { + printk(KERN_ERR "alg: cipher: Failed to load transform for " + "%s: %ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + if (desc->suite.cipher.enc.vecs) { + err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs, + desc->suite.cipher.enc.count); + if (err) + goto out; + } + + if (desc->suite.cipher.dec.vecs) + err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs, + desc->suite.cipher.dec.count); + +out: + crypto_free_ablkcipher(tfm); + return err; +} + +static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, + u32 type, u32 mask) +{ + struct crypto_hash *tfm; + int err; + + tfm = crypto_alloc_hash(driver, type, mask); + if (IS_ERR(tfm)) { + printk(KERN_ERR "alg: hash: Failed to load transform for %s: " + "%ld\n", driver, PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + err = test_nhash(tfm, desc->suite.hash.vecs, desc->suite.hash.count); + + crypto_free_hash(tfm); + return err; +} + +/* Please keep this list sorted by algorithm name. */ +static const struct alg_test_desc alg_test_descs[] = { + { + .alg = "cbc(aes)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = aes_cbc_enc_tv_template, + .count = AES_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_cbc_dec_tv_template, + .count = AES_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "cbc(anubis)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = anubis_cbc_enc_tv_template, + .count = ANUBIS_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = anubis_cbc_dec_tv_template, + .count = ANUBIS_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "cbc(blowfish)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = bf_cbc_enc_tv_template, + .count = BF_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = bf_cbc_dec_tv_template, + .count = BF_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "cbc(des)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = des_cbc_enc_tv_template, + .count = DES_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = des_cbc_dec_tv_template, + .count = DES_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "cbc(des3_ede)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = des3_ede_cbc_enc_tv_template, + .count = DES3_EDE_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = des3_ede_cbc_dec_tv_template, + .count = DES3_EDE_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "cbc(twofish)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = tf_cbc_enc_tv_template, + .count = TF_CBC_ENC_TEST_VECTORS + }, + .dec = { + .vecs = tf_cbc_dec_tv_template, + .count = TF_CBC_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ccm(aes)", + .test = alg_test_aead, + .suite = { + .aead = { + .enc = { + .vecs = aes_ccm_enc_tv_template, + .count = AES_CCM_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_ccm_dec_tv_template, + .count = AES_CCM_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(aes)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = aes_enc_tv_template, + .count = AES_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_dec_tv_template, + .count = AES_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(anubis)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = anubis_enc_tv_template, + .count = ANUBIS_ENC_TEST_VECTORS + }, + .dec = { + .vecs = anubis_dec_tv_template, + .count = ANUBIS_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(arc4)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = arc4_enc_tv_template, + .count = ARC4_ENC_TEST_VECTORS + }, + .dec = { + .vecs = arc4_dec_tv_template, + .count = ARC4_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(blowfish)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = bf_enc_tv_template, + .count = BF_ENC_TEST_VECTORS + }, + .dec = { + .vecs = bf_dec_tv_template, + .count = BF_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(cast5)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = cast5_enc_tv_template, + .count = CAST5_ENC_TEST_VECTORS + }, + .dec = { + .vecs = cast5_dec_tv_template, + .count = CAST5_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(cast6)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = cast6_enc_tv_template, + .count = CAST6_ENC_TEST_VECTORS + }, + .dec = { + .vecs = cast6_dec_tv_template, + .count = CAST6_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(des)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = des_enc_tv_template, + .count = DES_ENC_TEST_VECTORS + }, + .dec = { + .vecs = des_dec_tv_template, + .count = DES_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(des3_ede)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = des3_ede_enc_tv_template, + .count = DES3_EDE_ENC_TEST_VECTORS + }, + .dec = { + .vecs = des3_ede_dec_tv_template, + .count = DES3_EDE_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(khazad)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = khazad_enc_tv_template, + .count = KHAZAD_ENC_TEST_VECTORS + }, + .dec = { + .vecs = khazad_dec_tv_template, + .count = KHAZAD_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(serpent)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = serpent_enc_tv_template, + .count = SERPENT_ENC_TEST_VECTORS + }, + .dec = { + .vecs = serpent_dec_tv_template, + .count = SERPENT_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(tea)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = tea_enc_tv_template, + .count = TEA_ENC_TEST_VECTORS + }, + .dec = { + .vecs = tea_dec_tv_template, + .count = TEA_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(tnepres)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = tnepres_enc_tv_template, + .count = TNEPRES_ENC_TEST_VECTORS + }, + .dec = { + .vecs = tnepres_dec_tv_template, + .count = TNEPRES_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(twofish)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = tf_enc_tv_template, + .count = TF_ENC_TEST_VECTORS + }, + .dec = { + .vecs = tf_dec_tv_template, + .count = TF_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(xeta)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = xeta_enc_tv_template, + .count = XETA_ENC_TEST_VECTORS + }, + .dec = { + .vecs = xeta_dec_tv_template, + .count = XETA_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "ecb(xtea)", + .test = alg_test_cipher, + .suite = { + .cipher = { + .enc = { + .vecs = xtea_enc_tv_template, + .count = XTEA_ENC_TEST_VECTORS + }, + .dec = { + .vecs = xtea_dec_tv_template, + .count = XTEA_DEC_TEST_VECTORS + } + } + } + }, { + .alg = "hmac(md5)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = hmac_md5_tv_template, + .count = HMAC_MD5_TEST_VECTORS + } + } + }, { + .alg = "hmac(sha1)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = hmac_sha1_tv_template, + .count = HMAC_SHA1_TEST_VECTORS + } + } + }, { + .alg = "hmac(sha256)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = hmac_sha256_tv_template, + .count = HMAC_SHA256_TEST_VECTORS + } + } + }, { + .alg = "rfc3686(ctr(aes))", + .test = alg_test_cipher, + .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 = "xcbc(aes)", + .test = alg_test_hash, + .suite = { + .hash = { + .vecs = aes_xcbc128_tv_template, + .count = XCBC_AES_TEST_VECTORS + } + } + } +}; + +static int alg_test(const char *driver, const char *alg, u32 type, u32 mask) +{ + int start = 0; + int end = ARRAY_SIZE(alg_test_descs); + + while (start < end) { + int i = (start + end) / 2; + int diff = strcmp(alg_test_descs[i].alg, alg); + + if (diff > 0) { + end = i; + continue; + } + + if (diff < 0) { + start = i + 1; + continue; + } + + return alg_test_descs[i].test(alg_test_descs + i, driver, + type, mask); + } + + printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); + return 0; +} + +static int alg_test_digest(const struct alg_test_desc *desc, + const char *driver, u32 type, u32 mask) +{ + return test_hash(driver, desc->suite.hash.vecs, desc->suite.hash.count); +} + +static const struct alg_test_desc digest_test_descs[] = { + { + .alg = "md4", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = md4_tv_template, + .count = MD4_TEST_VECTORS + } + } + }, { + .alg = "md5", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = md5_tv_template, + .count = MD5_TEST_VECTORS + } + } + }, { + .alg = "michael_mic", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = michael_mic_tv_template, + .count = MICHAEL_MIC_TEST_VECTORS + } + } + }, { + .alg = "sha1", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = sha1_tv_template, + .count = SHA1_TEST_VECTORS + } + } + }, { + .alg = "sha256", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = sha256_tv_template, + .count = SHA256_TEST_VECTORS + } + } + }, { + .alg = "sha384", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = sha384_tv_template, + .count = SHA384_TEST_VECTORS + } + } + }, { + .alg = "sha512", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = sha512_tv_template, + .count = SHA512_TEST_VECTORS + } + } + }, { + .alg = "tgr128", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = tgr128_tv_template, + .count = TGR128_TEST_VECTORS + } + } + }, { + .alg = "tgr160", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = tgr160_tv_template, + .count = TGR160_TEST_VECTORS + } + } + }, { + .alg = "tgr192", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = tgr192_tv_template, + .count = TGR192_TEST_VECTORS + } + } + }, { + .alg = "wp256", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = wp256_tv_template, + .count = WP256_TEST_VECTORS + } + } + }, { + .alg = "wp384", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = wp384_tv_template, + .count = WP384_TEST_VECTORS + } + } + }, { + .alg = "wp512", + .test = alg_test_digest, + .suite = { + .hash = { + .vecs = wp512_tv_template, + .count = WP512_TEST_VECTORS + } + } + } +}; + +static int digest_test(const char *driver, const char *alg) +{ + int start = 0; + int end = ARRAY_SIZE(digest_test_descs); + + while (start < end) { + int i = (start + end) / 2; + int diff = strcmp(digest_test_descs[i].alg, alg); + + if (diff > 0) { + end = i; + continue; + } + + if (diff < 0) { + start = i + 1; + continue; + } + + return digest_test_descs[i].test(digest_test_descs + i, driver, + 0, 0); + } + + printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); + return 0; +} + +static inline int tcrypt_test(const char *alg) +{ + return alg_test(alg, alg, 0, 0); +} + +static inline int tcrypt_test_digest(const char *alg) +{ + return digest_test(alg, alg); +} + +static void do_test(int m) +{ + int i; + + switch (m) { + case 0: + for (i = 1; i < 200; i++) + do_test(i); case 1: - test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); + tcrypt_test_digest("md5"); break; case 2: - test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); + tcrypt_test_digest("sha1"); break; case 3: - test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template, - DES_ENC_TEST_VECTORS); - test_cipher("ecb(des)", DECRYPT, des_dec_tv_template, - DES_DEC_TEST_VECTORS); - test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template, - DES_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template, - DES_CBC_DEC_TEST_VECTORS); + tcrypt_test("ecb(des)"); + tcrypt_test("cbc(des)"); break; case 4: - test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template, - DES3_EDE_ENC_TEST_VECTORS); - test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template, - DES3_EDE_DEC_TEST_VECTORS); - - test_cipher("cbc(des3_ede)", ENCRYPT, - des3_ede_cbc_enc_tv_template, - DES3_EDE_CBC_ENC_TEST_VECTORS); - - test_cipher("cbc(des3_ede)", DECRYPT, - des3_ede_cbc_dec_tv_template, - DES3_EDE_CBC_DEC_TEST_VECTORS); + tcrypt_test("ecb(des3_ede)"); + tcrypt_test("cbc(des3_ede)"); break; case 5: - test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); + tcrypt_test_digest("md4"); break; case 6: - test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); + tcrypt_test_digest("sha256"); break; case 7: - test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template, - BF_ENC_TEST_VECTORS); - test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template, - BF_DEC_TEST_VECTORS); - test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template, - BF_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template, - BF_CBC_DEC_TEST_VECTORS); + tcrypt_test("ecb(blowfish)"); + tcrypt_test("cbc(blowfish)"); break; case 8: - test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template, - TF_ENC_TEST_VECTORS); - test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template, - TF_DEC_TEST_VECTORS); - test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template, - TF_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template, - TF_CBC_DEC_TEST_VECTORS); + tcrypt_test("ecb(twofish)"); + tcrypt_test("cbc(twofish)"); break; case 9: - test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template, - SERPENT_ENC_TEST_VECTORS); - test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template, - SERPENT_DEC_TEST_VECTORS); + tcrypt_test("ecb(serpent)"); break; case 10: - test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template, - AES_ENC_TEST_VECTORS); - test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template, - AES_DEC_TEST_VECTORS); - test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template, - AES_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template, - AES_CBC_DEC_TEST_VECTORS); - test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template, - AES_CTR_ENC_TEST_VECTORS); - test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template, - AES_CTR_DEC_TEST_VECTORS); + tcrypt_test("ecb(aes)"); + tcrypt_test("cbc(aes)"); + tcrypt_test("rfc3686(ctr(aes))"); break; case 11: - test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); + tcrypt_test_digest("sha384"); break; case 12: - test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); + tcrypt_test_digest("sha512"); break; case 13: @@ -1534,28 +2014,19 @@ static void do_test(void) break; case 14: - test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template, - CAST5_ENC_TEST_VECTORS); - test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template, - CAST5_DEC_TEST_VECTORS); + tcrypt_test("ecb(cast5)"); break; case 15: - test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template, - CAST6_ENC_TEST_VECTORS); - test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template, - CAST6_DEC_TEST_VECTORS); + tcrypt_test("ecb(cast6)"); break; case 16: - test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template, - ARC4_ENC_TEST_VECTORS); - test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template, - ARC4_DEC_TEST_VECTORS); + tcrypt_test("ecb(arc4)"); break; case 17: - test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); + tcrypt_test_digest("michael_mic"); break; case 18: @@ -1563,101 +2034,73 @@ static void do_test(void) break; case 19: - test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template, - TEA_ENC_TEST_VECTORS); - test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template, - TEA_DEC_TEST_VECTORS); + tcrypt_test("ecb(tea)"); break; case 20: - test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template, - XTEA_ENC_TEST_VECTORS); - test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template, - XTEA_DEC_TEST_VECTORS); + tcrypt_test("ecb(xtea)"); break; case 21: - test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template, - KHAZAD_ENC_TEST_VECTORS); - test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template, - KHAZAD_DEC_TEST_VECTORS); + tcrypt_test("ecb(khazad)"); break; case 22: - test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); + tcrypt_test_digest("wp512"); break; case 23: - test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS); + tcrypt_test_digest("wp384"); break; case 24: - test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS); + tcrypt_test_digest("wp256"); break; case 25: - test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template, - TNEPRES_ENC_TEST_VECTORS); - test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template, - TNEPRES_DEC_TEST_VECTORS); + tcrypt_test("ecb(tnepres)"); break; case 26: - test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template, - ANUBIS_ENC_TEST_VECTORS); - test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template, - ANUBIS_DEC_TEST_VECTORS); - test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template, - ANUBIS_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template, - ANUBIS_CBC_ENC_TEST_VECTORS); + tcrypt_test("ecb(anubis)"); + tcrypt_test("cbc(anubis)"); break; case 27: - test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS); + tcrypt_test_digest("tgr192"); break; case 28: - test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS); + tcrypt_test_digest("tgr160"); break; case 29: - test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); + tcrypt_test_digest("tgr128"); break; case 30: - test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template, - XETA_ENC_TEST_VECTORS); - test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template, - XETA_DEC_TEST_VECTORS); + tcrypt_test("ecb(xeta)"); break; case 37: - test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template, - AES_CCM_ENC_TEST_VECTORS); - test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template, - AES_CCM_DEC_TEST_VECTORS); + tcrypt_test("ccm(aes)"); break; case 100: - test_nhash("hmac(md5)", hmac_md5_tv_template, - HMAC_MD5_TEST_VECTORS); + tcrypt_test("hmac(md5)"); break; case 101: - test_nhash("hmac(sha1)", hmac_sha1_tv_template, - HMAC_SHA1_TEST_VECTORS); + tcrypt_test("hmac(sha1)"); break; case 102: - test_nhash("hmac(sha256)", hmac_sha256_tv_template, - HMAC_SHA256_TEST_VECTORS); + tcrypt_test("hmac(sha256)"); break; case 106: - test_hash("xcbc(aes)", aes_xcbc128_tv_template, - XCBC_AES_TEST_VECTORS); + tcrypt_test("xcbc(aes)"); break; case 200: @@ -1776,11 +2219,6 @@ static void do_test(void) case 1000: test_available(); break; - - default: - /* useful for debugging */ - printk("not testing anything\n"); - break; } } @@ -1807,7 +2245,7 @@ static int __init init(void) goto err_free_axbuf; } - do_test(); + do_test(mode); /* We intentionaly return -EAGAIN to prevent keeping * the module. It does all its work from init()