]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
crypto: Adapt kdf_t interface to support KDFs with fixed output length
authorTobias Brunner <tobias@strongswan.org>
Mon, 14 Mar 2022 15:54:13 +0000 (16:54 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Apr 2022 17:02:56 +0000 (19:02 +0200)
src/libstrongswan/crypto/crypto_tester.c
src/libstrongswan/crypto/kdfs/kdf.c
src/libstrongswan/crypto/kdfs/kdf.h
src/libstrongswan/plugins/botan/botan_kdf.c
src/libstrongswan/plugins/kdf/kdf_prf_plus.c
src/libstrongswan/plugins/openssl/openssl_kdf.c
src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c

index 5fd7d2ba9bf0f163b0beebff425a497b5ab7b83b..3aad7773ad291fb304cf310f0114ee9ee30bfbfb 100644 (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))
index 24dcb424d46960b2754110ee78e34224f86a85c3..f597629c67d30bb656776e88ec6d6e2f0131ea7a 100644 (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;
+}
index 4c1a77ecaaf3b96908abcaf648983bb07d27f71b..2e741153e093eb281d5bc303226054ee2a6657aa 100644 (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_ @}*/
index ff375851e2d9e3e80ff9b8d4fbae7b53adafa393..b7eeb20e45c7c03eb6c99b50c8271929a3929062 100644 (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,
index a62e8b4d40054ac39cb0344eb1b28cd9fddd7419..8e3d1ccaa61857a9494878166247b45ac4b2b233 100644 (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,
index 3e632476a39565af4fb5c1abf9376bf9c23f582e..9fbadc10971a1924e3b442f30e7ace6205a02edb 100644 (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,
index 7a08a350336dcd817ffdcb58e7755cf3668fbd83..b89c138f7dfd5b18725fca4a23b326686cd95790 100644 (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,