]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add HKDF algorithms with fixed digests.
authorDaniel Van Geest <daniel.vangeest@cryptonext-security.com>
Thu, 3 Apr 2025 09:45:20 +0000 (10:45 +0100)
committerPauli <ppzgs1@gmail.com>
Thu, 10 Jul 2025 01:13:21 +0000 (11:13 +1000)
Add HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 which are versions
of HKDF that have the digest pre-set. The digest cannot be changed
for contexts of these types.

RFC 8619 defines algorithm identifiers for these combinations.
These algorithm identifiers will be used in future features, e.g.
KEMRecipientInfo.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/27247)

17 files changed:
CHANGES.md
crypto/objects/obj_dat.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
fuzz/oids.txt
include/openssl/core_names.h.in
include/openssl/obj_mac.h
providers/defltprov.c
providers/fips/fipsprov.c
providers/implementations/exchange/kdf_exch.c
providers/implementations/include/prov/implementations.h
providers/implementations/include/prov/names.h
providers/implementations/kdfs/hkdf.c
test/evp_kdf_test.c
test/recipes/20-test_kdf.t
test/recipes/30-test_evp_data/evpkdf_hkdf.txt
test/recipes/30-test_evp_data/evppkey_kdf_hkdf.txt

index e21a6e52edde5d1a2a754db66140dae81e082749..1b1b6bac2fb9e3347c5f281730f0ea14d4a604ac 100644 (file)
@@ -112,6 +112,11 @@ OpenSSL 3.6
 
    *Dimitri John Ledkov*
 
+ * HKDF with (SHA-256,SHA-384,SHA-512) has assigned OIDs. Added ability to load
+   HKDF configured with these explicit digests by name or OID.
+
+   *Daniel Van Geest (CryptoNext Security)*
+
 OpenSSL 3.5
 -----------
 
index dcd0f3f41c4543d0423df728fb8c73bee32f5620..5b6a97c6fbb06f22eac4fff8350235ed11843578 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
-static const unsigned char so[9517] = {
+static const unsigned char so[9550] = {
     0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
@@ -1348,9 +1348,12 @@ static const unsigned char so[9517] = {
     0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2C,  /* [ 9489] OBJ_SLH_DSA_SHAKE_192f_WITH_SHAKE256 */
     0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2D,  /* [ 9498] OBJ_SLH_DSA_SHAKE_256s_WITH_SHAKE256 */
     0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2E,  /* [ 9507] OBJ_SLH_DSA_SHAKE_256f_WITH_SHAKE256 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1C,  /* [ 9516] OBJ_HKDF_SHA256 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1D,  /* [ 9527] OBJ_HKDF_SHA384 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1E,  /* [ 9538] OBJ_HKDF_SHA512 */
 };
 
-#define NUM_NID 1496
+#define NUM_NID 1499
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2848,9 +2851,12 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"AES-128-CBC-HMAC-SHA512-ETM", "aes-128-cbc-hmac-sha512-etm", NID_aes_128_cbc_hmac_sha512_etm},
     {"AES-192-CBC-HMAC-SHA512-ETM", "aes-192-cbc-hmac-sha512-etm", NID_aes_192_cbc_hmac_sha512_etm},
     {"AES-256-CBC-HMAC-SHA512-ETM", "aes-256-cbc-hmac-sha512-etm", NID_aes_256_cbc_hmac_sha512_etm},
+    {"id-alg-hkdf-with-sha256", "HKDF-SHA256", NID_HKDF_SHA256, 11, &so[9516]},
+    {"id-alg-hkdf-with-sha384", "HKDF-SHA384", NID_HKDF_SHA384, 11, &so[9527]},
+    {"id-alg-hkdf-with-sha512", "HKDF-SHA512", NID_HKDF_SHA512, 11, &so[9538]},
 };
 
-#define NUM_SN 1487
+#define NUM_SN 1490
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -3480,6 +3486,9 @@ static const unsigned int sn_objs[NUM_SN] = {
      323,    /* "id-alg-des40" */
      326,    /* "id-alg-dh-pop" */
      325,    /* "id-alg-dh-sig-hmac-sha1" */
+    1496,    /* "id-alg-hkdf-with-sha256" */
+    1497,    /* "id-alg-hkdf-with-sha384" */
+    1498,    /* "id-alg-hkdf-with-sha512" */
     1456,    /* "id-alg-ml-kem-1024" */
     1454,    /* "id-alg-ml-kem-512" */
     1455,    /* "id-alg-ml-kem-768" */
@@ -4341,7 +4350,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1289,    /* "zstd" */
 };
 
-#define NUM_LN 1487
+#define NUM_LN 1490
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -4468,6 +4477,9 @@ static const unsigned int ln_objs[NUM_LN] = {
     1472,    /* "HASH-ML-DSA-44-WITH-SHA512" */
     1473,    /* "HASH-ML-DSA-65-WITH-SHA512" */
     1474,    /* "HASH-ML-DSA-87-WITH-SHA512" */
+    1496,    /* "HKDF-SHA256" */
+    1497,    /* "HKDF-SHA384" */
+    1498,    /* "HKDF-SHA512" */
     1156,    /* "HMAC DSTU Gost 34311-95" */
      988,    /* "HMAC GOST 34.11-2012 256 bit" */
      989,    /* "HMAC GOST 34.11-2012 512 bit" */
@@ -5832,7 +5844,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 1344
+#define NUM_OBJ 1347
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -7145,6 +7157,9 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      247,    /* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
      125,    /* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
      893,    /* OBJ_id_alg_PWRI_KEK              1 2 840 113549 1 9 16 3 9 */
+    1496,    /* OBJ_HKDF_SHA256                  1 2 840 113549 1 9 16 3 28 */
+    1497,    /* OBJ_HKDF_SHA384                  1 2 840 113549 1 9 16 3 29 */
+    1498,    /* OBJ_HKDF_SHA512                  1 2 840 113549 1 9 16 3 30 */
      248,    /* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
      249,    /* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
      250,    /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
index 15bd8909e8eebb4d4c1fe2c578e028400741555b..842b024dcc0284f89b0c20fdb428b2d9b1314258 100644 (file)
@@ -1493,3 +1493,6 @@ aes_256_cbc_hmac_sha256_etm               1492
 aes_128_cbc_hmac_sha512_etm            1493
 aes_192_cbc_hmac_sha512_etm            1494
 aes_256_cbc_hmac_sha512_etm            1495
+HKDF_SHA256            1496
+HKDF_SHA384            1497
+HKDF_SHA512            1498
index 6afeefff60876ac662cca3b8c6f9ded4d64004ce..bbd757b8cf1bca150023610fab1e37795456e6f3 100644 (file)
@@ -336,6 +336,9 @@ id-smime-alg 5              : id-smime-alg-ESDH
 id-smime-alg 6         : id-smime-alg-CMS3DESwrap
 id-smime-alg 7         : id-smime-alg-CMSRC2wrap
 id-smime-alg 9         : id-alg-PWRI-KEK
+id-smime-alg 28                : id-alg-hkdf-with-sha256       : HKDF-SHA256
+id-smime-alg 29                : id-alg-hkdf-with-sha384       : HKDF-SHA384
+id-smime-alg 30                : id-alg-hkdf-with-sha512       : HKDF-SHA512
 
 # S/MIME Certificate Distribution
 id-smime-cd 1          : id-smime-cd-ldap
index 307e92ea513d2a3fad63e5b7aee6159ac3bb052d..29a801ae37bef0ab18435786a2dbf53a8e1e83f2 100644 (file)
@@ -1344,3 +1344,6 @@ OBJ_SLH_DSA_SHAKE_192s_WITH_SHAKE256="\x60\x86\x48\x01\x65\x03\x04\x03\x2B"
 OBJ_SLH_DSA_SHAKE_192f_WITH_SHAKE256="\x60\x86\x48\x01\x65\x03\x04\x03\x2C"
 OBJ_SLH_DSA_SHAKE_256s_WITH_SHAKE256="\x60\x86\x48\x01\x65\x03\x04\x03\x2D"
 OBJ_SLH_DSA_SHAKE_256f_WITH_SHAKE256="\x60\x86\x48\x01\x65\x03\x04\x03\x2E"
+OBJ_HKDF_SHA256="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1C"
+OBJ_HKDF_SHA384="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1D"
+OBJ_HKDF_SHA512="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1E"
index d53cac43327caff4366e20bc80ee482784867bdf..66f796c03a28954277c152d896321713419183e0 100644 (file)
@@ -66,6 +66,9 @@ extern "C" {
 
 /* Known KDF names */
 # define OSSL_KDF_NAME_HKDF           "HKDF"
+# define OSSL_KDF_NAME_HKDF_SHA256    "HKDF-SHA256"
+# define OSSL_KDF_NAME_HKDF_SHA384    "HKDF-SHA384"
+# define OSSL_KDF_NAME_HKDF_SHA512    "HKDF-SHA512"
 # define OSSL_KDF_NAME_TLS1_3_KDF     "TLS13-KDF"
 # define OSSL_KDF_NAME_PBKDF1         "PBKDF1"
 # define OSSL_KDF_NAME_PBKDF2         "PBKDF2"
index 8326216f67f233a63a7a537b4c9888aea6f7ad51..a2f4bc01605e3a6876498efc3482d44ff6138188 100644 (file)
 #define NID_id_alg_PWRI_KEK             893
 #define OBJ_id_alg_PWRI_KEK             OBJ_id_smime_alg,9L
 
+#define SN_HKDF_SHA256          "id-alg-hkdf-with-sha256"
+#define LN_HKDF_SHA256          "HKDF-SHA256"
+#define NID_HKDF_SHA256         1496
+#define OBJ_HKDF_SHA256         OBJ_id_smime_alg,28L
+
+#define SN_HKDF_SHA384          "id-alg-hkdf-with-sha384"
+#define LN_HKDF_SHA384          "HKDF-SHA384"
+#define NID_HKDF_SHA384         1497
+#define OBJ_HKDF_SHA384         OBJ_id_smime_alg,29L
+
+#define SN_HKDF_SHA512          "id-alg-hkdf-with-sha512"
+#define LN_HKDF_SHA512          "HKDF-SHA512"
+#define NID_HKDF_SHA512         1498
+#define OBJ_HKDF_SHA512         OBJ_id_smime_alg,30L
+
 #define SN_id_smime_cd_ldap             "id-smime-cd-ldap"
 #define NID_id_smime_cd_ldap            248
 #define OBJ_id_smime_cd_ldap            OBJ_id_smime_cd,1L
index 7e3c354de0f17eae3d8607c631b732c24c854db1..412737296c65045604e2c186bc991511666ecdc7 100644 (file)
@@ -358,6 +358,9 @@ static const OSSL_ALGORITHM deflt_macs[] = {
 
 static const OSSL_ALGORITHM deflt_kdfs[] = {
     { PROV_NAMES_HKDF, "provider=default", ossl_kdf_hkdf_functions },
+    { PROV_NAMES_HKDF_SHA256, "provider=default", ossl_kdf_hkdf_sha256_functions },
+    { PROV_NAMES_HKDF_SHA384, "provider=default", ossl_kdf_hkdf_sha384_functions },
+    { PROV_NAMES_HKDF_SHA512, "provider=default", ossl_kdf_hkdf_sha512_functions },
     { PROV_NAMES_TLS1_3_KDF, "provider=default",
       ossl_kdf_tls1_3_kdf_functions },
     { PROV_NAMES_SSKDF, "provider=default", ossl_kdf_sskdf_functions },
@@ -395,6 +398,9 @@ static const OSSL_ALGORITHM deflt_keyexch[] = {
 #endif
     { PROV_NAMES_TLS1_PRF, "provider=default", ossl_kdf_tls1_prf_keyexch_functions },
     { PROV_NAMES_HKDF, "provider=default", ossl_kdf_hkdf_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA256, "provider=default", ossl_kdf_hkdf_sha256_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA384, "provider=default", ossl_kdf_hkdf_sha384_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA512, "provider=default", ossl_kdf_hkdf_sha512_keyexch_functions },
     { PROV_NAMES_SCRYPT, "provider=default",
       ossl_kdf_scrypt_keyexch_functions },
     { NULL, NULL, NULL }
@@ -583,6 +589,12 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
       PROV_DESCS_TLS1_PRF_SIGN },
     { PROV_NAMES_HKDF, "provider=default", ossl_kdf_keymgmt_functions,
       PROV_DESCS_HKDF_SIGN },
+    { PROV_NAMES_HKDF_SHA256, "provider=default", ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA256_SIGN },
+    { PROV_NAMES_HKDF_SHA384, "provider=default", ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA384_SIGN },
+    { PROV_NAMES_HKDF_SHA512, "provider=default", ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA512_SIGN },
     { PROV_NAMES_SCRYPT, "provider=default", ossl_kdf_keymgmt_functions,
       PROV_DESCS_SCRYPT_SIGN },
     { PROV_NAMES_HMAC, "provider=default", ossl_mac_legacy_keymgmt_functions,
index 5f9745ce5ad47b4c270e9a7f7bcbae777bd08516..5a1e11c03f3623d9d94f475106f806338994c998 100644 (file)
@@ -404,6 +404,9 @@ static const OSSL_ALGORITHM fips_macs_internal[] = {
 
 static const OSSL_ALGORITHM fips_kdfs[] = {
     { PROV_NAMES_HKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_functions },
+    { PROV_NAMES_HKDF_SHA256, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha256_functions },
+    { PROV_NAMES_HKDF_SHA384, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha384_functions },
+    { PROV_NAMES_HKDF_SHA512, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha512_functions },
     { PROV_NAMES_TLS1_3_KDF, FIPS_DEFAULT_PROPERTIES,
       ossl_kdf_tls1_3_kdf_functions },
     { PROV_NAMES_SSKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_sskdf_functions },
@@ -445,6 +448,9 @@ static const OSSL_ALGORITHM fips_keyexch[] = {
     { PROV_NAMES_TLS1_PRF, FIPS_DEFAULT_PROPERTIES,
       ossl_kdf_tls1_prf_keyexch_functions },
     { PROV_NAMES_HKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA256, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha256_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA384, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha384_keyexch_functions },
+    { PROV_NAMES_HKDF_SHA512, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_sha512_keyexch_functions },
     { NULL, NULL, NULL }
 };
 
@@ -612,6 +618,12 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
       PROV_DESCS_TLS1_PRF_SIGN },
     { PROV_NAMES_HKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions,
       PROV_DESCS_HKDF_SIGN },
+    { PROV_NAMES_HKDF_SHA256, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA256_SIGN },
+    { PROV_NAMES_HKDF_SHA384, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA384_SIGN },
+    { PROV_NAMES_HKDF_SHA512, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions,
+      PROV_DESCS_HKDF_SHA512_SIGN },
     { PROV_NAMES_HMAC, FIPS_DEFAULT_PROPERTIES, ossl_mac_legacy_keymgmt_functions,
       PROV_DESCS_HMAC_SIGN },
 #ifndef OPENSSL_NO_CMAC
index 340a2663c588ee820ec8d5ee49b590f4967efc35..5e363737b0e20dc6acce0d401e8b0842cd3045aa 100644 (file)
@@ -79,6 +79,9 @@ err:
 
 KDF_NEWCTX(tls1_prf, "TLS1-PRF")
 KDF_NEWCTX(hkdf, "HKDF")
+KDF_NEWCTX(hkdf_sha256, "HKDF-SHA256")
+KDF_NEWCTX(hkdf_sha384, "HKDF-SHA384")
+KDF_NEWCTX(hkdf_sha512, "HKDF-SHA512")
 KDF_NEWCTX(scrypt, "SCRYPT")
 
 static int kdf_init(void *vpkdfctx, void *vkdf, const OSSL_PARAM params[])
@@ -206,6 +209,9 @@ static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx,
 
 KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
 KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF")
+KDF_SETTABLE_CTX_PARAMS(hkdf_sha256, "HKDF-SHA256")
+KDF_SETTABLE_CTX_PARAMS(hkdf_sha384, "HKDF-SHA384")
+KDF_SETTABLE_CTX_PARAMS(hkdf_sha512, "HKDF-SHA512")
 KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
 
 static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx,
@@ -234,6 +240,9 @@ static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx,
 
 KDF_GETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
 KDF_GETTABLE_CTX_PARAMS(hkdf, "HKDF")
+KDF_GETTABLE_CTX_PARAMS(hkdf_sha256, "HKDF-SHA256")
+KDF_GETTABLE_CTX_PARAMS(hkdf_sha384, "HKDF-SHA384")
+KDF_GETTABLE_CTX_PARAMS(hkdf_sha512, "HKDF-SHA512")
 KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
 
 #define KDF_KEYEXCH_FUNCTIONS(funcname) \
@@ -254,4 +263,7 @@ KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
 
 KDF_KEYEXCH_FUNCTIONS(tls1_prf)
 KDF_KEYEXCH_FUNCTIONS(hkdf)
+KDF_KEYEXCH_FUNCTIONS(hkdf_sha256)
+KDF_KEYEXCH_FUNCTIONS(hkdf_sha384)
+KDF_KEYEXCH_FUNCTIONS(hkdf_sha512)
 KDF_KEYEXCH_FUNCTIONS(scrypt)
index 311e5f3869335fa96fbce3af91e91ef900632a34..e2a3cd543c5f3cf167242dfc5010865883073e7e 100644 (file)
@@ -287,6 +287,9 @@ extern const OSSL_DISPATCH ossl_kdf_scrypt_functions[];
 #endif
 extern const OSSL_DISPATCH ossl_kdf_tls1_prf_functions[];
 extern const OSSL_DISPATCH ossl_kdf_hkdf_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha256_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha384_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha512_functions[];
 extern const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[];
 extern const OSSL_DISPATCH ossl_kdf_sshkdf_functions[];
 extern const OSSL_DISPATCH ossl_kdf_sskdf_functions[];
@@ -374,6 +377,9 @@ extern const OSSL_DISPATCH ossl_x448_keyexch_functions[];
 #endif
 extern const OSSL_DISPATCH ossl_kdf_tls1_prf_keyexch_functions[];
 extern const OSSL_DISPATCH ossl_kdf_hkdf_keyexch_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha256_keyexch_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha384_keyexch_functions[];
+extern const OSSL_DISPATCH ossl_kdf_hkdf_sha512_keyexch_functions[];
 extern const OSSL_DISPATCH ossl_kdf_scrypt_keyexch_functions[];
 
 /* Signature */
index 34e1147b2b76a487d2088d9cd5e3b6730f7b9b02..aaf9808a3ba4e227565a7e6fddaf6c8b887d3386 100644 (file)
  */
 #define PROV_NAMES_HKDF "HKDF"
 #define PROV_DESCS_HKDF_SIGN "OpenSSL HKDF via EVP_PKEY implementation"
+#define PROV_NAMES_HKDF_SHA256 "HKDF-SHA256:id-alg-hkdf-with-sha256:1.2.840.113549.1.9.16.3.28"
+#define PROV_DESCS_HKDF_SHA256_SIGN "OpenSSL HKDF-SHA256 via EVP_PKEY implementation"
+#define PROV_NAMES_HKDF_SHA384 "HKDF-SHA384:id-alg-hkdf-with-sha384:1.2.840.113549.1.9.16.3.29"
+#define PROV_DESCS_HKDF_SHA384_SIGN "OpenSSL HKDF-SHA384 via EVP_PKEY implementation"
+#define PROV_NAMES_HKDF_SHA512 "HKDF-SHA512:id-alg-hkdf-with-sha512:1.2.840.113549.1.9.16.3.30"
+#define PROV_DESCS_HKDF_SHA512_SIGN "OpenSSL HKDF-SHA512 via EVP_PKEY implementation"
 #define PROV_NAMES_TLS1_3_KDF "TLS13-KDF"
 #define PROV_NAMES_SSKDF "SSKDF"
 #define PROV_NAMES_PBKDF1 "PBKDF1"
index f5306d606823f9a2a041954dfdeb307daaccfeee..bfe8d8d533fab17148e78fbc83b26c4160d6b90a 100644 (file)
@@ -51,6 +51,13 @@ static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params;
 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params;
 static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_tls1_3_gettable_ctx_params;
 static OSSL_FUNC_kdf_get_ctx_params_fn kdf_tls1_3_get_ctx_params;
+static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha256_new;
+static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha384_new;
+static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha512_new;
+static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_fixed_digest_settable_ctx_params;
+static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_fixed_digest_set_ctx_params;
+
+static void *kdf_hkdf_fixed_digest_new(void *provctx, const char *digest);
 
 static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
                 const unsigned char *salt, size_t salt_len,
@@ -66,12 +73,14 @@ static int HKDF_Expand(const EVP_MD *evp_md,
                        const unsigned char *info, size_t info_len,
                        unsigned char *okm, size_t okm_len);
 
-/* Settable context parameters that are common across HKDF and the TLS KDF */
-#define HKDF_COMMON_SETTABLES                                       \
+/*
+ * Settable context parameters that are common across HKDF (including
+ * implementations with a default digest) and the TLS KDF
+ */
+#define HKDF_COMMON_SETTABLES_NO_DIGEST                             \
     OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),           \
     OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),                      \
     OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),     \
-    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),         \
     OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),           \
     OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0)
 
@@ -476,6 +485,83 @@ const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {
     OSSL_DISPATCH_END
 };
 
+static void *kdf_hkdf_fixed_digest_new(void *provctx, const char *digest)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
+    KDF_HKDF *ctx;
+    OSSL_PARAM params[2];
+
+    ctx = kdf_hkdf_new(provctx);
+    if (ctx == NULL)
+        return NULL;
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
+                                                 (char *)digest, 0);
+    params[1] = OSSL_PARAM_construct_end();
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) {
+        kdf_hkdf_free(ctx);
+        return NULL;
+    }
+
+    return ctx;
+}
+
+#define KDF_HKDF_FIXED_DIGEST_NEW(hashname, hashstring) \
+    static void *kdf_hkdf_##hashname##_new(void *provctx) \
+    { \
+        return kdf_hkdf_fixed_digest_new(provctx, hashstring); \
+    }
+
+KDF_HKDF_FIXED_DIGEST_NEW(sha256, "SHA256")
+KDF_HKDF_FIXED_DIGEST_NEW(sha384, "SHA384")
+KDF_HKDF_FIXED_DIGEST_NEW(sha512, "SHA512")
+
+static const OSSL_PARAM *kdf_hkdf_fixed_digest_settable_ctx_params(ossl_unused void *ctx,
+                                                                   ossl_unused void *provctx)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        HKDF_COMMON_SETTABLES_NO_DIGEST,
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_hkdf_fixed_digest_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+        /*
+         * TODO: OPENSSL MAINTAINERS: should it fail an any attempt to set the digest or
+         * should it be allowed to set the digest to the current digest?
+         */
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
+                       "Setting the digest is not supported for fixed-digest HKDFs");
+        return 0;
+    }
+
+    return kdf_hkdf_set_ctx_params(vctx, params);
+}
+
+#define MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(hashname) \
+    const OSSL_DISPATCH ossl_kdf_hkdf_##hashname##_functions[] = { \
+        { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_##hashname##_new }, \
+        { OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup }, \
+        { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free }, \
+        { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset }, \
+        { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive }, \
+        { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, \
+          (void(*)(void))kdf_hkdf_fixed_digest_settable_ctx_params }, \
+        { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_fixed_digest_set_ctx_params }, \
+        { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_hkdf_gettable_ctx_params }, \
+        { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params }, \
+        OSSL_DISPATCH_END \
+    };
+
+MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha256)
+MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha384)
+MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha512)
+
 /*
  * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
  * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and
index 1de2cff02a39895c4bc5402a844207053eb4bff8..ddbb4fc147430d0042786984f6b5e1ba714cca70 100644 (file)
@@ -240,7 +240,42 @@ static int test_kdf_hkdf(void)
     return ret;
 }
 
-static int do_kdf_hkdf_gettables(int extract_only, int has_digest)
+static int kdf_hkdf_fixed_digest(const char *kdf_name, char *digest)
+{
+    int ret;
+    EVP_KDF_CTX *kctx1 = NULL;
+    EVP_KDF_CTX *kctx2 = NULL;
+    unsigned char out1[10];
+    unsigned char out2[10];
+    OSSL_PARAM *params1;
+    OSSL_PARAM *params2;
+
+    params1 = construct_hkdf_params(digest, "secret", 6, "salt", "label");
+    params2 = construct_hkdf_params(NULL, "secret", 6, "salt", "label");
+
+    ret = TEST_ptr(params1)
+        && TEST_ptr(params2)
+        && TEST_ptr(kctx1 = get_kdfbyname(OSSL_KDF_NAME_HKDF))
+        && TEST_ptr(kctx2 = get_kdfbyname(kdf_name))
+        && TEST_int_gt(EVP_KDF_derive(kctx1, out1, sizeof(out1), params1), 0)
+        && TEST_int_gt(EVP_KDF_derive(kctx2, out2, sizeof(out2), params2), 0)
+        && TEST_mem_eq(out1, sizeof(out1), out2, sizeof(out2));
+
+    EVP_KDF_CTX_free(kctx1);
+    EVP_KDF_CTX_free(kctx2);
+    OPENSSL_free(params1);
+    OPENSSL_free(params2);
+    return ret;
+}
+
+static int test_kdf_hkdf_fixed_digest(void)
+{
+    return kdf_hkdf_fixed_digest(OSSL_KDF_NAME_HKDF_SHA256, "sha256")
+        && kdf_hkdf_fixed_digest(OSSL_KDF_NAME_HKDF_SHA384, "sha384")
+        && kdf_hkdf_fixed_digest(OSSL_KDF_NAME_HKDF_SHA512, "sha512");
+}
+
+static int do_kdf_hkdf_gettables(int expand_only, int has_digest)
 {
     int ret = 0;
     size_t sz = 0;
@@ -352,6 +387,31 @@ static int test_kdf_hkdf_invalid_digest(void)
     return ret;
 }
 
+static int kdf_hkdf_fixed_digest_change_digest(const char *kdf_name, char *digest)
+{
+    int ret;
+    EVP_KDF_CTX *kctx = NULL;
+    OSSL_PARAM *params;
+
+    /* It is not allowed to change the digest in a fixed-digest KDF */
+    params = construct_hkdf_params(digest, "secret", 6, "salt", "label");
+
+    ret = TEST_ptr(params)
+        && TEST_ptr(kctx = get_kdfbyname(kdf_name))
+        && TEST_false(EVP_KDF_CTX_set_params(kctx, params));
+
+    EVP_KDF_CTX_free(kctx);
+    OPENSSL_free(params);
+    return ret;
+}
+
+static int test_kdf_hkdf_fixed_digest_change_digest(void)
+{
+    return kdf_hkdf_fixed_digest_change_digest(OSSL_KDF_NAME_HKDF_SHA256, "sha256")
+        && kdf_hkdf_fixed_digest_change_digest(OSSL_KDF_NAME_HKDF_SHA384, "sha384")
+        && kdf_hkdf_fixed_digest_change_digest(OSSL_KDF_NAME_HKDF_SHA512, "sha512");
+}
+
 static int test_kdf_hkdf_derive_set_params_fail(void)
 {
     int ret = 0, i = 0;
@@ -2096,7 +2156,9 @@ int setup_tests(void)
     ADD_TEST(test_kdf_tls1_prf_empty_seed);
     ADD_TEST(test_kdf_tls1_prf_1byte_seed);
     ADD_TEST(test_kdf_hkdf);
+    ADD_TEST(test_kdf_hkdf_fixed_digest);
     ADD_TEST(test_kdf_hkdf_invalid_digest);
+    ADD_TEST(test_kdf_hkdf_fixed_digest_change_digest);
     ADD_TEST(test_kdf_hkdf_zero_output_size);
     ADD_TEST(test_kdf_hkdf_empty_key);
     ADD_TEST(test_kdf_hkdf_1byte_key);
index 44b066497c64679ed238207ae2ea73f63f22dc75..de5c6e379e801a17325cddf753eed2f32be2e25f 100755 (executable)
@@ -25,6 +25,9 @@ my @kdf_tests = (
     { cmd => [qw{openssl kdf -keylen 10 -digest SHA256 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF}],
       expected => '2a:c4:36:9f:52:59:96:f8:de:13',
       desc => 'HKDF SHA256' },
+    { cmd => [qw{openssl kdf -keylen 10 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF-SHA256}],
+      expected => '2a:c4:36:9f:52:59:96:f8:de:13',
+      desc => 'HKDF-SHA256' },
     { cmd => [qw{openssl kdf -keylen 25 -digest SHA256 -kdfopt pass:passwordPASSWORDpassword -kdfopt salt:saltSALTsaltSALTsaltSALTsaltSALTsalt -kdfopt iter:4096 PBKDF2}],
       expected => '34:8C:89:DB:CB:D3:2B:2F:32:D8:14:B8:11:6E:84:CF:2B:17:34:7E:BC:18:00:18:1C',
       desc => 'PBKDF2 SHA256'},
index c617f2cc44092731de0fb40abf3f3d2cf4fb5d9d..71ae8c6f71acbfe494020b2231e56d7170a03ebc 100644 (file)
@@ -20,6 +20,12 @@ Ctrl.salt = hexsalt:000102030405060708090a0b0c
 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
 Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
 
+KDF = HKDF-SHA256
+Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+Ctrl.salt = hexsalt:000102030405060708090a0b0c
+Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
+Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
+
 KDF = HKDF
 Ctrl.mode = mode:EXTRACT_ONLY
 Ctrl.digest = digest:SHA256
index 1fb24720012bb75ad88cc427877e4eb9b6a01df4..932ada897e717a3cee6996872fa2f974ff24308b 100644 (file)
@@ -20,6 +20,12 @@ Ctrl.salt = hexsalt:000102030405060708090a0b0c
 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
 Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
 
+PKEYKDF = HKDF-SHA256
+Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+Ctrl.salt = hexsalt:000102030405060708090a0b0c
+Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
+Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
+
 PKEYKDF = HKDF
 Ctrl.mode = mode:EXTRACT_ONLY
 Ctrl.md = md:SHA256