crypto-tester: Add facility to test KDFs

This commit is contained in:
Tobias Brunner
2022-04-14 18:54:24 +02:00
parent ec17fa2fef
commit 0c6baa8997
4 changed files with 274 additions and 2 deletions
+194
View File
@@ -69,6 +69,11 @@ struct private_crypto_tester_t {
*/
linked_list_t *xof;
/**
* List of KDF test vectors
*/
linked_list_t *kdf;
/**
* List of DRBG test vectors
*/
@@ -1186,6 +1191,185 @@ failure:
return !failed;
}
/**
* Create a KDF using the given arguments
*/
static kdf_t *create_kdf_args(kdf_constructor_t create,
key_derivation_function_t alg, ...)
{
va_list args;
kdf_t *kdf;
va_start(args, alg);
kdf = create(alg, args);
va_end(args);
return kdf;
}
/**
* Create a KDF using arguments from the given test vector
*/
static kdf_t *create_kdf_vector(kdf_constructor_t create,
key_derivation_function_t alg,
kdf_test_vector_t *vector)
{
switch (alg)
{
case KDF_PRF_PLUS:
return create_kdf_args(create, alg, vector->arg.prf);
case KDF_UNDEFINED:
break;
}
return NULL;
}
/**
* Check if the given test vector applies to the passed arguments
*/
static bool kdf_vector_applies(key_derivation_function_t alg,
kdf_test_args_t *args, kdf_test_vector_t *vector)
{
bool applies = FALSE;
switch (alg)
{
case KDF_PRF_PLUS:
{
pseudo_random_function_t prf;
VA_ARGS_VGET(args->args, prf);
applies = (prf == vector->arg.prf);
break;
}
case KDF_UNDEFINED:
break;
}
return applies;
}
METHOD(crypto_tester_t, test_kdf, bool,
private_crypto_tester_t *this, key_derivation_function_t alg,
kdf_constructor_t create, kdf_test_args_t *args, u_int *speed,
const char *plugin_name)
{
enumerator_t *enumerator;
kdf_test_vector_t *vector;
va_list copy;
bool failed = FALSE;
u_int tested = 0, construction_failed = 0;
enumerator = this->kdf->create_enumerator(this->kdf);
while (enumerator->enumerate(enumerator, &vector))
{
kdf_t *kdf;
chunk_t out = chunk_empty;
if (vector->alg != alg ||
(args && !kdf_vector_applies(alg, args, vector)))
{
continue;
}
tested++;
failed = TRUE;
if (args)
{
va_copy(copy, args->args);
kdf = create(alg, copy);
va_end(copy);
}
else
{
kdf = create_kdf_vector(create, alg, vector);
}
if (!kdf)
{
if (args)
{
DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
key_derivation_function_names, alg, plugin_name);
break;
}
/* while there could be a problem, the constructor might just not
* be able to create an instance for this test vector, we check
* for that at the end */
construction_failed++;
failed = FALSE;
continue;
}
if (vector->key.len &&
!kdf->set_param(kdf, KDF_PARAM_KEY, vector->key))
{
goto failure;
}
if (vector->salt.len &&
!kdf->set_param(kdf, KDF_PARAM_SALT, vector->salt))
{
goto failure;
}
/* allocated bytes */
if (!kdf->allocate_bytes(kdf, vector->out.len, &out))
{
goto failure;
}
if (!chunk_equals(out, vector->out))
{
goto failure;
}
/* bytes to existing buffer */
memset(out.ptr, 0, out.len);
if (!kdf->get_bytes(kdf, out.len, out.ptr))
{
goto failure;
}
if (!chunk_equals(out, vector->out))
{
goto failure;
}
failed = FALSE;
failure:
kdf->destroy(kdf);
chunk_free(&out);
if (failed)
{
DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
key_derivation_function_names, alg, plugin_name,
get_name(vector));
break;
}
}
enumerator->destroy(enumerator);
if (!tested)
{
DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
this->required ? "disabled" : "enabled ",
key_derivation_function_names, alg, plugin_name);
return !this->required;
}
tested -= construction_failed;
if (!tested)
{
DBG1(DBG_LIB, "%s %N[%s]: unable to apply any available test vectors",
this->required ? "disabled" : "enabled ",
key_derivation_function_names, alg, plugin_name);
return !this->required;
}
if (!failed)
{
if (speed)
{
DBG2(DBG_LIB, "benchmarking for %N is currently not supported",
key_derivation_function_names, alg);
}
DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
key_derivation_function_names, alg, plugin_name, tested);
}
return !failed;
}
/**
* Benchmark a DRBG
*/
@@ -1622,6 +1806,12 @@ METHOD(crypto_tester_t, add_xof_vector, void,
this->xof->insert_last(this->xof, vector);
}
METHOD(crypto_tester_t, add_kdf_vector, void,
private_crypto_tester_t *this, kdf_test_vector_t *vector)
{
this->kdf->insert_last(this->kdf, vector);
}
METHOD(crypto_tester_t, add_drbg_vector, void,
private_crypto_tester_t *this, drbg_test_vector_t *vector)
{
@@ -1649,6 +1839,7 @@ METHOD(crypto_tester_t, destroy, void,
this->hasher->destroy(this->hasher);
this->prf->destroy(this->prf);
this->xof->destroy(this->xof);
this->kdf->destroy(this->kdf);
this->drbg->destroy(this->drbg);
this->rng->destroy(this->rng);
this->dh->destroy(this->dh);
@@ -1670,6 +1861,7 @@ crypto_tester_t *crypto_tester_create()
.test_hasher = _test_hasher,
.test_prf = _test_prf,
.test_xof = _test_xof,
.test_kdf = _test_kdf,
.test_drbg = _test_drbg,
.test_rng = _test_rng,
.test_dh = _test_dh,
@@ -1679,6 +1871,7 @@ crypto_tester_t *crypto_tester_create()
.add_hasher_vector = _add_hasher_vector,
.add_prf_vector = _add_prf_vector,
.add_xof_vector = _add_xof_vector,
.add_kdf_vector = _add_kdf_vector,
.add_drbg_vector = _add_drbg_vector,
.add_rng_vector = _add_rng_vector,
.add_dh_vector = _add_dh_vector,
@@ -1690,6 +1883,7 @@ crypto_tester_t *crypto_tester_create()
.hasher = linked_list_create(),
.prf = linked_list_create(),
.xof = linked_list_create(),
.kdf = linked_list_create(),
.drbg = linked_list_create(),
.rng = linked_list_create(),
.dh = linked_list_create(),