FROMLIST: crypto: testmgr - add tests for finup_mb

Update the shash self-tests to test the new finup_mb method when
CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y.

Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>

Bug: 351884559
Link: https://lore.kernel.org/linux-crypto/20241001153718.111665-3-ebiggers@kernel.org/
Change-Id: I0b2bad7317a7b689d41f6a185042c401e081ba33
Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
Eric Biggers
2024-10-01 08:37:13 -07:00
parent a0a9222d20
commit 6d85b7fe15
+66 -7
View File
@@ -229,6 +229,7 @@ enum flush_type {
enum finalization_type {
FINALIZATION_TYPE_FINAL, /* use final() */
FINALIZATION_TYPE_FINUP, /* use finup() */
FINALIZATION_TYPE_FINUP_MB, /* use finup_mb() */
FINALIZATION_TYPE_DIGEST, /* use digest() */
};
@@ -292,6 +293,10 @@ struct test_sg_division {
* @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
* the @key_offset
* @finalization_type: what finalization function to use for hashes
* @multibuffer_index: random number used to generate the message index to use
* for finup_mb (when finup_mb is used).
* @multibuffer_count: random number used to generate the num_msgs parameter to
* finup_mb (when finup_mb is used).
* @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP.
* This applies to the parts of the operation that aren't controlled
* individually by @nosimd_setkey or @src_divs[].nosimd.
@@ -309,6 +314,8 @@ struct testvec_config {
bool iv_offset_relative_to_alignmask;
bool key_offset_relative_to_alignmask;
enum finalization_type finalization_type;
unsigned int multibuffer_index;
unsigned int multibuffer_count;
bool nosimd;
bool nosimd_setkey;
};
@@ -1124,15 +1131,23 @@ static void generate_random_testvec_config(struct rnd_state *rng,
p += scnprintf(p, end - p, " may_sleep");
}
switch (prandom_u32_below(rng, 4)) {
switch (prandom_u32_below(rng, 8)) {
case 0:
case 1:
cfg->finalization_type = FINALIZATION_TYPE_FINAL;
p += scnprintf(p, end - p, " use_final");
break;
case 1:
case 2:
cfg->finalization_type = FINALIZATION_TYPE_FINUP;
p += scnprintf(p, end - p, " use_finup");
break;
case 3:
case 4:
cfg->finalization_type = FINALIZATION_TYPE_FINUP_MB;
cfg->multibuffer_index = prandom_u32_state(rng);
cfg->multibuffer_count = prandom_u32_state(rng);
p += scnprintf(p, end - p, " use_finup_mb");
break;
default:
cfg->finalization_type = FINALIZATION_TYPE_DIGEST;
p += scnprintf(p, end - p, " use_digest");
@@ -1291,6 +1306,33 @@ static inline int check_shash_op(const char *op, int err,
return err;
}
static int do_finup_mb(struct shash_desc *desc,
const u8 *data, unsigned int len, u8 *result,
const struct testvec_config *cfg,
const struct test_sglist *tsgl)
{
struct crypto_shash *tfm = desc->tfm;
const u8 *unused_data = tsgl->bufs[XBUFSIZE - 1];
u8 unused_result[HASH_MAX_DIGESTSIZE];
const u8 *datas[HASH_MAX_MB_MSGS];
u8 *outs[HASH_MAX_MB_MSGS];
unsigned int num_msgs;
unsigned int msg_idx;
unsigned int i;
num_msgs = 1 + (cfg->multibuffer_count % crypto_shash_mb_max_msgs(tfm));
if (WARN_ON_ONCE(num_msgs > HASH_MAX_MB_MSGS))
return -EINVAL;
msg_idx = cfg->multibuffer_index % num_msgs;
for (i = 0; i < num_msgs; i++) {
datas[i] = unused_data;
outs[i] = unused_result;
}
datas[msg_idx] = data;
outs[msg_idx] = result;
return crypto_shash_finup_mb(desc, datas, len, outs, num_msgs);
}
/* Test one hash test vector in one configuration, using the shash API */
static int test_shash_vec_cfg(const struct hash_testvec *vec,
const char *vec_name,
@@ -1367,7 +1409,10 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
goto result_ready;
}
/* Using init(), zero or more update(), then final() or finup() */
/*
* Using init(), zero or more update(), then either final(), finup(), or
* finup_mb().
*/
if (cfg->nosimd)
crypto_disable_simd_for_test();
@@ -1379,12 +1424,14 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
return err;
for (i = 0; i < tsgl->nents; i++) {
const u8 *data = sg_virt(&tsgl->sgl[i]);
unsigned int len = tsgl->sgl[i].length;
if (i + 1 == tsgl->nents &&
cfg->finalization_type == FINALIZATION_TYPE_FINUP) {
if (divs[i]->nosimd)
crypto_disable_simd_for_test();
err = crypto_shash_finup(desc, sg_virt(&tsgl->sgl[i]),
tsgl->sgl[i].length, result);
err = crypto_shash_finup(desc, data, len, result);
if (divs[i]->nosimd)
crypto_reenable_simd_for_test();
err = check_shash_op("finup", err, driver, vec_name,
@@ -1393,10 +1440,22 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
return err;
goto result_ready;
}
if (i + 1 == tsgl->nents &&
cfg->finalization_type == FINALIZATION_TYPE_FINUP_MB) {
if (divs[i]->nosimd)
crypto_disable_simd_for_test();
err = do_finup_mb(desc, data, len, result, cfg, tsgl);
if (divs[i]->nosimd)
crypto_reenable_simd_for_test();
err = check_shash_op("finup_mb", err, driver, vec_name,
cfg);
if (err)
return err;
goto result_ready;
}
if (divs[i]->nosimd)
crypto_disable_simd_for_test();
err = crypto_shash_update(desc, sg_virt(&tsgl->sgl[i]),
tsgl->sgl[i].length);
err = crypto_shash_update(desc, data, len);
if (divs[i]->nosimd)
crypto_reenable_simd_for_test();
err = check_shash_op("update", err, driver, vec_name, cfg);