aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 292d28caf00f..5721bf4a1c89 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1291,14 +1291,12 @@ static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
* Generate a hash test vector from the given implementation.
* Assumes the buffers in 'vec' were already allocated.
*/
-static void generate_random_hash_testvec(struct crypto_shash *tfm,
+static void generate_random_hash_testvec(struct shash_desc *desc,
struct hash_testvec *vec,
unsigned int maxkeysize,
unsigned int maxdatasize,
char *name, size_t max_namelen)
{
- SHASH_DESC_ON_STACK(desc, tfm);
-
/* Data */
vec->psize = generate_random_length(maxdatasize);
generate_random_bytes((u8 *)vec->plaintext, vec->psize);
@@ -1315,7 +1313,7 @@ static void generate_random_hash_testvec(struct crypto_shash *tfm,
vec->ksize = 1 + (prandom_u32() % maxkeysize);
generate_random_bytes((u8 *)vec->key, vec->ksize);
- vec->setkey_error = crypto_shash_setkey(tfm, vec->key,
+ vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key,
vec->ksize);
/* If the key couldn't be set, no need to continue to digest. */
if (vec->setkey_error)
@@ -1323,7 +1321,6 @@ static void generate_random_hash_testvec(struct crypto_shash *tfm,
}
/* Digest */
- desc->tfm = tfm;
vec->digest_error = crypto_shash_digest(desc, vec->plaintext,
vec->psize, (u8 *)vec->digest);
done:
@@ -1349,10 +1346,11 @@ static int test_hash_vs_generic_impl(const char *driver,
const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
char _generic_driver[CRYPTO_MAX_ALG_NAME];
struct crypto_shash *generic_tfm = NULL;
+ struct shash_desc *generic_desc = NULL;
unsigned int i;
struct hash_testvec vec = { 0 };
char vec_name[64];
- struct testvec_config cfg;
+ struct testvec_config *cfg;
char cfgname[TESTVEC_CONFIG_NAMELEN];
int err;
@@ -1382,6 +1380,20 @@ static int test_hash_vs_generic_impl(const char *driver,
return err;
}
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ generic_desc = kzalloc(sizeof(*desc) +
+ crypto_shash_descsize(generic_tfm), GFP_KERNEL);
+ if (!generic_desc) {
+ err = -ENOMEM;
+ goto out;
+ }
+ generic_desc->tfm = generic_tfm;
+
/* Check the algorithm properties for consistency. */
if (digestsize != crypto_shash_digestsize(generic_tfm)) {
@@ -1413,12 +1425,12 @@ static int test_hash_vs_generic_impl(const char *driver,
}
for (i = 0; i < fuzz_iterations * 8; i++) {
- generate_random_hash_testvec(generic_tfm, &vec,
+ generate_random_hash_testvec(generic_desc, &vec,
maxkeysize, maxdatasize,
vec_name, sizeof(vec_name));
- generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname));
+ generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
- err = test_hash_vec_cfg(driver, &vec, vec_name, &cfg,
+ err = test_hash_vec_cfg(driver, &vec, vec_name, cfg,
req, tsgl, hashstate);
if (err)
goto out;
@@ -1426,10 +1438,12 @@ static int test_hash_vs_generic_impl(const char *driver,
}
err = 0;
out:
+ kfree(cfg);
kfree(vec.key);
kfree(vec.plaintext);
kfree(vec.digest);
crypto_free_shash(generic_tfm);
+ kzfree(generic_desc);
return err;
}
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
@@ -1820,6 +1834,7 @@ static void generate_random_aead_testvec(struct aead_request *req,
* If the key or authentication tag size couldn't be set, no need to
* continue to encrypt.
*/
+ vec->crypt_error = 0;
if (vec->setkey_error || vec->setauthsize_error)
goto done;
@@ -1867,7 +1882,7 @@ static int test_aead_vs_generic_impl(const char *driver,
unsigned int i;
struct aead_testvec vec = { 0 };
char vec_name[64];
- struct testvec_config cfg;
+ struct testvec_config *cfg;
char cfgname[TESTVEC_CONFIG_NAMELEN];
int err;
@@ -1897,6 +1912,12 @@ static int test_aead_vs_generic_impl(const char *driver,
return err;
}
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg) {
+ err = -ENOMEM;
+ goto out;
+ }
+
generic_req = aead_request_alloc(generic_tfm, GFP_KERNEL);
if (!generic_req) {
err = -ENOMEM;
@@ -1951,20 +1972,23 @@ static int test_aead_vs_generic_impl(const char *driver,
generate_random_aead_testvec(generic_req, &vec,
maxkeysize, maxdatasize,
vec_name, sizeof(vec_name));
- generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname));
+ generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
- err = test_aead_vec_cfg(driver, ENCRYPT, &vec, vec_name, &cfg,
- req, tsgls);
- if (err)
- goto out;
- err = test_aead_vec_cfg(driver, DECRYPT, &vec, vec_name, &cfg,
+ err = test_aead_vec_cfg(driver, ENCRYPT, &vec, vec_name, cfg,
req, tsgls);
if (err)
goto out;
+ if (vec.crypt_error == 0) {
+ err = test_aead_vec_cfg(driver, DECRYPT, &vec, vec_name,
+ cfg, req, tsgls);
+ if (err)
+ goto out;
+ }
cond_resched();
}
err = 0;
out:
+ kfree(cfg);
kfree(vec.key);
kfree(vec.iv);
kfree(vec.assoc);
@@ -2389,6 +2413,15 @@ static void generate_random_cipher_testvec(struct skcipher_request *req,
skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
skcipher_request_set_crypt(req, &src, &dst, vec->len, iv);
vec->crypt_error = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
+ if (vec->crypt_error != 0) {
+ /*
+ * The only acceptable error here is for an invalid length, so
+ * skcipher decryption should fail with the same error too.
+ * We'll test for this. But to keep the API usage well-defined,
+ * explicitly initialize the ciphertext buffer too.
+ */
+ memset((u8 *)vec->ctext, 0, vec->len);
+ }
done:
snprintf(name, max_namelen, "\"random: len=%u klen=%u\"",
vec->len, vec->klen);
@@ -2414,7 +2447,7 @@ static int test_skcipher_vs_generic_impl(const char *driver,
unsigned int i;
struct cipher_testvec vec = { 0 };
char vec_name[64];
- struct testvec_config cfg;
+ struct testvec_config *cfg;
char cfgname[TESTVEC_CONFIG_NAMELEN];
int err;
@@ -2448,6 +2481,12 @@ static int test_skcipher_vs_generic_impl(const char *driver,
return err;
}
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg) {
+ err = -ENOMEM;
+ goto out;
+ }
+
generic_req = skcipher_request_alloc(generic_tfm, GFP_KERNEL);
if (!generic_req) {
err = -ENOMEM;
@@ -2495,20 +2534,21 @@ static int test_skcipher_vs_generic_impl(const char *driver,
for (i = 0; i < fuzz_iterations * 8; i++) {
generate_random_cipher_testvec(generic_req, &vec, maxdatasize,
vec_name, sizeof(vec_name));
- generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname));
+ generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
err = test_skcipher_vec_cfg(driver, ENCRYPT, &vec, vec_name,
- &cfg, req, tsgls);
+ cfg, req, tsgls);
if (err)
goto out;
err = test_skcipher_vec_cfg(driver, DECRYPT, &vec, vec_name,
- &cfg, req, tsgls);
+ cfg, req, tsgls);
if (err)
goto out;
cond_resched();
}
err = 0;
out:
+ kfree(cfg);
kfree(vec.key);
kfree(vec.iv);
kfree(vec.ptext);