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: 330611177
Link: https://lore.kernel.org/r/20240621165922.77672-4-ebiggers@kernel.org
Change-Id: I0b2bad7317a7b689d41f6a185042c401e081ba33
Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
Eric Biggers 2024-06-21 10:37:48 -07:00 committed by William McVicker
parent 17f53e8a94
commit a2372f602d

View File

@ -229,6 +229,7 @@ enum flush_type {
enum finalization_type { enum finalization_type {
FINALIZATION_TYPE_FINAL, /* use final() */ FINALIZATION_TYPE_FINAL, /* use final() */
FINALIZATION_TYPE_FINUP, /* use finup() */ FINALIZATION_TYPE_FINUP, /* use finup() */
FINALIZATION_TYPE_FINUP_MB, /* use finup_mb() */
FINALIZATION_TYPE_DIGEST, /* use digest() */ 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 * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
* the @key_offset * the @key_offset
* @finalization_type: what finalization function to use for hashes * @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. * @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP.
*/ */
struct testvec_config { struct testvec_config {
@ -305,6 +310,8 @@ struct testvec_config {
bool iv_offset_relative_to_alignmask; bool iv_offset_relative_to_alignmask;
bool key_offset_relative_to_alignmask; bool key_offset_relative_to_alignmask;
enum finalization_type finalization_type; enum finalization_type finalization_type;
unsigned int multibuffer_index;
unsigned int multibuffer_count;
bool nosimd; bool nosimd;
}; };
@ -1113,15 +1120,23 @@ static void generate_random_testvec_config(struct rnd_state *rng,
p += scnprintf(p, end - p, " may_sleep"); p += scnprintf(p, end - p, " may_sleep");
} }
switch (prandom_u32_below(rng, 4)) { switch (prandom_u32_below(rng, 8)) {
case 0: case 0:
case 1:
cfg->finalization_type = FINALIZATION_TYPE_FINAL; cfg->finalization_type = FINALIZATION_TYPE_FINAL;
p += scnprintf(p, end - p, " use_final"); p += scnprintf(p, end - p, " use_final");
break; break;
case 1: case 2:
cfg->finalization_type = FINALIZATION_TYPE_FINUP; cfg->finalization_type = FINALIZATION_TYPE_FINUP;
p += scnprintf(p, end - p, " use_finup"); p += scnprintf(p, end - p, " use_finup");
break; 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: default:
cfg->finalization_type = FINALIZATION_TYPE_DIGEST; cfg->finalization_type = FINALIZATION_TYPE_DIGEST;
p += scnprintf(p, end - p, " use_digest"); p += scnprintf(p, end - p, " use_digest");
@ -1274,6 +1289,33 @@ static inline int check_shash_op(const char *op, int err,
return 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 */ /* Test one hash test vector in one configuration, using the shash API */
static int test_shash_vec_cfg(const struct hash_testvec *vec, static int test_shash_vec_cfg(const struct hash_testvec *vec,
const char *vec_name, const char *vec_name,
@ -1351,7 +1393,10 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
goto result_ready; 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) if (cfg->nosimd)
crypto_disable_simd_for_test(); crypto_disable_simd_for_test();
@ -1363,12 +1408,14 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
return err; return err;
for (i = 0; i < tsgl->nents; i++) { 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 && if (i + 1 == tsgl->nents &&
cfg->finalization_type == FINALIZATION_TYPE_FINUP) { cfg->finalization_type == FINALIZATION_TYPE_FINUP) {
if (divs[i]->nosimd) if (divs[i]->nosimd)
crypto_disable_simd_for_test(); crypto_disable_simd_for_test();
err = crypto_shash_finup(desc, sg_virt(&tsgl->sgl[i]), err = crypto_shash_finup(desc, data, len, result);
tsgl->sgl[i].length, result);
if (divs[i]->nosimd) if (divs[i]->nosimd)
crypto_reenable_simd_for_test(); crypto_reenable_simd_for_test();
err = check_shash_op("finup", err, driver, vec_name, err = check_shash_op("finup", err, driver, vec_name,
@ -1377,10 +1424,22 @@ static int test_shash_vec_cfg(const struct hash_testvec *vec,
return err; return err;
goto result_ready; 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) if (divs[i]->nosimd)
crypto_disable_simd_for_test(); crypto_disable_simd_for_test();
err = crypto_shash_update(desc, sg_virt(&tsgl->sgl[i]), err = crypto_shash_update(desc, data, len);
tsgl->sgl[i].length);
if (divs[i]->nosimd) if (divs[i]->nosimd)
crypto_reenable_simd_for_test(); crypto_reenable_simd_for_test();
err = check_shash_op("update", err, driver, vec_name, cfg); err = check_shash_op("update", err, driver, vec_name, cfg);