crypto: testmgr - add helpers for fuzzing against generic implementation
Add some helper functions in preparation for fuzz testing algorithms against their generic implementation. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
951d13328a
commit
f2bb770ae8
128
crypto/testmgr.c
128
crypto/testmgr.c
|
@ -128,6 +128,7 @@ struct kpp_test_suite {
|
||||||
|
|
||||||
struct alg_test_desc {
|
struct alg_test_desc {
|
||||||
const char *alg;
|
const char *alg;
|
||||||
|
const char *generic_driver;
|
||||||
int (*test)(const struct alg_test_desc *desc, const char *driver,
|
int (*test)(const struct alg_test_desc *desc, const char *driver,
|
||||||
u32 type, u32 mask);
|
u32 type, u32 mask);
|
||||||
int fips_allowed; /* set if alg is allowed in fips mode */
|
int fips_allowed; /* set if alg is allowed in fips mode */
|
||||||
|
@ -745,6 +746,91 @@ static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||||
|
|
||||||
|
/* Generate a random length in range [0, max_len], but prefer smaller values */
|
||||||
|
static unsigned int generate_random_length(unsigned int max_len)
|
||||||
|
{
|
||||||
|
unsigned int len = prandom_u32() % (max_len + 1);
|
||||||
|
|
||||||
|
switch (prandom_u32() % 4) {
|
||||||
|
case 0:
|
||||||
|
return len % 64;
|
||||||
|
case 1:
|
||||||
|
return len % 256;
|
||||||
|
case 2:
|
||||||
|
return len % 1024;
|
||||||
|
default:
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sometimes make some random changes to the given data buffer */
|
||||||
|
static void mutate_buffer(u8 *buf, size_t count)
|
||||||
|
{
|
||||||
|
size_t num_flips;
|
||||||
|
size_t i;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
/* Sometimes flip some bits */
|
||||||
|
if (prandom_u32() % 4 == 0) {
|
||||||
|
num_flips = min_t(size_t, 1 << (prandom_u32() % 8), count * 8);
|
||||||
|
for (i = 0; i < num_flips; i++) {
|
||||||
|
pos = prandom_u32() % (count * 8);
|
||||||
|
buf[pos / 8] ^= 1 << (pos % 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sometimes flip some bytes */
|
||||||
|
if (prandom_u32() % 4 == 0) {
|
||||||
|
num_flips = min_t(size_t, 1 << (prandom_u32() % 8), count);
|
||||||
|
for (i = 0; i < num_flips; i++)
|
||||||
|
buf[prandom_u32() % count] ^= 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Randomly generate 'count' bytes, but sometimes make them "interesting" */
|
||||||
|
static void generate_random_bytes(u8 *buf, size_t count)
|
||||||
|
{
|
||||||
|
u8 b;
|
||||||
|
u8 increment;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (prandom_u32() % 8) { /* Choose a generation strategy */
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
/* All the same byte, plus optional mutations */
|
||||||
|
switch (prandom_u32() % 4) {
|
||||||
|
case 0:
|
||||||
|
b = 0x00;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
b = 0xff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
b = (u8)prandom_u32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(buf, b, count);
|
||||||
|
mutate_buffer(buf, count);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* Ascending or descending bytes, plus optional mutations */
|
||||||
|
increment = (u8)prandom_u32();
|
||||||
|
b = (u8)prandom_u32();
|
||||||
|
for (i = 0; i < count; i++, b += increment)
|
||||||
|
buf[i] = b;
|
||||||
|
mutate_buffer(buf, count);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Fully random bytes */
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
buf[i] = (u8)prandom_u32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
||||||
size_t max_divs, char *p, char *end,
|
size_t max_divs, char *p, char *end,
|
||||||
bool gen_flushes, u32 req_flags)
|
bool gen_flushes, u32 req_flags)
|
||||||
|
@ -899,6 +985,48 @@ static void crypto_reenable_simd_for_test(void)
|
||||||
__this_cpu_write(crypto_simd_disabled_for_test, false);
|
__this_cpu_write(crypto_simd_disabled_for_test, false);
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given an algorithm name, build the name of the generic implementation of that
|
||||||
|
* algorithm, assuming the usual naming convention. Specifically, this appends
|
||||||
|
* "-generic" to every part of the name that is not a template name. Examples:
|
||||||
|
*
|
||||||
|
* aes => aes-generic
|
||||||
|
* cbc(aes) => cbc(aes-generic)
|
||||||
|
* cts(cbc(aes)) => cts(cbc(aes-generic))
|
||||||
|
* rfc7539(chacha20,poly1305) => rfc7539(chacha20-generic,poly1305-generic)
|
||||||
|
*
|
||||||
|
* Return: 0 on success, or -ENAMETOOLONG if the generic name would be too long
|
||||||
|
*/
|
||||||
|
static int build_generic_driver_name(const char *algname,
|
||||||
|
char driver_name[CRYPTO_MAX_ALG_NAME])
|
||||||
|
{
|
||||||
|
const char *in = algname;
|
||||||
|
char *out = driver_name;
|
||||||
|
size_t len = strlen(algname);
|
||||||
|
|
||||||
|
if (len >= CRYPTO_MAX_ALG_NAME)
|
||||||
|
goto too_long;
|
||||||
|
do {
|
||||||
|
const char *in_saved = in;
|
||||||
|
|
||||||
|
while (*in && *in != '(' && *in != ')' && *in != ',')
|
||||||
|
*out++ = *in++;
|
||||||
|
if (*in != '(' && in > in_saved) {
|
||||||
|
len += 8;
|
||||||
|
if (len >= CRYPTO_MAX_ALG_NAME)
|
||||||
|
goto too_long;
|
||||||
|
memcpy(out, "-generic", 8);
|
||||||
|
out += 8;
|
||||||
|
}
|
||||||
|
} while ((*out++ = *in++) != '\0');
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
too_long:
|
||||||
|
pr_err("alg: generic driver name for \"%s\" would be too long\n",
|
||||||
|
algname);
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
}
|
||||||
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
|
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
|
||||||
static void crypto_disable_simd_for_test(void)
|
static void crypto_disable_simd_for_test(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue