summaryrefslogtreecommitdiff
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c216
1 files changed, 159 insertions, 57 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 5823735..7795550 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -179,13 +179,14 @@ static int do_one_async_hash_op(struct ahash_request *req,
ret = wait_for_completion_interruptible(&tr->completion);
if (!ret)
ret = tr->err;
- INIT_COMPLETION(tr->completion);
+ reinit_completion(&tr->completion);
}
return ret;
}
-static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
- unsigned int tcount, bool use_digest)
+static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+ unsigned int tcount, bool use_digest,
+ const int align_offset)
{
const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
unsigned int i, j, k, temp;
@@ -216,10 +217,15 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
if (template[i].np)
continue;
+ ret = -EINVAL;
+ if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE))
+ goto out;
+
j++;
memset(result, 0, 64);
hash_buff = xbuf[0];
+ hash_buff += align_offset;
memcpy(hash_buff, template[i].plaintext, template[i].psize);
sg_init_one(&sg[0], hash_buff, template[i].psize);
@@ -281,6 +287,10 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
j = 0;
for (i = 0; i < tcount; i++) {
+ /* alignment tests are only done with continuous buffers */
+ if (align_offset != 0)
+ break;
+
if (template[i].np) {
j++;
memset(result, 0, 64);
@@ -326,7 +336,7 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
ret = wait_for_completion_interruptible(
&tresult.completion);
if (!ret && !(ret = tresult.err)) {
- INIT_COMPLETION(tresult.completion);
+ reinit_completion(&tresult.completion);
break;
}
/* fall through */
@@ -358,9 +368,36 @@ out_nobuf:
return ret;
}
+static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+ unsigned int tcount, bool use_digest)
+{
+ unsigned int alignmask;
+ int ret;
+
+ ret = __test_hash(tfm, template, tcount, use_digest, 0);
+ if (ret)
+ return ret;
+
+ /* test unaligned buffers, check with one byte offset */
+ ret = __test_hash(tfm, template, tcount, use_digest, 1);
+ if (ret)
+ return ret;
+
+ alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+ if (alignmask) {
+ /* Check if alignment mask for tfm is correctly set. */
+ ret = __test_hash(tfm, template, tcount, use_digest,
+ alignmask + 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int __test_aead(struct crypto_aead *tfm, int enc,
struct aead_testvec *template, unsigned int tcount,
- const bool diff_dst)
+ const bool diff_dst, const int align_offset)
{
const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
unsigned int i, j, k, n, temp;
@@ -423,15 +460,16 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
if (!template[i].np) {
j++;
- /* some tepmplates have no input data but they will
+ /* some templates have no input data but they will
* touch input
*/
input = xbuf[0];
+ input += align_offset;
assoc = axbuf[0];
ret = -EINVAL;
- if (WARN_ON(template[i].ilen > PAGE_SIZE ||
- template[i].alen > PAGE_SIZE))
+ if (WARN_ON(align_offset + template[i].ilen >
+ PAGE_SIZE || template[i].alen > PAGE_SIZE))
goto out;
memcpy(input, template[i].input, template[i].ilen);
@@ -465,15 +503,16 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
goto out;
}
- sg_init_one(&sg[0], input,
- template[i].ilen + (enc ? authsize : 0));
-
if (diff_dst) {
output = xoutbuf[0];
+ output += align_offset;
+ sg_init_one(&sg[0], input, template[i].ilen);
sg_init_one(&sgout[0], output,
+ template[i].rlen);
+ } else {
+ sg_init_one(&sg[0], input,
template[i].ilen +
(enc ? authsize : 0));
- } else {
output = input;
}
@@ -504,7 +543,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !(ret = result.err)) {
- INIT_COMPLETION(result.completion);
+ reinit_completion(&result.completion);
break;
}
case -EBADMSG:
@@ -530,6 +569,10 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
}
for (i = 0, j = 0; i < tcount; i++) {
+ /* alignment tests are only done with continuous buffers */
+ if (align_offset != 0)
+ break;
+
if (template[i].np) {
j++;
@@ -569,12 +612,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
memcpy(q, template[i].input + temp,
template[i].tap[k]);
- n = template[i].tap[k];
- if (k == template[i].np - 1 && enc)
- n += authsize;
- if (offset_in_page(q) + n < PAGE_SIZE)
- q[n] = 0;
-
sg_set_buf(&sg[k], q, template[i].tap[k]);
if (diff_dst) {
@@ -582,13 +619,17 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
offset_in_page(IDX[k]);
memset(q, 0, template[i].tap[k]);
- if (offset_in_page(q) + n < PAGE_SIZE)
- q[n] = 0;
sg_set_buf(&sgout[k], q,
template[i].tap[k]);
}
+ n = template[i].tap[k];
+ if (k == template[i].np - 1 && enc)
+ n += authsize;
+ if (offset_in_page(q) + n < PAGE_SIZE)
+ q[n] = 0;
+
temp += template[i].tap[k];
}
@@ -607,10 +648,10 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
goto out;
}
- sg[k - 1].length += authsize;
-
if (diff_dst)
sgout[k - 1].length += authsize;
+ else
+ sg[k - 1].length += authsize;
}
sg_init_table(asg, template[i].anp);
@@ -654,7 +695,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !(ret = result.err)) {
- INIT_COMPLETION(result.completion);
+ reinit_completion(&result.completion);
break;
}
case -EBADMSG:
@@ -732,15 +773,34 @@ out_noxbuf:
static int test_aead(struct crypto_aead *tfm, int enc,
struct aead_testvec *template, unsigned int tcount)
{
+ unsigned int alignmask;
int ret;
/* test 'dst == src' case */
- ret = __test_aead(tfm, enc, template, tcount, false);
+ ret = __test_aead(tfm, enc, template, tcount, false, 0);
if (ret)
return ret;
/* test 'dst != src' case */
- return __test_aead(tfm, enc, template, tcount, true);
+ ret = __test_aead(tfm, enc, template, tcount, true, 0);
+ if (ret)
+ return ret;
+
+ /* test unaligned buffers, check with one byte offset */
+ ret = __test_aead(tfm, enc, template, tcount, true, 1);
+ if (ret)
+ return ret;
+
+ alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+ if (alignmask) {
+ /* Check if alignment mask for tfm is correctly set. */
+ ret = __test_aead(tfm, enc, template, tcount, true,
+ alignmask + 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int test_cipher(struct crypto_cipher *tfm, int enc,
@@ -820,7 +880,7 @@ out_nobuf:
static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
struct cipher_testvec *template, unsigned int tcount,
- const bool diff_dst)
+ const bool diff_dst, const int align_offset)
{
const char *algo =
crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
@@ -876,10 +936,12 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
j++;
ret = -EINVAL;
- if (WARN_ON(template[i].ilen > PAGE_SIZE))
+ if (WARN_ON(align_offset + template[i].ilen >
+ PAGE_SIZE))
goto out;
data = xbuf[0];
+ data += align_offset;
memcpy(data, template[i].input, template[i].ilen);
crypto_ablkcipher_clear_flags(tfm, ~0);
@@ -900,6 +962,7 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
sg_init_one(&sg[0], data, template[i].ilen);
if (diff_dst) {
data = xoutbuf[0];
+ data += align_offset;
sg_init_one(&sgout[0], data, template[i].ilen);
}
@@ -918,7 +981,7 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err))) {
- INIT_COMPLETION(result.completion);
+ reinit_completion(&result.completion);
break;
}
/* fall through */
@@ -941,6 +1004,9 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
j = 0;
for (i = 0; i < tcount; i++) {
+ /* alignment tests are only done with continuous buffers */
+ if (align_offset != 0)
+ break;
if (template[i].iv)
memcpy(iv, template[i].iv, MAX_IVLEN);
@@ -1018,7 +1084,7 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = wait_for_completion_interruptible(
&result.completion);
if (!ret && !((ret = result.err))) {
- INIT_COMPLETION(result.completion);
+ reinit_completion(&result.completion);
break;
}
/* fall through */
@@ -1075,15 +1141,34 @@ out_nobuf:
static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
struct cipher_testvec *template, unsigned int tcount)
{
+ unsigned int alignmask;
int ret;
/* test 'dst == src' case */
- ret = __test_skcipher(tfm, enc, template, tcount, false);
+ ret = __test_skcipher(tfm, enc, template, tcount, false, 0);
if (ret)
return ret;
/* test 'dst != src' case */
- return __test_skcipher(tfm, enc, template, tcount, true);
+ ret = __test_skcipher(tfm, enc, template, tcount, true, 0);
+ if (ret)
+ return ret;
+
+ /* test unaligned buffers, check with one byte offset */
+ ret = __test_skcipher(tfm, enc, template, tcount, true, 1);
+ if (ret)
+ return ret;
+
+ alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+ if (alignmask) {
+ /* Check if alignment mask for tfm is correctly set. */
+ ret = __test_skcipher(tfm, enc, template, tcount, true,
+ alignmask + 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
@@ -1654,16 +1739,10 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "__cbc-twofish-avx",
.test = alg_test_null,
}, {
- .alg = "__cbc-twofish-avx2",
- .test = alg_test_null,
- }, {
.alg = "__driver-cbc-aes-aesni",
.test = alg_test_null,
.fips_allowed = 1,
}, {
- .alg = "__driver-cbc-blowfish-avx2",
- .test = alg_test_null,
- }, {
.alg = "__driver-cbc-camellia-aesni",
.test = alg_test_null,
}, {
@@ -1688,16 +1767,10 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "__driver-cbc-twofish-avx",
.test = alg_test_null,
}, {
- .alg = "__driver-cbc-twofish-avx2",
- .test = alg_test_null,
- }, {
.alg = "__driver-ecb-aes-aesni",
.test = alg_test_null,
.fips_allowed = 1,
}, {
- .alg = "__driver-ecb-blowfish-avx2",
- .test = alg_test_null,
- }, {
.alg = "__driver-ecb-camellia-aesni",
.test = alg_test_null,
}, {
@@ -1722,9 +1795,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "__driver-ecb-twofish-avx",
.test = alg_test_null,
}, {
- .alg = "__driver-ecb-twofish-avx2",
- .test = alg_test_null,
- }, {
.alg = "__ghash-pclmulqdqni",
.test = alg_test_null,
.fips_allowed = 1,
@@ -1974,12 +2044,19 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
- .alg = "cryptd(__driver-cbc-aes-aesni)",
- .test = alg_test_null,
+ .alg = "crct10dif",
+ .test = alg_test_hash,
.fips_allowed = 1,
+ .suite = {
+ .hash = {
+ .vecs = crct10dif_tv_template,
+ .count = CRCT10DIF_TEST_VECTORS
+ }
+ }
}, {
- .alg = "cryptd(__driver-cbc-blowfish-avx2)",
+ .alg = "cryptd(__driver-cbc-aes-aesni)",
.test = alg_test_null,
+ .fips_allowed = 1,
}, {
.alg = "cryptd(__driver-cbc-camellia-aesni)",
.test = alg_test_null,
@@ -1994,9 +2071,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.test = alg_test_null,
.fips_allowed = 1,
}, {
- .alg = "cryptd(__driver-ecb-blowfish-avx2)",
- .test = alg_test_null,
- }, {
.alg = "cryptd(__driver-ecb-camellia-aesni)",
.test = alg_test_null,
}, {
@@ -2021,9 +2095,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "cryptd(__driver-ecb-twofish-avx)",
.test = alg_test_null,
}, {
- .alg = "cryptd(__driver-ecb-twofish-avx2)",
- .test = alg_test_null,
- }, {
.alg = "cryptd(__driver-gcm-aes-aesni)",
.test = alg_test_null,
.fips_allowed = 1,
@@ -3068,6 +3139,35 @@ static const struct alg_test_desc alg_test_descs[] = {
}
};
+static bool alg_test_descs_checked;
+
+static void alg_test_descs_check_order(void)
+{
+ int i;
+
+ /* only check once */
+ if (alg_test_descs_checked)
+ return;
+
+ alg_test_descs_checked = true;
+
+ for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) {
+ int diff = strcmp(alg_test_descs[i - 1].alg,
+ alg_test_descs[i].alg);
+
+ if (WARN_ON(diff > 0)) {
+ pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n",
+ alg_test_descs[i - 1].alg,
+ alg_test_descs[i].alg);
+ }
+
+ if (WARN_ON(diff == 0)) {
+ pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n",
+ alg_test_descs[i].alg);
+ }
+ }
+}
+
static int alg_find_test(const char *alg)
{
int start = 0;
@@ -3099,6 +3199,8 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
int j;
int rc;
+ alg_test_descs_check_order();
+
if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
char nalg[CRYPTO_MAX_ALG_NAME];
@@ -3130,7 +3232,7 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
if (i >= 0)
rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
type, mask);
- if (j >= 0)
+ if (j >= 0 && j != i)
rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
type, mask);