crypto: Adapt kdf_t interface to support KDFs with fixed output length

This commit is contained in:
Tobias Brunner 2022-03-14 16:54:13 +01:00
parent 96c7692661
commit 7bde56a9bc
7 changed files with 89 additions and 1 deletions

View File

@ -1309,6 +1309,17 @@ METHOD(crypto_tester_t, test_kdf, bool,
{
goto failure;
}
if (kdf_has_fixed_output_length(alg))
{
if (kdf->get_length(kdf) != vector->out.len)
{
goto failure;
}
}
else if (kdf->get_length(kdf) != SIZE_MAX)
{
goto failure;
}
/* allocated bytes */
if (!kdf->allocate_bytes(kdf, vector->out.len, &out))
{
@ -1318,6 +1329,19 @@ METHOD(crypto_tester_t, test_kdf, bool,
{
goto failure;
}
/* allocate without knowing the length */
if (kdf_has_fixed_output_length(alg))
{
chunk_free(&out);
if (!kdf->allocate_bytes(kdf, 0, &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))

View File

@ -26,3 +26,17 @@ ENUM(key_derivation_function_names, KDF_UNDEFINED, KDF_PRF_PLUS,
"KDF_UNDEFINED",
"KDF_PRF_PLUS",
);
/*
* Described in header
*/
bool kdf_has_fixed_output_length(key_derivation_function_t type)
{
switch (type)
{
case KDF_PRF_PLUS:
case KDF_UNDEFINED:
break;
}
return FALSE;
}

View File

@ -85,9 +85,18 @@ struct kdf_t {
*/
key_derivation_function_t (*get_type)(kdf_t *this);
/**
* Output length for KDFs that produce a fixed amount of output.
*
* @return fixed output length, SIZE_MAX for variable length
*/
size_t (*get_length)(kdf_t *this);
/**
* Derives a key of the given length and writes it to the buffer.
*
* @note Fails if out_len doesn't match for KDFs with fixed output length.
*
* @param out_len number of key bytes requested
* @param buffer pointer where the derived key will be written
* @return TRUE if key derived successfully
@ -98,7 +107,12 @@ struct kdf_t {
/**
* Derives a key of the given length and allocates space for it.
*
* @param out_len number of key bytes requested
* @note Fails if out_len doesn't match for KDFs with fixed output length.
* However, for simplified usage, 0 can be passed for out_len to
* automatically allocate a chunk of the correct size.
*
* @param out_len number of key bytes requested, or 0 for KDFs with fixed
* output length
* @param chunk chunk which will hold the derived key
* @return TRUE if key derived successfully
*/
@ -121,4 +135,12 @@ struct kdf_t {
void (*destroy)(kdf_t *this);
};
/**
* Check if the given KDF type has a fixed output length.
*
* @param type KDF type
* @return TRUE if the KDF type has a fixed output length
*/
bool kdf_has_fixed_output_length(key_derivation_function_t type);
#endif /** KDF_H_ @}*/

View File

@ -71,6 +71,12 @@ METHOD(kdf_t, get_type, key_derivation_function_t,
return KDF_PRF_PLUS;
}
METHOD(kdf_t, get_length, size_t,
private_kdf_t *this)
{
return SIZE_MAX;
}
METHOD(kdf_t, get_bytes, bool,
private_kdf_t *this, size_t out_len, uint8_t *buffer)
{
@ -162,6 +168,7 @@ kdf_t *botan_kdf_create(key_derivation_function_t algo, va_list args)
INIT(this,
.public = {
.get_type = _get_type,
.get_length = _get_length,
.get_bytes = _get_bytes,
.allocate_bytes = _allocate_bytes,
.set_param = _set_param,

View File

@ -51,6 +51,12 @@ METHOD(kdf_t, get_type, key_derivation_function_t,
return KDF_PRF_PLUS;
}
METHOD(kdf_t, get_length, size_t,
private_kdf_t *this)
{
return SIZE_MAX;
}
METHOD(kdf_t, get_bytes, bool,
private_kdf_t *this, size_t out_len, uint8_t *buffer)
{
@ -156,6 +162,7 @@ kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args)
INIT(this,
.public = {
.get_type = _get_type,
.get_length = _get_length,
.get_bytes = _get_bytes,
.allocate_bytes = _allocate_bytes,
.set_param = _set_param,

View File

@ -66,6 +66,12 @@ METHOD(kdf_t, get_type, key_derivation_function_t,
return KDF_PRF_PLUS;
}
METHOD(kdf_t, get_length, size_t,
private_kdf_t *this)
{
return SIZE_MAX;
}
METHOD(kdf_t, get_bytes, bool,
private_kdf_t *this, size_t out_len, uint8_t *buffer)
{
@ -153,6 +159,7 @@ kdf_t *openssl_kdf_create(key_derivation_function_t algo, va_list args)
INIT(this,
.public = {
.get_type = _get_type,
.get_length = _get_length,
.get_bytes = _get_bytes,
.allocate_bytes = _allocate_bytes,
.set_param = _set_param,

View File

@ -64,6 +64,12 @@ METHOD(kdf_t, get_type, key_derivation_function_t,
return KDF_PRF_PLUS;
}
METHOD(kdf_t, get_length, size_t,
private_kdf_t *this)
{
return SIZE_MAX;
}
METHOD(kdf_t, get_bytes, bool,
private_kdf_t *this, size_t out_len, uint8_t *buffer)
{
@ -141,6 +147,7 @@ kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args)
INIT(this,
.public = {
.get_type = _get_type,
.get_length = _get_length,
.get_bytes = _get_bytes,
.allocate_bytes = _allocate_bytes,
.set_param = _set_param,