From: Tobias Brunner Date: Mon, 14 Mar 2022 15:54:13 +0000 (+0100) Subject: crypto: Adapt kdf_t interface to support KDFs with fixed output length X-Git-Tag: 5.9.6rc1~2^2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bde56a9bc7248fdc88c23879e70df58f85ef651;p=thirdparty%2Fstrongswan.git crypto: Adapt kdf_t interface to support KDFs with fixed output length --- diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index 5fd7d2ba9b..3aad7773ad 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -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)) diff --git a/src/libstrongswan/crypto/kdfs/kdf.c b/src/libstrongswan/crypto/kdfs/kdf.c index 24dcb424d4..f597629c67 100644 --- a/src/libstrongswan/crypto/kdfs/kdf.c +++ b/src/libstrongswan/crypto/kdfs/kdf.c @@ -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; +} diff --git a/src/libstrongswan/crypto/kdfs/kdf.h b/src/libstrongswan/crypto/kdfs/kdf.h index 4c1a77ecaa..2e741153e0 100644 --- a/src/libstrongswan/crypto/kdfs/kdf.h +++ b/src/libstrongswan/crypto/kdfs/kdf.h @@ -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_ @}*/ diff --git a/src/libstrongswan/plugins/botan/botan_kdf.c b/src/libstrongswan/plugins/botan/botan_kdf.c index ff375851e2..b7eeb20e45 100644 --- a/src/libstrongswan/plugins/botan/botan_kdf.c +++ b/src/libstrongswan/plugins/botan/botan_kdf.c @@ -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, diff --git a/src/libstrongswan/plugins/kdf/kdf_prf_plus.c b/src/libstrongswan/plugins/kdf/kdf_prf_plus.c index a62e8b4d40..8e3d1ccaa6 100644 --- a/src/libstrongswan/plugins/kdf/kdf_prf_plus.c +++ b/src/libstrongswan/plugins/kdf/kdf_prf_plus.c @@ -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, diff --git a/src/libstrongswan/plugins/openssl/openssl_kdf.c b/src/libstrongswan/plugins/openssl/openssl_kdf.c index 3e632476a3..9fbadc1097 100644 --- a/src/libstrongswan/plugins/openssl/openssl_kdf.c +++ b/src/libstrongswan/plugins/openssl/openssl_kdf.c @@ -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, diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c index 7a08a35033..b89c138f7d 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c @@ -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,