]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Replaced buf+size pairs with datum
authord-Dudas <david.dudas03@e-uvt.ro>
Fri, 3 Apr 2026 19:22:19 +0000 (22:22 +0300)
committerd-Dudas <david.dudas03@e-uvt.ro>
Sat, 18 Apr 2026 06:26:59 +0000 (09:26 +0300)
Also removed _gnutls_hpke prefix from
static functions.

Signed-off-by: David Dudas <david.dudas03@e-uvt.ro>
lib/hpke/hpke-builders.c
lib/hpke/hpke-builders.h
lib/hpke/hpke-hkdf.c
lib/hpke/hpke-hkdf.h
lib/hpke/hpke-key-management.c
lib/hpke/hpke-key-management.h
lib/hpke/hpke.c

index 6f96f4468238613e905fd878ed4bf9b11a145d3b..bd5daa6a55a5b6178ae788fb4056f33b2c92a4fd 100644 (file)
@@ -29,75 +29,65 @@ static const unsigned char hpke_v1_label[] = "HPKE-v1";
 static const unsigned char eae_prk_label[] = "eae_prk";
 static const unsigned char shared_secret_label[] = "shared_secret";
 
-static void _gnutls_hpke_append_buf(unsigned char *dst, size_t *dst_len,
-                                   const unsigned char *src, size_t src_len)
+static void append_datum(gnutls_datum_t *dst, const gnutls_datum_t *src)
 {
-       memcpy(dst + *dst_len, src, src_len);
-       *dst_len += src_len;
+       memcpy(dst->data + dst->size, src->data, src->size);
+       dst->size += src->size;
+}
+
+static void append_bytes(gnutls_datum_t *dst, const unsigned char *src,
+                        const size_t src_size)
+{
+       memcpy(dst->data + dst->size, src, src_size);
+       dst->size += src_size;
 }
 
 void _gnutls_hpke_build_key_context_for_scheduling(
-       const uint8_t mode, const unsigned char *psk_id_hash,
-       const size_t psk_id_hash_len, const unsigned char *info_hash,
-       const size_t info_hash_len, unsigned char *key_schedule_context_buf,
-       size_t *key_schedule_context_len)
+       const uint8_t mode, const gnutls_datum_t *psk_id_hash,
+       const gnutls_datum_t *info_hash, gnutls_datum_t *key_schedule_context)
+
 {
-       *key_schedule_context_len = 0;
-
-       _gnutls_hpke_append_buf(key_schedule_context_buf,
-                               key_schedule_context_len, &mode, 1);
-       _gnutls_hpke_append_buf(key_schedule_context_buf,
-                               key_schedule_context_len, psk_id_hash,
-                               psk_id_hash_len);
-       _gnutls_hpke_append_buf(key_schedule_context_buf,
-                               key_schedule_context_len, info_hash,
-                               info_hash_len);
+       key_schedule_context->size = 0;
+
+       append_bytes(key_schedule_context, &mode, 1);
+       append_datum(key_schedule_context, psk_id_hash);
+       append_datum(key_schedule_context, info_hash);
 }
 
-void _gnutls_hpke_build_expand_info(
-       const unsigned char *suite_id, const size_t suite_id_size,
-       const unsigned char *label, const size_t label_size,
-       const unsigned char *context, const size_t context_size, const size_t L,
-       unsigned char *expand_info_buf, size_t *expand_info_len)
+void _gnutls_hpke_build_expand_info(const gnutls_datum_t *suite_id,
+                                   const gnutls_datum_t *label,
+                                   const gnutls_datum_t *context,
+                                   const size_t L, gnutls_datum_t *expand_info)
 {
-       *expand_info_len = 0;
+       expand_info->size = 0;
 
        unsigned char L_buf[2];
        L_buf[0] = (L >> 8) & 0xff;
        L_buf[1] = L & 0xff;
 
-       _gnutls_hpke_append_buf(expand_info_buf, expand_info_len, L_buf, 2);
-       _gnutls_hpke_append_buf(expand_info_buf, expand_info_len, hpke_v1_label,
-                               sizeof(hpke_v1_label) - 1);
-       _gnutls_hpke_append_buf(expand_info_buf, expand_info_len, suite_id,
-                               suite_id_size);
-       _gnutls_hpke_append_buf(expand_info_buf, expand_info_len, label,
-                               label_size);
+       append_bytes(expand_info, L_buf, 2);
+       append_bytes(expand_info, hpke_v1_label, sizeof(hpke_v1_label) - 1);
+       append_datum(expand_info, suite_id);
+       append_datum(expand_info, label);
+
        if (context != NULL) {
-               _gnutls_hpke_append_buf(expand_info_buf, expand_info_len,
-                                       context, context_size);
+               append_datum(expand_info, context);
        }
 }
 
-void _gnutls_hpke_build_labeled_extract_key(const unsigned char *suite_id,
-                                           const size_t suite_id_size,
-                                           const unsigned char *label,
-                                           const size_t label_size,
+void _gnutls_hpke_build_labeled_extract_key(const gnutls_datum_t *suite_id,
+                                           const gnutls_datum_t *label,
                                            const gnutls_datum_t *ikm,
-                                           unsigned char *extract_key_buf,
-                                           size_t *extract_key_len)
+                                           gnutls_datum_t *extract_key)
 {
-       *extract_key_len = 0;
-
-       _gnutls_hpke_append_buf(extract_key_buf, extract_key_len, hpke_v1_label,
-                               sizeof(hpke_v1_label) - 1);
-       _gnutls_hpke_append_buf(extract_key_buf, extract_key_len, suite_id,
-                               suite_id_size);
-       _gnutls_hpke_append_buf(extract_key_buf, extract_key_len, label,
-                               label_size);
+       extract_key->size = 0;
+
+       append_bytes(extract_key, hpke_v1_label, sizeof(hpke_v1_label) - 1);
+       append_datum(extract_key, suite_id);
+       append_datum(extract_key, label);
+
        if (ikm != NULL) {
-               _gnutls_hpke_append_buf(extract_key_buf, extract_key_len,
-                                       ikm->data, ikm->size);
+               append_datum(extract_key, ikm);
        }
 }
 
@@ -111,53 +101,39 @@ void _gnutls_hpke_build_kem_suite_id(const uint16_t kem_id,
        suite_id[4] = kem_id & 0xff;
 }
 
-void _gnutls_hpke_build_ikm_label(const unsigned char *suite_id,
-                                 const size_t suite_id_size,
-                                 const unsigned char *dh, const size_t dh_size,
-                                 unsigned char *ikm_label_buf,
-                                 size_t *ikm_label_len)
+void _gnutls_hpke_build_ikm_label(const gnutls_datum_t *suite_id,
+                                 const gnutls_datum_t *dh,
+                                 gnutls_datum_t *ikm_label)
 {
-       *ikm_label_len = 0;
-
-       _gnutls_hpke_append_buf(ikm_label_buf, ikm_label_len, hpke_v1_label,
-                               sizeof(hpke_v1_label) - 1);
-       _gnutls_hpke_append_buf(ikm_label_buf, ikm_label_len, suite_id,
-                               suite_id_size);
-       _gnutls_hpke_append_buf(ikm_label_buf, ikm_label_len, eae_prk_label,
-                               sizeof(eae_prk_label) - 1);
-       _gnutls_hpke_append_buf(ikm_label_buf, ikm_label_len, dh, dh_size);
+       ikm_label->size = 0;
+
+       append_bytes(ikm_label, hpke_v1_label, sizeof(hpke_v1_label) - 1);
+       append_datum(ikm_label, suite_id);
+       append_bytes(ikm_label, eae_prk_label, sizeof(eae_prk_label) - 1);
+       append_datum(ikm_label, dh);
 }
 
-void _gnutls_hpke_build_info_label(
-       const unsigned char *receiver_pubkey_raw,
-       size_t receiver_pubkey_raw_size, const unsigned char *sender_pubkey_raw,
-       size_t sender_pubkey_raw_size,
-       const unsigned char *ephemeral_pubkey_raw,
-       size_t ephemeral_pubkey_raw_size, const unsigned char *suite_id,
-       const size_t suite_id_size, const uint16_t Nsecret,
-       unsigned char *info_label_buf, size_t *info_label_len)
+void _gnutls_hpke_build_info_label(const gnutls_datum_t *pkR_raw,
+                                  const gnutls_datum_t *pkS_raw,
+                                  const gnutls_datum_t *pkE_raw,
+                                  const gnutls_datum_t *suite_id,
+                                  const uint16_t Nh,
+                                  gnutls_datum_t *info_label)
 {
-       *info_label_len = 0;
-
-       unsigned char Nsecret_buf[2];
-       Nsecret_buf[0] = (Nsecret >> 8) & 0xff;
-       Nsecret_buf[1] = Nsecret & 0xff;
-
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len, Nsecret_buf, 2);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len, hpke_v1_label,
-                               sizeof(hpke_v1_label) - 1);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len, suite_id,
-                               suite_id_size);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len,
-                               shared_secret_label,
-                               sizeof(shared_secret_label) - 1);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len,
-                               ephemeral_pubkey_raw,
-                               ephemeral_pubkey_raw_size);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len,
-                               receiver_pubkey_raw, receiver_pubkey_raw_size);
-       _gnutls_hpke_append_buf(info_label_buf, info_label_len,
-                               sender_pubkey_raw, sender_pubkey_raw_size);
+       info_label->size = 0;
+
+       unsigned char Nh_buf[2];
+       Nh_buf[0] = (Nh >> 8) & 0xff;
+       Nh_buf[1] = Nh & 0xff;
+
+       append_bytes(info_label, Nh_buf, 2);
+       append_bytes(info_label, hpke_v1_label, sizeof(hpke_v1_label) - 1);
+       append_datum(info_label, suite_id);
+       append_bytes(info_label, shared_secret_label,
+                    sizeof(shared_secret_label) - 1);
+       append_datum(info_label, pkE_raw);
+       append_datum(info_label, pkR_raw);
+       append_datum(info_label, pkS_raw);
 }
 
 void _gnutls_hpke_build_suite_id_for_scheduling(const uint16_t kem_id,
index 4b87f94e80bd2e0c6daa1b409792ad26402df33c..cea23df4ed57c778e75ec12a9242bb232785bc9b 100644 (file)
 #include <stdint.h>
 
 void _gnutls_hpke_build_key_context_for_scheduling(
-       const uint8_t mode, const unsigned char *psk_id_hash,
-       const size_t psk_id_hash_len, const unsigned char *info_hash,
-       const size_t info_hash_len, unsigned char *key_schedule_context_buf,
-       size_t *key_schedule_context_len);
+       const uint8_t mode, const gnutls_datum_t *psk_id_hash,
+       const gnutls_datum_t *info_hash, gnutls_datum_t *key_schedule_context);
 
-void _gnutls_hpke_build_expand_info(
-       const unsigned char *suite_id, const size_t suite_id_size,
-       const unsigned char *label, const size_t label_size,
-       const unsigned char *context, const size_t context_size, const size_t L,
-       unsigned char *expand_info_buf, size_t *expand_info_len);
+void _gnutls_hpke_build_expand_info(const gnutls_datum_t *suite_id,
+                                   const gnutls_datum_t *label,
+                                   const gnutls_datum_t *context,
+                                   const size_t L,
+                                   gnutls_datum_t *expand_info);
 
-void _gnutls_hpke_build_labeled_extract_key(const unsigned char *suite_id,
-                                           const size_t suite_id_size,
-                                           const unsigned char *label,
-                                           const size_t label_size,
+void _gnutls_hpke_build_labeled_extract_key(const gnutls_datum_t *suite_id,
+                                           const gnutls_datum_t *label,
                                            const gnutls_datum_t *ikm,
-                                           unsigned char *extract_key_buf,
-                                           size_t *extract_key_len);
+                                           gnutls_datum_t *extract_key);
 
 void _gnutls_hpke_build_kem_suite_id(const uint16_t kem_id,
                                     unsigned char *suite_id);
 
-void _gnutls_hpke_build_ikm_label(const unsigned char *suite_id,
-                                 const size_t suite_id_size,
-                                 const unsigned char *dh, const size_t dh_size,
-                                 unsigned char *ikm_label_buf,
-                                 size_t *ikm_label_len);
+void _gnutls_hpke_build_ikm_label(const gnutls_datum_t *suite_id,
+                                 const gnutls_datum_t *dh,
+                                 gnutls_datum_t *ikm_label);
 
-void _gnutls_hpke_build_info_label(
-       const unsigned char *receiver_pubkey_raw,
-       size_t receiver_pubkey_raw_size, const unsigned char *sender_pubkey_raw,
-       size_t sender_pubkey_raw_size,
-       const unsigned char *ephemeral_pubkey_raw,
-       size_t ephemeral_pubkey_raw_size, const unsigned char *suite_id,
-       const size_t suite_id_size, const uint16_t Nsecret,
-       unsigned char *info_label_buf, size_t *info_label_len);
+void _gnutls_hpke_build_info_label(const gnutls_datum_t *pkR_raw,
+                                  const gnutls_datum_t *pkS_raw,
+                                  const gnutls_datum_t *pkE_raw,
+                                  const gnutls_datum_t *suite_id,
+                                  const uint16_t Nh,
+                                  gnutls_datum_t *info_label);
 
 void _gnutls_hpke_build_suite_id_for_scheduling(const uint16_t kem_id,
                                                const uint16_t kdf_id,
index d7b78c00acf86cbf6e3ac9486b0b0e855c141b3b..f3e3cd9f09e8ef5780a7f8df9b90579edb8c271f 100644 (file)
 
 #define HPKE_MAX_EXTRACT_KEY_SIZE 94
 
-int _gnutls_hpke_labeled_extract(
-       const gnutls_mac_algorithm_t mac, const unsigned char *suite_id,
-       const size_t suite_id_size, const unsigned char *salt,
-       const size_t salt_size, const unsigned char *label,
-       const size_t label_size, const gnutls_datum_t *ikm,
-       unsigned char *hash_out_buf, size_t *hash_out_len)
+int _gnutls_hpke_labeled_extract(const gnutls_mac_algorithm_t mac,
+                                const gnutls_datum_t *suite_id,
+                                const gnutls_datum_t *salt,
+                                const gnutls_datum_t *label,
+                                const gnutls_datum_t *ikm, gnutls_datum_t *out)
 {
-       int ret;
        unsigned char extract_key_buf[HPKE_MAX_EXTRACT_KEY_SIZE] = { 0 };
-       size_t extract_key_size = 0;
+       gnutls_datum_t extract_key = { extract_key_buf, 0 };
 
-       size_t hash_size = gnutls_hmac_get_len(mac);
-       if (hash_size == 0) {
+       out->size = gnutls_hmac_get_len(mac);
+       if (out->size == 0) {
                return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
        }
 
-       _gnutls_hpke_build_labeled_extract_key(suite_id, suite_id_size, label,
-                                              label_size, ikm, extract_key_buf,
-                                              &extract_key_size);
+       _gnutls_hpke_build_labeled_extract_key(suite_id, label, ikm,
+                                              &extract_key);
 
-       gnutls_datum_t extract_key = { extract_key_buf, extract_key_size };
-       gnutls_datum_t salt_datum = { (unsigned char *)salt, salt_size };
-       ret = gnutls_hkdf_extract(mac, &extract_key, &salt_datum, hash_out_buf);
+       int ret = gnutls_hkdf_extract(mac, &extract_key, salt, out->data);
        if (ret < 0) {
+               out->size = 0;
                gnutls_assert_val(ret);
        }
-       *hash_out_len = hash_size;
 
-       gnutls_memset(extract_key_buf, 0, extract_key_size);
+       zeroize_key(extract_key.data, extract_key.size);
 
        return ret;
 }
index cbe15f947f53c7755e37009e4515e8a542bf8e46..1832e6295b6968e062fc7dd049f92412d117daa5 100644 (file)
 
 #include <gnutls/gnutls.h>
 
-int _gnutls_hpke_labeled_extract(
-       const gnutls_mac_algorithm_t mac, const unsigned char *suite_id,
-       const size_t suite_id_size, const unsigned char *salt,
-       const size_t salt_size, const unsigned char *label,
-       const size_t label_size, const gnutls_datum_t *ikm,
-       unsigned char *hash_out_buf, size_t *hash_out_len);
+int _gnutls_hpke_labeled_extract(const gnutls_mac_algorithm_t mac,
+                                const gnutls_datum_t *suite_id,
+                                const gnutls_datum_t *salt,
+                                const gnutls_datum_t *label,
+                                const gnutls_datum_t *ikm,
+                                gnutls_datum_t *out);
 
 #endif /* HPKE_HKDF_HELPER_H */
index 77be400b7f19a6821ea1dc1ccb29aab1374679a3..3373496e0d02c7b70f7595d7c2ffef02ca9941fa 100644 (file)
 #define GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE 66
 #define GNUTLS_HPKE_MAX_MONTGOMERY_KEY_SIZE 56
 
-static const unsigned char dkp_prk_label[] = "dkp_prk";
-static const unsigned char sk_label[] = "sk";
-static const unsigned char candidate_label[] = "candidate";
-
 static const unsigned char p256_order[32] = {
        0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
@@ -62,24 +58,22 @@ static const unsigned char p521_order[66] = {
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 };
 
-static void _gnutls_hpke_coord_pad_left_to_buf(const gnutls_datum_t *in,
-                                              size_t out_size,
-                                              unsigned char *out)
+static void coord_pad_left_to_buf(const gnutls_datum_t *in, size_t out_size,
+                                 unsigned char *out)
 {
        gnutls_memset(out, 0, out_size - in->size);
        memcpy(out + (out_size - in->size), in->data, in->size);
 }
 
 int _gnutls_hpke_pubkey_to_datum(const gnutls_pubkey_t pk,
-                                unsigned char *pubkey_raw,
-                                size_t *pubkey_raw_size)
+                                gnutls_datum_t *pubkey_raw)
 {
        int ret;
        gnutls_ecc_curve_t curve;
        gnutls_datum_t x = { NULL, 0 };
        gnutls_datum_t y = { NULL, 0 };
 
-       *pubkey_raw_size = 0;
+       pubkey_raw->size = 0;
 
        ret = gnutls_pubkey_export_ecc_raw2(pk, &curve, &x, &y,
                                            GNUTLS_EXPORT_FLAG_NO_LZ);
@@ -94,8 +88,8 @@ int _gnutls_hpke_pubkey_to_datum(const gnutls_pubkey_t pk,
                        goto cleanup;
                }
 
-               memcpy(pubkey_raw, x.data, x.size);
-               *pubkey_raw_size = x.size;
+               memcpy(pubkey_raw->data, x.data, x.size);
+               pubkey_raw->size = x.size;
                goto cleanup;
        }
 
@@ -107,29 +101,24 @@ int _gnutls_hpke_pubkey_to_datum(const gnutls_pubkey_t pk,
                goto cleanup;
        }
 
-       _gnutls_hpke_coord_pad_left_to_buf(&x, coord_size, pubkey_raw + 1);
-       _gnutls_hpke_coord_pad_left_to_buf(&y, coord_size,
-                                          pubkey_raw + 1 + coord_size);
+       coord_pad_left_to_buf(&x, coord_size, pubkey_raw->data + 1);
+       coord_pad_left_to_buf(&y, coord_size,
+                             pubkey_raw->data + 1 + coord_size);
 
-       pubkey_raw[0] = 0x04;
-       *pubkey_raw_size = total_size;
-       ret = 0;
+       pubkey_raw->data[0] = 0x04;
+       pubkey_raw->size = total_size;
 
 cleanup:
-       if (x.data != NULL) {
-               gnutls_free(x.data);
-       }
-
-       if (y.data != NULL) {
-               gnutls_free(y.data);
-       }
+       _gnutls_free_datum(&x);
+       _gnutls_free_datum(&y);
 
        return ret;
 }
 
-static int _gnutls_hpke_extract_coordinates_from_pubkey_datum(
-       const gnutls_ecc_curve_t curve, const gnutls_datum_t *datum,
-       unsigned char *x, size_t *x_size, unsigned char *y, size_t *y_size)
+static int extract_coordinates_from_pubkey_datum(const gnutls_ecc_curve_t curve,
+                                                const gnutls_datum_t *datum,
+                                                gnutls_datum_t *x,
+                                                gnutls_datum_t *y)
 {
        const size_t coord_size = gnutls_ecc_curve_get_size(curve);
 
@@ -144,18 +133,18 @@ static int _gnutls_hpke_extract_coordinates_from_pubkey_datum(
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               memcpy(x, datum->data, coord_size);
-               *x_size = coord_size;
+               memcpy(x->data, datum->data, coord_size);
+               x->size = coord_size;
        } else {
                if (datum->size != 1 + 2 * coord_size ||
                    datum->data[0] != 0x04) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               memcpy(x, datum->data + 1, coord_size);
-               *x_size = coord_size;
-               memcpy(y, datum->data + 1 + coord_size, coord_size);
-               *y_size = coord_size;
+               memcpy(x->data, datum->data + 1, coord_size);
+               x->size = coord_size;
+               memcpy(y->data, datum->data + 1 + coord_size, coord_size);
+               y->size = coord_size;
        }
 
        return 0;
@@ -166,13 +155,14 @@ int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                                 gnutls_pubkey_t *pk)
 {
        int ret;
-       unsigned char x[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
-       size_t x_size = 0;
-       unsigned char y[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
-       size_t y_size = 0;
 
-       ret = _gnutls_hpke_extract_coordinates_from_pubkey_datum(
-               curve, datum, x, &x_size, y, &y_size);
+       unsigned char x_buf[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
+       unsigned char y_buf[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
+
+       gnutls_datum_t x = { x_buf, 0 };
+       gnutls_datum_t y = { y_buf, 0 };
+
+       ret = extract_coordinates_from_pubkey_datum(curve, datum, &x, &y);
        if (ret < 0) {
                return gnutls_assert_val(ret);
        }
@@ -182,9 +172,7 @@ int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                return gnutls_assert_val(ret);
        }
 
-       gnutls_datum_t x_datum = { x, x_size };
-       gnutls_datum_t y_datum = { y, y_size };
-       ret = gnutls_pubkey_import_ecc_raw(*pk, curve, &x_datum, &y_datum);
+       ret = gnutls_pubkey_import_ecc_raw(*pk, curve, &x, &y);
        if (ret < 0) {
                gnutls_assert_val(ret);
                gnutls_pubkey_deinit(*pk);
@@ -195,8 +183,7 @@ int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
        return ret;
 }
 
-static void _gnutls_hpke_clamp_sk(const gnutls_hpke_kem_t kem,
-                                 unsigned char *sk_buf)
+static void clamp_sk(const gnutls_hpke_kem_t kem, unsigned char *sk_buf)
 {
        switch (kem) {
        case GNUTLS_HPKE_KEM_DHKEM_X25519: {
@@ -215,15 +202,14 @@ static void _gnutls_hpke_clamp_sk(const gnutls_hpke_kem_t kem,
        }
 }
 
-static int
-_gnutls_hpke_derive_montgomery_curve_public_key(const gnutls_hpke_kem_t kem,
-                                               const gnutls_datum_t *priv_raw,
-                                               unsigned char *pub_raw)
+static int derive_montgomery_curve_public_key(const gnutls_hpke_kem_t kem,
+                                             const gnutls_datum_t *priv_raw,
+                                             unsigned char *pub_raw)
 {
        uint8_t k[GNUTLS_HPKE_MAX_MONTGOMERY_KEY_SIZE];
 
        memcpy(k, priv_raw->data, priv_raw->size);
-       _gnutls_hpke_clamp_sk(kem, k);
+       clamp_sk(kem, k);
 
        switch (kem) {
        case GNUTLS_HPKE_KEM_DHKEM_X25519: {
@@ -238,57 +224,56 @@ _gnutls_hpke_derive_montgomery_curve_public_key(const gnutls_hpke_kem_t kem,
                break;
        }
 
-       gnutls_memset(k, 0, sizeof(k));
+       zeroize_key(k, sizeof(k));
        return 0;
 }
 
-static int _gnutls_hpke_montgomery_curve_keypair_from_raw_privkey(
+static int montgomery_curve_keypair_from_raw_privkey(
        const gnutls_mac_algorithm_t mac, const gnutls_hpke_kem_t kem,
        const gnutls_datum_t *dkp_prk, const gnutls_ecc_curve_t curve,
-       const unsigned char *suite_id, size_t suite_id_size,
-       gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey)
+       const gnutls_datum_t *suite_id, gnutls_privkey_t *privkey,
+       gnutls_pubkey_t *pubkey)
 {
        int ret;
-       unsigned char labeled_expand_info[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
-               0
-       };
-       size_t labeled_expand_info_size = 0;
+       unsigned char
+               labeled_expand_info_buf[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
+                       0
+               };
        unsigned char sk_buf[GNUTLS_HPKE_MAX_MONTGOMERY_KEY_SIZE] = { 0 };
-       size_t sk_size = 0;
 
-       sk_size = gnutls_ecc_curve_get_size(curve);
-       if (sk_size == 0) {
+       gnutls_datum_t labeled_expand_info = { labeled_expand_info_buf, 0 };
+       gnutls_datum_t sk = { sk_buf, 0 };
+
+       sk.size = gnutls_ecc_curve_get_size(curve);
+       if (sk.size == 0) {
                ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
                goto cleanup;
        }
 
-       _gnutls_hpke_build_expand_info(suite_id, suite_id_size, sk_label,
-                                      sizeof(sk_label) - 1, NULL, 0, sk_size,
-                                      labeled_expand_info,
-                                      &labeled_expand_info_size);
-       gnutls_datum_t labeled_expand_info_datum = { labeled_expand_info,
-                                                    labeled_expand_info_size };
-       ret = gnutls_hkdf_expand(mac, dkp_prk, &labeled_expand_info_datum,
-                                sk_buf, sk_size);
+       const gnutls_datum_t sk_label = { (void *)"sk", sizeof("sk") - 1 };
+
+       _gnutls_hpke_build_expand_info(suite_id, &sk_label, NULL, sk.size,
+                                      &labeled_expand_info);
+       ret = gnutls_hkdf_expand(mac, dkp_prk, &labeled_expand_info, sk.data,
+                                sk.size);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       _gnutls_hpke_clamp_sk(kem, sk_buf);
+       clamp_sk(kem, sk.data);
        ret = gnutls_privkey_init(privkey);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       gnutls_datum_t k = { sk_buf, sk_size };
        unsigned char pk_buf[32];
 
-       _gnutls_hpke_derive_montgomery_curve_public_key(kem, &k, pk_buf);
+       derive_montgomery_curve_public_key(kem, &sk, pk_buf);
 
        gnutls_datum_t x = { pk_buf, 32 };
-       ret = gnutls_privkey_import_ecc_raw(*privkey, curve, &x, NULL, &k);
+       ret = gnutls_privkey_import_ecc_raw(*privkey, curve, &x, NULL, &sk);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto error;
@@ -309,25 +294,18 @@ static int _gnutls_hpke_montgomery_curve_keypair_from_raw_privkey(
        goto cleanup;
 
 error:
-       if (privkey != NULL && *privkey != NULL) {
-               gnutls_privkey_deinit(*privkey);
-               *privkey = NULL;
-       }
-
-       if (pubkey != NULL && *pubkey != NULL) {
-               gnutls_pubkey_deinit(*pubkey);
-               *pubkey = NULL;
-       }
+       gnutls_privkey_deinit(*privkey);
+       gnutls_pubkey_deinit(*pubkey);
 
 cleanup:
 
-       gnutls_memset(sk_buf, 0, sizeof(sk_buf));
-       gnutls_memset(labeled_expand_info, 0, sizeof(labeled_expand_info));
+       zeroize_key(sk.data, sk.size);
+       zeroize_key(labeled_expand_info.data, labeled_expand_info.size);
 
        return ret;
 }
 
-static int _gnutls_hpke_is_all_zero(const unsigned char *buf, size_t len)
+static int is_all_zero(const unsigned char *buf, size_t len)
 {
        size_t i;
        unsigned char acc = 0;
@@ -338,8 +316,7 @@ static int _gnutls_hpke_is_all_zero(const unsigned char *buf, size_t len)
        return acc == 0;
 }
 
-static const unsigned char *
-_gnutls_hpke_get_kem_order(const gnutls_hpke_kem_t kem)
+static const unsigned char *get_kem_order(const gnutls_hpke_kem_t kem)
 {
        switch (kem) {
        case GNUTLS_HPKE_KEM_DHKEM_P256:
@@ -353,8 +330,7 @@ _gnutls_hpke_get_kem_order(const gnutls_hpke_kem_t kem)
        }
 }
 
-static int _gnutls_hpke_be_lt(const unsigned char *a, const unsigned char *b,
-                             size_t len)
+static int be_lt(const unsigned char *a, const unsigned char *b, size_t len)
 {
        size_t i;
 
@@ -368,10 +344,9 @@ static int _gnutls_hpke_be_lt(const unsigned char *a, const unsigned char *b,
        return 0;
 }
 
-static int
-_gnutls_hpke_get_ecc_and_curve_len_for_curve(const gnutls_ecc_curve_t curve,
-                                            const struct ecc_curve **ecc,
-                                            size_t *coord_size)
+static int get_ecc_and_curve_len_for_curve(const gnutls_ecc_curve_t curve,
+                                          const struct ecc_curve **ecc,
+                                          size_t *coord_size)
 {
        switch (curve) {
        case GNUTLS_ECC_CURVE_SECP256R1:
@@ -393,32 +368,31 @@ _gnutls_hpke_get_ecc_and_curve_len_for_curve(const gnutls_ecc_curve_t curve,
        return 0;
 }
 
-static int _gnutls_hpke_export_pubkey_coordinate(const size_t coord_size,
-                                                mpz_t p, unsigned char *p_raw,
-                                                size_t *p_raw_size)
+static int export_pubkey_coordinate(const size_t coord_size, mpz_t p,
+                                   gnutls_datum_t *raw)
 {
        unsigned char tmp[66];
        size_t count = 0;
 
        memset(tmp, 0, sizeof(tmp));
-       memset(p_raw, 0, coord_size);
+       memset(raw->data, 0, coord_size);
 
        mpz_export(tmp, &count, 1, 1, 1, 0, p);
        if (count > coord_size) {
                return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
        }
 
-       memcpy(p_raw + (coord_size - count), tmp, count);
-       *p_raw_size = coord_size;
+       memcpy(raw->data + (coord_size - count), tmp, count);
+       raw->size = coord_size;
 
-       gnutls_memset(tmp, 0, sizeof(tmp));
+       zeroize_key(tmp, sizeof(tmp));
 
        return 0;
 }
 
-static int _gnutls_hpke_derive_raw_public_key_for_prime_curve(
-       const gnutls_ecc_curve_t curve, const gnutls_datum_t *priv_raw,
-       unsigned char *x, size_t *x_len, unsigned char *y, size_t *y_len)
+static int raw_public_key_for_prime_curve(const gnutls_ecc_curve_t curve,
+                                         const gnutls_datum_t *priv_raw,
+                                         gnutls_datum_t *x, gnutls_datum_t *y)
 {
        int ret = 0;
        const struct ecc_curve *ecc = NULL;
@@ -430,14 +404,13 @@ static int _gnutls_hpke_derive_raw_public_key_for_prime_curve(
        int point_inited = 0;
        int mpz_inited = 0;
 
-       ret = _gnutls_hpke_get_ecc_and_curve_len_for_curve(curve, &ecc,
-                                                          &coord_len);
+       ret = get_ecc_and_curve_len_for_curve(curve, &ecc, &coord_len);
        if (ret < 0) {
                return gnutls_assert_val(ret);
        }
 
-       *x_len = 0;
-       *y_len = 0;
+       x->size = 0;
+       y->size = 0;
 
        mpz_init(k);
        mpz_init(px);
@@ -460,13 +433,13 @@ static int _gnutls_hpke_derive_raw_public_key_for_prime_curve(
        ecc_point_mul_g(&p, &s);
        ecc_point_get(&p, px, py);
 
-       ret = _gnutls_hpke_export_pubkey_coordinate(coord_len, px, x, x_len);
+       ret = export_pubkey_coordinate(coord_len, px, x);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_export_pubkey_coordinate(coord_len, py, y, y_len);
+       ret = export_pubkey_coordinate(coord_len, py, y);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto cleanup;
@@ -488,40 +461,39 @@ cleanup:
        return ret;
 }
 
-static int _gnutls_hpke_prime_curve_keypair_from_raw_privkey(
+static int prime_curve_keypair_from_raw_privkey(
        const gnutls_mac_algorithm_t mac, const gnutls_hpke_kem_t kem,
        const gnutls_datum_t *dkp_prk, const gnutls_ecc_curve_t curve,
-       const unsigned char *suite_id, size_t suite_id_size,
-       gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey)
+       const gnutls_datum_t *suite_id, gnutls_privkey_t *privkey,
+       gnutls_pubkey_t *pubkey)
 {
        int ret;
-       unsigned char labeled_expand_info[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
-               0
-       };
-       size_t labeled_expand_info_size = 0;
+       unsigned char
+               labeled_expand_info_buf[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
+                       0
+               };
        unsigned char sk_buf[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE] = { 0 };
-       size_t sk_size = 0;
 
-       sk_size = gnutls_ecc_curve_get_size(curve);
-       if (sk_size == 0) {
+       gnutls_datum_t labeled_expand_info = { labeled_expand_info_buf, 0 };
+       gnutls_datum_t sk = { sk_buf, 0 };
+
+       sk.size = gnutls_ecc_curve_get_size(curve);
+       if (sk.size == 0) {
                ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
                goto cleanup;
        }
 
+       const gnutls_datum_t candidate_label = { (void *)"candidate",
+                                                sizeof("candidate") - 1 };
+
        for (size_t counter = 0; counter < 256; counter++) {
-               _gnutls_hpke_build_expand_info(suite_id, suite_id_size,
-                                              candidate_label,
-                                              sizeof(candidate_label) - 1,
-                                              (unsigned char *)&counter, 1,
-                                              sk_size, labeled_expand_info,
-                                              &labeled_expand_info_size);
-               gnutls_datum_t labeled_expand_info_datum = {
-                       labeled_expand_info, labeled_expand_info_size
-               };
+               gnutls_datum_t context = { (void *)&counter, 1 };
+               _gnutls_hpke_build_expand_info(suite_id, &candidate_label,
+                                              &context, sk.size,
+                                              &labeled_expand_info);
 
-               ret = gnutls_hkdf_expand(mac, dkp_prk,
-                                        &labeled_expand_info_datum, sk_buf,
-                                        sk_size);
+               ret = gnutls_hkdf_expand(mac, dkp_prk, &labeled_expand_info,
+                                        sk.data, sk.size);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto cleanup;
@@ -531,17 +503,17 @@ static int _gnutls_hpke_prime_curve_keypair_from_raw_privkey(
                        sk_buf[0] &= 0x01;
                }
 
-               if (_gnutls_hpke_is_all_zero(sk_buf, sk_size)) {
+               if (is_all_zero(sk.data, sk.size)) {
                        continue;
                }
 
-               const unsigned char *order = _gnutls_hpke_get_kem_order(kem);
+               const unsigned char *order = get_kem_order(kem);
                if (order == NULL) {
                        ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
                        goto cleanup;
                }
 
-               ret = _gnutls_hpke_be_lt(sk_buf, order, sk_size);
+               ret = be_lt(sk.data, order, sk.size);
                if (!ret) {
                        continue;
                }
@@ -552,22 +524,20 @@ static int _gnutls_hpke_prime_curve_keypair_from_raw_privkey(
                        goto cleanup;
                }
 
-               gnutls_datum_t k = { sk_buf, sk_size };
                unsigned char x_buf[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
-               size_t x_buf_len = 0;
                unsigned char y_buf[GNUTLS_HPKE_MAX_RAW_KEY_COORDINATE_SIZE];
-               size_t y_buf_len = 0;
-               ret = _gnutls_hpke_derive_raw_public_key_for_prime_curve(
-                       curve, &k, x_buf, &x_buf_len, y_buf, &y_buf_len);
+
+               gnutls_datum_t x = { x_buf, 0 };
+               gnutls_datum_t y = { y_buf, 0 };
+
+               ret = raw_public_key_for_prime_curve(curve, &sk, &x, &y);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto error;
                }
 
-               gnutls_datum_t x = { x_buf, x_buf_len };
-               gnutls_datum_t y = { y_buf, y_buf_len };
                ret = gnutls_privkey_import_ecc_raw(*privkey, curve, &x, &y,
-                                                   &k);
+                                                   &sk);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto error;
@@ -591,20 +561,12 @@ static int _gnutls_hpke_prime_curve_keypair_from_raw_privkey(
        goto cleanup;
 
 error:
-       if (privkey != NULL && *privkey != NULL) {
-               gnutls_privkey_deinit(*privkey);
-               *privkey = NULL;
-       }
-
-       if (pubkey != NULL && *pubkey != NULL) {
-               gnutls_pubkey_deinit(*pubkey);
-               *pubkey = NULL;
-       }
+       gnutls_privkey_deinit(*privkey);
+       gnutls_pubkey_deinit(*pubkey);
 
 cleanup:
-
-       gnutls_memset(sk_buf, 0, sizeof(sk_buf));
-       gnutls_memset(labeled_expand_info, 0, sizeof(labeled_expand_info));
+       zeroize_key(sk.data, sk.size);
+       zeroize_key(labeled_expand_info.data, labeled_expand_info.size);
 
        return ret;
 }
@@ -616,7 +578,7 @@ int _gnutls_hpke_keypair_from_ikm(const gnutls_hpke_kem_t kem,
 {
        int ret;
        unsigned char dkp_prk_buf[HPKE_MAX_HASH_SIZE] = { 0 };
-       size_t dkp_prk_len = 0;
+       gnutls_datum_t dkp_prk = { dkp_prk_buf, 0 };
 
        const gnutls_mac_algorithm_t mac = _gnutls_hpke_kem_to_mac(kem);
        if (mac == GNUTLS_MAC_UNKNOWN) {
@@ -633,45 +595,44 @@ int _gnutls_hpke_keypair_from_ikm(const gnutls_hpke_kem_t kem,
        unsigned char suite_id_buf[HPKE_SUITE_ID_SIZE] = { 0 };
        _gnutls_hpke_build_kem_suite_id(kem, suite_id_buf);
 
-       ret = _gnutls_hpke_labeled_extract(
-               mac, suite_id_buf, HPKE_SUITE_ID_SIZE, NULL, 0, dkp_prk_label,
-               sizeof(dkp_prk_label) - 1, ikme, dkp_prk_buf, &dkp_prk_len);
+       gnutls_datum_t suite_id = { suite_id_buf, HPKE_SUITE_ID_SIZE };
+       gnutls_datum_t dkp_prk_label = { (void *)"dkp_prk",
+                                        sizeof("dkp_prk") - 1 };
+
+       ret = _gnutls_hpke_labeled_extract(mac, &suite_id, NULL, &dkp_prk_label,
+                                          ikme, &dkp_prk);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       gnutls_datum_t dkp_prk = { dkp_prk_buf, dkp_prk_len };
-
        switch (kem) {
        case GNUTLS_HPKE_KEM_DHKEM_X448:
        case GNUTLS_HPKE_KEM_DHKEM_X25519:
-               ret = _gnutls_hpke_montgomery_curve_keypair_from_raw_privkey(
-                       mac, kem, &dkp_prk, curve, suite_id_buf,
-                       HPKE_SUITE_ID_SIZE, privkey, pubkey);
+               ret = montgomery_curve_keypair_from_raw_privkey(
+                       mac, kem, &dkp_prk, curve, &suite_id, privkey, pubkey);
                break;
        case GNUTLS_HPKE_KEM_DHKEM_P256:
        case GNUTLS_HPKE_KEM_DHKEM_P384:
        case GNUTLS_HPKE_KEM_DHKEM_P521:
-               ret = _gnutls_hpke_prime_curve_keypair_from_raw_privkey(
-                       mac, kem, &dkp_prk, curve, suite_id_buf,
-                       HPKE_SUITE_ID_SIZE, privkey, pubkey);
+               ret = prime_curve_keypair_from_raw_privkey(
+                       mac, kem, &dkp_prk, curve, &suite_id, privkey, pubkey);
                break;
        default:
                ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
 cleanup:
-
-       gnutls_memset(dkp_prk_buf, 0, dkp_prk_len);
+       zeroize_key(dkp_prk.data, dkp_prk.size);
 
        return ret;
 }
 
-static int _gnutls_hpke_generate_new_keypair(
-       const gnutls_ecc_curve_t curve, const gnutls_hpke_kem_t kem,
-       const gnutls_pk_algorithm_t pk_algo,
-       gnutls_privkey_t *ephemeral_privkey, gnutls_pubkey_t *ephemeral_pubkey)
+static int generate_new_keypair(const gnutls_ecc_curve_t curve,
+                               const gnutls_hpke_kem_t kem,
+                               const gnutls_pk_algorithm_t pk_algo,
+                               gnutls_privkey_t *ephemeral_privkey,
+                               gnutls_pubkey_t *ephemeral_pubkey)
 {
        int ret;
 
@@ -729,9 +690,8 @@ int _gnutls_hpke_generate_keypair(const gnutls_datum_t *ikme,
                        return ret;
                }
 
-               ret = _gnutls_hpke_generate_new_keypair(curve, kem, pk_algo,
-                                                       ephemeral_privkey,
-                                                       ephemeral_pubkey);
+               ret = generate_new_keypair(curve, kem, pk_algo,
+                                          ephemeral_privkey, ephemeral_pubkey);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        return ret;
index 24a870b9d86acf940fbb9d769829f69ebb788cf9..53695a0f19e41e3b87d1af73fcfbbc4fa2084c4a 100644 (file)
@@ -36,8 +36,7 @@
 #define HPKE_MAX_LABELED_EXPAND_INFO_SIZE 158
 
 int _gnutls_hpke_pubkey_to_datum(const gnutls_pubkey_t pk,
-                                unsigned char *pubkey_raw,
-                                size_t *pubkey_raw_size);
+                                gnutls_datum_t *pubkey_raw);
 
 int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                                 const gnutls_datum_t *datum,
index ddf4bdde9a2e079ad891bf23037a546e04bd06af..8f58081e664789da1e78fa1ecf20f79ba9f61ee1 100644 (file)
 
 #include "errors.h"
 
-static const unsigned char psk_id_hash_label[] = "psk_id_hash";
-static const unsigned char info_hash_label[] = "info_hash";
-static const unsigned char secret_hash_label[] = "secret";
-static const unsigned char key_expand_label[] = "key";
-static const unsigned char base_nonce_expand_label[] = "base_nonce";
-static const unsigned char exporter_secret_expand_label[] = "exp";
-static const unsigned char export_secret_label[] = "sec";
+static const gnutls_datum_t info_hash_label = { (void *)"info_hash",
+                                               sizeof("info_hash") - 1 };
+static const gnutls_datum_t psk_id_hash_label = { (void *)"psk_id_hash",
+                                                 sizeof("psk_id_hash") - 1 };
+static const gnutls_datum_t secret_hash_label = { (void *)"secret",
+                                                 sizeof("secret") - 1 };
 
 #define HPKE_MAX_PARAMETER_SIZE 66
 #define HPKE_PSK_MIN_SIZE 32
@@ -76,28 +75,28 @@ struct gnutls_hpke_context_st {
        uint64_t seq;
 };
 
-static bool _gnutls_hpke_is_auth_mode(const gnutls_hpke_mode_t mode)
+static bool is_auth_mode(const gnutls_hpke_mode_t mode)
 {
        return mode == GNUTLS_HPKE_MODE_AUTH ||
               mode == GNUTLS_HPKE_MODE_AUTH_PSK;
 }
 
-static bool _gnutls_hpke_is_psk_mode(const gnutls_hpke_mode_t mode)
+static bool is_psk_mode(const gnutls_hpke_mode_t mode)
 {
        return mode == GNUTLS_HPKE_MODE_PSK ||
               mode == GNUTLS_HPKE_MODE_AUTH_PSK;
 }
 
-static bool _gnutls_is_key_curve_type_compatible_with_param_dhkem(
-       const gnutls_hpke_kem_t kem, const gnutls_ecc_curve_t curve)
+static bool
+is_key_curve_type_compatible_with_param_dhkem(const gnutls_hpke_kem_t kem,
+                                             const gnutls_ecc_curve_t curve)
 {
        const gnutls_ecc_curve_t expected_curve =
                _gnutls_hpke_kem_to_curve(kem);
        return curve == expected_curve;
 }
 
-static int _gnutls_hpke_validate_pubkey_for_kem(gnutls_pubkey_t pk,
-                                               gnutls_hpke_kem_t kem)
+static int validate_pubkey_for_kem(gnutls_pubkey_t pk, gnutls_hpke_kem_t kem)
 {
        int ret;
        gnutls_pk_algorithm_t pk_algo;
@@ -117,16 +116,14 @@ static int _gnutls_hpke_validate_pubkey_for_kem(gnutls_pubkey_t pk,
                return gnutls_assert_val(ret);
        }
 
-       if (!_gnutls_is_key_curve_type_compatible_with_param_dhkem(kem,
-                                                                  curve)) {
+       if (!is_key_curve_type_compatible_with_param_dhkem(kem, curve)) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
        return 0;
 }
 
-static int _gnutls_hpke_validate_privkey_for_kem(gnutls_privkey_t sk,
-                                                gnutls_hpke_kem_t kem)
+static int validate_privkey_for_kem(gnutls_privkey_t sk, gnutls_hpke_kem_t kem)
 {
        int ret;
        unsigned int bits = 0;
@@ -151,31 +148,38 @@ static int _gnutls_hpke_validate_privkey_for_kem(gnutls_privkey_t sk,
                return gnutls_assert_val(ret);
        }
 
-       if (!_gnutls_is_key_curve_type_compatible_with_param_dhkem(kem,
-                                                                  curve)) {
+       if (!is_key_curve_type_compatible_with_param_dhkem(kem, curve)) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
        return 0;
 }
 
-static int _gnutls_hpke_get_shared_secret(
-       const gnutls_hpke_kem_t kem, const gnutls_hpke_kdf_t kdf,
-       const gnutls_hpke_mode_t mode, const gnutls_pubkey_t receiver_pubkey,
-       const gnutls_pubkey_t sender_pubkey,
-       const gnutls_pubkey_t ephemeral_pubkey, const unsigned char *dh,
-       const size_t dh_size, unsigned char *shared_secret,
-       size_t *shared_secret_size)
+static int
+get_shared_secret(const gnutls_hpke_kem_t kem, const gnutls_hpke_kdf_t kdf,
+                 const gnutls_hpke_mode_t mode, const gnutls_pubkey_t pkR,
+                 const gnutls_pubkey_t pkS, const gnutls_pubkey_t pkE,
+                 const gnutls_datum_t *dh, gnutls_datum_t *shared_secret)
 {
        int ret = 0;
-       unsigned char receiver_pubkey_raw[HPKE_MAX_DHKEM_PUBKEY_SIZE];
-       size_t receiver_pubkey_raw_size = 0;
-       unsigned char sender_pubkey_raw[HPKE_MAX_DHKEM_PUBKEY_SIZE];
-       size_t sender_pubkey_raw_size = 0;
-       unsigned char ephemeral_pubkey_raw[HPKE_MAX_DHKEM_PUBKEY_SIZE];
-       size_t ephemeral_pubkey_raw_size = 0;
-       unsigned char info_label[HPKE_MAX_INFO_LABEL_SIZE] = { 0 };
-       size_t info_label_size = 0;
+
+       unsigned char pkR_raw_buf[HPKE_MAX_DHKEM_PUBKEY_SIZE];
+       unsigned char pkS_raw_buf[HPKE_MAX_DHKEM_PUBKEY_SIZE];
+       unsigned char pkE_raw_buf[HPKE_MAX_DHKEM_PUBKEY_SIZE];
+       unsigned char info_label_buf[HPKE_MAX_INFO_LABEL_SIZE] = { 0 };
+       unsigned char suite_id_buf[HPKE_SUITE_ID_SIZE] = { 0 };
+       unsigned char ikm_label_buf[HPKE_IKM_LABEL_MAX_SIZE];
+       unsigned char salt_buf[HPKE_MAX_SALT_SIZE] = { 0 };
+       unsigned char eae_prk_buf[HPKE_MAX_EAE_PRK_SIZE] = { 0 };
+
+       gnutls_datum_t pkR_raw = { pkR_raw_buf, 0 };
+       gnutls_datum_t pkS_raw = { pkS_raw_buf, 0 };
+       gnutls_datum_t pkE_raw = { pkE_raw_buf, 0 };
+       gnutls_datum_t info_label = { info_label_buf, 0 };
+       gnutls_datum_t suite_id = { suite_id_buf, HPKE_SUITE_ID_SIZE };
+       gnutls_datum_t ikm_label = { ikm_label_buf, 0 };
+       gnutls_datum_t salt = { salt_buf, 0 };
+       gnutls_datum_t eae_prk = { eae_prk_buf, 0 };
 
        const gnutls_mac_algorithm_t mac = _gnutls_hpke_kdf_to_mac(kdf);
        if (mac == GNUTLS_MAC_UNKNOWN) {
@@ -187,86 +191,67 @@ static int _gnutls_hpke_get_shared_secret(
                return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
        }
 
-       unsigned char suite_id[HPKE_SUITE_ID_SIZE] = { 0 };
-       _gnutls_hpke_build_kem_suite_id(kem, suite_id);
-
-       unsigned char ikm_label[HPKE_IKM_LABEL_MAX_SIZE];
-       size_t ikm_label_size = 0;
-       _gnutls_hpke_build_ikm_label(suite_id, HPKE_SUITE_ID_SIZE, dh, dh_size,
-                                    ikm_label, &ikm_label_size);
-
-       gnutls_datum_t ikm_label_datum = { ikm_label, ikm_label_size };
+       salt.size = Nh;
+       eae_prk.size = Nh;
 
-       unsigned char salt[HPKE_MAX_SALT_SIZE] = { 0 };
-       gnutls_datum_t salt_datum = { salt, Nh };
-       unsigned char eae_prk[HPKE_MAX_EAE_PRK_SIZE] = { 0 };
+       _gnutls_hpke_build_kem_suite_id(kem, suite_id.data);
+       _gnutls_hpke_build_ikm_label(&suite_id, dh, &ikm_label);
 
-       ret = gnutls_hkdf_extract(mac, &ikm_label_datum, &salt_datum, eae_prk);
+       ret = gnutls_hkdf_extract(mac, &ikm_label, &salt, eae_prk.data);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_pubkey_to_datum(ephemeral_pubkey,
-                                          ephemeral_pubkey_raw,
-                                          &ephemeral_pubkey_raw_size);
+       ret = _gnutls_hpke_pubkey_to_datum(pkE, &pkE_raw);
        if (ret != 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_pubkey_to_datum(receiver_pubkey, receiver_pubkey_raw,
-                                          &receiver_pubkey_raw_size);
+       ret = _gnutls_hpke_pubkey_to_datum(pkR, &pkR_raw);
        if (ret != 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       if (_gnutls_hpke_is_auth_mode(mode)) {
-               ret = _gnutls_hpke_pubkey_to_datum(sender_pubkey,
-                                                  sender_pubkey_raw,
-                                                  &sender_pubkey_raw_size);
+       if (is_auth_mode(mode)) {
+               ret = _gnutls_hpke_pubkey_to_datum(pkS, &pkS_raw);
                if (ret != 0) {
                        gnutls_assert_val(ret);
                        goto cleanup;
                }
        }
 
-       _gnutls_hpke_build_info_label(
-               receiver_pubkey_raw, receiver_pubkey_raw_size,
-               sender_pubkey_raw, sender_pubkey_raw_size, ephemeral_pubkey_raw,
-               ephemeral_pubkey_raw_size, suite_id, HPKE_SUITE_ID_SIZE, Nh,
-               info_label, &info_label_size);
+       _gnutls_hpke_build_info_label(&pkR_raw, &pkS_raw, &pkE_raw, &suite_id,
+                                     Nh, &info_label);
 
-       gnutls_datum_t eae_prk_datum = { eae_prk, Nh };
-       gnutls_datum_t info_label_datum = { info_label, info_label_size };
-       *shared_secret_size = Nh;
-       ret = gnutls_hkdf_expand(mac, &eae_prk_datum, &info_label_datum,
-                                shared_secret, *shared_secret_size);
+       shared_secret->size = Nh;
+       ret = gnutls_hkdf_expand(mac, &eae_prk, &info_label,
+                                shared_secret->data, shared_secret->size);
        if (ret < 0) {
-               gnutls_memset(shared_secret, 0, *shared_secret_size);
-               *shared_secret_size = 0;
+               zeroize_key(shared_secret->data, shared_secret->size);
+               shared_secret->size = 0;
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
 cleanup:
-
-       gnutls_memset(ikm_label, 0, ikm_label_size);
-       gnutls_memset(eae_prk, 0, Nh);
-       gnutls_memset(info_label, 0, info_label_size);
-       gnutls_memset(receiver_pubkey_raw, 0, receiver_pubkey_raw_size);
-       gnutls_memset(sender_pubkey_raw, 0, sender_pubkey_raw_size);
-       gnutls_memset(ephemeral_pubkey_raw, 0, ephemeral_pubkey_raw_size);
+       zeroize_key(ikm_label.data, ikm_label.size);
+       zeroize_key(eae_prk.data, eae_prk.size);
+       zeroize_key(info_label.data, info_label.size);
+       zeroize_key(pkR_raw.data, pkR_raw.size);
+       zeroize_key(pkS_raw.data, pkS_raw.size);
+       zeroize_key(pkE_raw.data, pkE_raw.size);
 
        return ret;
 }
 
-static int _gnutls_hpke_encap_get_dh(const gnutls_hpke_mode_t mode,
-                                    const gnutls_pubkey_t receiver_pubkey,
-                                    const gnutls_privkey_t ephemeral_privkey,
-                                    const gnutls_privkey_t sender_privkey,
-                                    unsigned char *dh, size_t *dh_size)
+static int encap_get_dh(const gnutls_hpke_mode_t mode,
+                       const gnutls_pubkey_t receiver_pubkey,
+                       const gnutls_privkey_t ephemeral_privkey,
+                       const gnutls_privkey_t sender_privkey,
+                       gnutls_datum_t *dh)
 {
        int ret = 0;
        gnutls_datum_t dhE = { NULL, 0 };
@@ -279,7 +264,7 @@ static int _gnutls_hpke_encap_get_dh(const gnutls_hpke_mode_t mode,
                goto cleanup;
        }
 
-       if (_gnutls_hpke_is_auth_mode(mode)) {
+       if (is_auth_mode(mode)) {
                ret = gnutls_privkey_derive_secret(
                        sender_privkey, receiver_pubkey, NULL, &dhS, 0);
                if (ret < 0) {
@@ -288,40 +273,31 @@ static int _gnutls_hpke_encap_get_dh(const gnutls_hpke_mode_t mode,
                }
        }
 
-       memcpy(dh, dhE.data, dhE.size);
-       *dh_size = dhE.size;
+       memcpy(dh->data, dhE.data, dhE.size);
+       dh->size = dhE.size;
 
-       if (_gnutls_hpke_is_auth_mode(mode)) {
-               memcpy(dh + dhE.size, dhS.data, dhS.size);
-               *dh_size += dhS.size;
+       if (is_auth_mode(mode)) {
+               memcpy(dh->data + dhE.size, dhS.data, dhS.size);
+               dh->size += dhS.size;
        }
 
 cleanup:
-       if (dhS.data != NULL) {
-               gnutls_memset(dhS.data, 0, dhS.size);
-               gnutls_free(dhS.data);
-       }
-
-       if (dhE.data != NULL) {
-               gnutls_memset(dhE.data, 0, dhE.size);
-               gnutls_free(dhE.data);
-       }
+       _gnutls_free_key_datum(&dhS);
+       _gnutls_free_key_datum(&dhE);
 
        return ret;
 }
 
-static int _gnutls_hpke_dhkem_encap(const gnutls_hpke_context_t ctx,
-                                   const gnutls_pubkey_t receiver_pubkey,
-                                   gnutls_datum_t *enc,
-                                   unsigned char *shared_secret,
-                                   size_t *shared_secret_size)
+static int dhkem_encap(const gnutls_hpke_context_t ctx,
+                      const gnutls_pubkey_t receiver_pubkey,
+                      gnutls_datum_t *enc, gnutls_datum_t *shared_secret)
 {
        int ret = 0;
        gnutls_privkey_t ephemeral_privkey = NULL;
        gnutls_pubkey_t ephemeral_pubkey = NULL;
        gnutls_pubkey_t sender_pubkey = NULL;
-       unsigned char dh[HPKE_MAX_DH_SIZE];
-       size_t dh_size = 0;
+       unsigned char dh_buf[HPKE_MAX_DH_SIZE];
+       gnutls_datum_t dh = { dh_buf, 0 };
 
        ret = _gnutls_hpke_generate_keypair(ctx->ikme, ctx->kem,
                                            receiver_pubkey, &ephemeral_privkey,
@@ -331,33 +307,31 @@ static int _gnutls_hpke_dhkem_encap(const gnutls_hpke_context_t ctx,
                goto cleanup;
        }
 
-       unsigned char pubkey_raw[HPKE_MAX_DHKEM_PUBKEY_SIZE];
-       size_t pubkey_raw_size = 0;
-       ret = _gnutls_hpke_pubkey_to_datum(ephemeral_pubkey, pubkey_raw,
-                                          &pubkey_raw_size);
+       unsigned char pubkey_raw_buffer[HPKE_MAX_DHKEM_PUBKEY_SIZE];
+       gnutls_datum_t pubkey_raw = { pubkey_raw_buffer, 0 };
+       ret = _gnutls_hpke_pubkey_to_datum(ephemeral_pubkey, &pubkey_raw);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       enc->size = pubkey_raw_size;
+       enc->size = pubkey_raw.size;
        enc->data = gnutls_malloc(enc->size);
        if (enc->data == NULL) {
                ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
                goto cleanup;
        }
 
-       memcpy(enc->data, pubkey_raw, pubkey_raw_size);
+       memcpy(enc->data, pubkey_raw.data, pubkey_raw.size);
 
-       ret = _gnutls_hpke_encap_get_dh(ctx->mode, receiver_pubkey,
-                                       ephemeral_privkey, ctx->sender_privkey,
-                                       dh, &dh_size);
+       ret = encap_get_dh(ctx->mode, receiver_pubkey, ephemeral_privkey,
+                          ctx->sender_privkey, &dh);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto error;
        }
 
-       if (_gnutls_hpke_is_auth_mode(ctx->mode)) {
+       if (is_auth_mode(ctx->mode)) {
                ret = gnutls_pubkey_init(&sender_pubkey);
                if (ret < 0) {
                        ret = gnutls_assert_val(ret);
@@ -371,14 +345,13 @@ static int _gnutls_hpke_dhkem_encap(const gnutls_hpke_context_t ctx,
                }
        }
 
-       ret = _gnutls_hpke_get_shared_secret(ctx->kem, ctx->kdf, ctx->mode,
-                                            receiver_pubkey, sender_pubkey,
-                                            ephemeral_pubkey, dh, dh_size,
-                                            shared_secret, shared_secret_size);
+       ret = get_shared_secret(ctx->kem, ctx->kdf, ctx->mode, receiver_pubkey,
+                               sender_pubkey, ephemeral_pubkey, &dh,
+                               shared_secret);
        if (ret < 0) {
-               if (*shared_secret_size > 0) {
-                       gnutls_memset(shared_secret, 0, *shared_secret_size);
-                       *shared_secret_size = 0;
+               if (shared_secret->size > 0) {
+                       zeroize_key(shared_secret, shared_secret->size);
+                       shared_secret->size = 0;
                }
                gnutls_assert_val(ret);
                goto error;
@@ -387,14 +360,10 @@ static int _gnutls_hpke_dhkem_encap(const gnutls_hpke_context_t ctx,
        goto cleanup;
 
 error:
-       if (enc != NULL && enc->data != NULL) {
-               gnutls_free(enc->data);
-               enc->data = NULL;
-               enc->size = 0;
-       }
+       _gnutls_free_key_datum(enc);
 
 cleanup:
-       gnutls_memset(dh, 0, dh_size);
+       zeroize_key(dh.data, dh.size);
 
        gnutls_pubkey_deinit(ephemeral_pubkey);
        gnutls_privkey_deinit(ephemeral_privkey);
@@ -403,11 +372,11 @@ cleanup:
        return ret;
 }
 
-static int _gnutls_hpke_decap_get_dh(const gnutls_hpke_mode_t mode,
-                                    const gnutls_pubkey_t ephemeral_pubkey,
-                                    const gnutls_pubkey_t sender_pubkey,
-                                    const gnutls_privkey_t receiver_privkey,
-                                    unsigned char *dh, size_t *dh_size)
+static int decap_get_dh(const gnutls_hpke_mode_t mode,
+                       const gnutls_pubkey_t ephemeral_pubkey,
+                       const gnutls_pubkey_t sender_pubkey,
+                       const gnutls_privkey_t receiver_privkey,
+                       gnutls_datum_t *dh)
 {
        int ret;
        gnutls_datum_t dhS = { NULL, 0 };
@@ -420,7 +389,7 @@ static int _gnutls_hpke_decap_get_dh(const gnutls_hpke_mode_t mode,
                goto cleanup;
        }
 
-       if (_gnutls_hpke_is_auth_mode(mode)) {
+       if (is_auth_mode(mode)) {
                ret = gnutls_privkey_derive_secret(
                        receiver_privkey, sender_pubkey, NULL, &dhS, 0);
                if (ret < 0) {
@@ -429,41 +398,34 @@ static int _gnutls_hpke_decap_get_dh(const gnutls_hpke_mode_t mode,
                }
        }
 
-       memcpy(dh, dhE.data, dhE.size);
-       *dh_size = dhE.size;
+       memcpy(dh->data, dhE.data, dhE.size);
+       dh->size = dhE.size;
 
-       if (_gnutls_hpke_is_auth_mode(mode)) {
-               memcpy(dh + dhE.size, dhS.data, dhS.size);
-               *dh_size += dhS.size;
+       if (is_auth_mode(mode)) {
+               memcpy(dh->data + dhE.size, dhS.data, dhS.size);
+               dh->size += dhS.size;
        }
 
 cleanup:
-       if (dhE.data != NULL) {
-               gnutls_memset(dhE.data, 0, dhE.size);
-               gnutls_free(dhE.data);
-       }
-
-       if (dhS.data != NULL) {
-               gnutls_memset(dhS.data, 0, dhS.size);
-               gnutls_free(dhS.data);
-       }
+       _gnutls_free_key_datum(&dhE);
+       _gnutls_free_key_datum(&dhS);
 
        return ret;
 }
 
-static int _gnutls_hpke_dhkem_decap(
-       const gnutls_hpke_kem_t kem, const gnutls_hpke_kdf_t kdf,
-       const gnutls_hpke_mode_t mode, const gnutls_privkey_t receiver_privkey,
-       const gnutls_pubkey_t sender_pubkey, const gnutls_datum_t *enc,
-       unsigned char *shared_secret, size_t *shared_secret_size)
+static int dhkem_decap(const gnutls_hpke_kem_t kem, const gnutls_hpke_kdf_t kdf,
+                      const gnutls_hpke_mode_t mode,
+                      const gnutls_privkey_t receiver_privkey,
+                      const gnutls_pubkey_t sender_pubkey,
+                      const gnutls_datum_t *enc, gnutls_datum_t *shared_secret)
 {
        int ret;
 
        gnutls_pubkey_t receiver_pubkey = NULL;
        gnutls_pubkey_t ephemeral_pubkey = NULL;
        gnutls_ecc_curve_t curve;
-       unsigned char dh[HPKE_MAX_DH_SIZE];
-       size_t dh_size = 0;
+       unsigned char dh_buf[HPKE_MAX_DH_SIZE];
+       gnutls_datum_t dh = { dh_buf, 0 };
 
        ret = gnutls_privkey_export_ecc_raw(receiver_privkey, &curve, NULL,
                                            NULL, NULL);
@@ -472,8 +434,7 @@ static int _gnutls_hpke_dhkem_decap(
                goto cleanup;
        }
 
-       if (!_gnutls_is_key_curve_type_compatible_with_param_dhkem(kem,
-                                                                  curve)) {
+       if (!is_key_curve_type_compatible_with_param_dhkem(kem, curve)) {
                ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                goto cleanup;
        }
@@ -484,14 +445,14 @@ static int _gnutls_hpke_dhkem_decap(
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_validate_pubkey_for_kem(ephemeral_pubkey, kem);
+       ret = validate_pubkey_for_kem(ephemeral_pubkey, kem);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_decap_get_dh(mode, ephemeral_pubkey, sender_pubkey,
-                                       receiver_privkey, dh, &dh_size);
+       ret = decap_get_dh(mode, ephemeral_pubkey, sender_pubkey,
+                          receiver_privkey, &dh);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
@@ -510,20 +471,18 @@ static int _gnutls_hpke_dhkem_decap(
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_get_shared_secret(kem, kdf, mode, receiver_pubkey,
-                                            sender_pubkey, ephemeral_pubkey,
-                                            dh, dh_size, shared_secret,
-                                            shared_secret_size);
+       ret = get_shared_secret(kem, kdf, mode, receiver_pubkey, sender_pubkey,
+                               ephemeral_pubkey, &dh, shared_secret);
        if (ret < 0) {
-               if (*shared_secret_size > 0) {
-                       gnutls_memset(shared_secret, 0, *shared_secret_size);
-                       *shared_secret_size = 0;
+               if (shared_secret->size > 0) {
+                       zeroize_key(shared_secret, shared_secret->size);
+                       shared_secret->size = 0;
                }
                gnutls_assert_val(ret);
        }
 
 cleanup:
-       gnutls_memset(dh, 0, dh_size);
+       zeroize_key(dh.data, dh.size);
 
        gnutls_pubkey_deinit(receiver_pubkey);
        gnutls_pubkey_deinit(ephemeral_pubkey);
@@ -531,27 +490,33 @@ cleanup:
        return ret;
 }
 
-static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
-                                const size_t shared_secret_size,
-                                const gnutls_datum_t *info,
-                                gnutls_hpke_context_t ctx)
+static int schedule(const gnutls_datum_t *shared_secret,
+                   const gnutls_datum_t *info, gnutls_hpke_context_t ctx)
 {
        int ret = 0;
 
-       unsigned char psk_id_hash[HPKE_MAX_HASH_SIZE] = { 0 };
-       size_t psk_id_hash_size = 0;
-       unsigned char info_hash[HPKE_MAX_HASH_SIZE] = { 0 };
-       size_t info_hash_size = 0;
-       unsigned char key_schedule_context[HPKE_MAX_KEY_SCHEDULE_CONTEXT_SIZE] = {
-               0
-       };
-       size_t key_schedule_context_size = 0;
-       unsigned char secret[HPKE_MAX_HASH_SIZE] = { 0 };
-       size_t secret_size = 0;
-       unsigned char labeled_expand_info[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
-               0
-       };
-       size_t labeled_expand_info_size = 0;
+       unsigned char psk_id_hash_buf[HPKE_MAX_HASH_SIZE] = { 0 };
+       unsigned char info_hash_buf[HPKE_MAX_HASH_SIZE] = { 0 };
+       unsigned char
+               key_schedule_context_buf[HPKE_MAX_KEY_SCHEDULE_CONTEXT_SIZE] = {
+                       0
+               };
+       unsigned char secret_buf[HPKE_MAX_HASH_SIZE] = { 0 };
+       unsigned char
+               labeled_expand_info_buf[HPKE_MAX_LABELED_EXPAND_INFO_SIZE] = {
+                       0
+               };
+       unsigned char salt_buf[HPKE_MAX_SALT_SIZE] = { 0 };
+       unsigned char suite_id_buf[HPKE_SCHEDULING_SUITE_ID_SIZE];
+
+       gnutls_datum_t psk_id_hash = { psk_id_hash_buf, 0 };
+       gnutls_datum_t info_hash = { info_hash_buf, 0 };
+       gnutls_datum_t key_schedule_context = { key_schedule_context_buf, 0 };
+       gnutls_datum_t secret = { secret_buf, 0 };
+       gnutls_datum_t labeled_expand_info = { labeled_expand_info_buf, 0 };
+       gnutls_datum_t suite_id = { suite_id_buf,
+                                   HPKE_SCHEDULING_SUITE_ID_SIZE };
+       gnutls_datum_t salt = { salt_buf, 0 };
 
        const gnutls_mac_algorithm_t mac = _gnutls_hpke_kdf_to_mac(ctx->kdf);
        if (mac == GNUTLS_MAC_UNKNOWN) {
@@ -563,49 +528,39 @@ static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
                return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
        }
 
-       unsigned char salt[HPKE_MAX_SALT_SIZE] = { 0 };
-       unsigned char suite_id[HPKE_SCHEDULING_SUITE_ID_SIZE];
+       salt.size = Nh;
+
        _gnutls_hpke_build_suite_id_for_scheduling(ctx->kem, ctx->kdf,
-                                                  ctx->aead, suite_id);
+                                                  ctx->aead, suite_id_buf);
 
-       ret = _gnutls_hpke_labeled_extract(
-               mac, suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE, salt, Nh,
-               psk_id_hash_label, sizeof(psk_id_hash_label) - 1, ctx->psk_id,
-               psk_id_hash, &psk_id_hash_size);
+       ret = _gnutls_hpke_labeled_extract(mac, &suite_id, &salt,
+                                          &psk_id_hash_label, ctx->psk_id,
+                                          &psk_id_hash);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_labeled_extract(mac, suite_id,
-                                          HPKE_SCHEDULING_SUITE_ID_SIZE, salt,
-                                          Nh, info_hash_label,
-                                          sizeof(info_hash_label) - 1, info,
-                                          info_hash, &info_hash_size);
+       ret = _gnutls_hpke_labeled_extract(mac, &suite_id, &salt,
+                                          &info_hash_label, info, &info_hash);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
        _gnutls_hpke_build_key_context_for_scheduling(
-               ctx->mode, psk_id_hash, psk_id_hash_size, info_hash,
-               info_hash_size, key_schedule_context,
-               &key_schedule_context_size);
-
-       ret = _gnutls_hpke_labeled_extract(
-               mac, suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE, shared_secret,
-               shared_secret_size, secret_hash_label,
-               sizeof(secret_hash_label) - 1, ctx->psk, secret, &secret_size);
+               ctx->mode, &psk_id_hash, &info_hash, &key_schedule_context);
+
+       ret = _gnutls_hpke_labeled_extract(mac, &suite_id, shared_secret,
+                                          &secret_hash_label, ctx->psk,
+                                          &secret);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
-       gnutls_datum_t secret_datum = { secret, secret_size };
-
        _gnutls_hpke_build_suite_id_for_scheduling(ctx->kem, ctx->kdf,
-                                                  ctx->aead, suite_id);
-       gnutls_datum_t expand_info = { NULL, 0 };
+                                                  ctx->aead, suite_id.data);
 
        if (ctx->aead != GNUTLS_HPKE_AEAD_EXPORT_ONLY) {
                const gnutls_cipher_algorithm_t cipher =
@@ -624,15 +579,13 @@ static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
                }
                ctx->key.size = Nk;
 
-               _gnutls_hpke_build_expand_info(
-                       suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE,
-                       key_expand_label, sizeof(key_expand_label) - 1,
-                       key_schedule_context, key_schedule_context_size, Nk,
-                       labeled_expand_info, &labeled_expand_info_size);
-               expand_info.data = labeled_expand_info;
-               expand_info.size = labeled_expand_info_size;
+               const gnutls_datum_t key_expand_label = { (void *)"key",
+                                                         sizeof("key") - 1 };
+               _gnutls_hpke_build_expand_info(&suite_id, &key_expand_label,
+                                              &key_schedule_context, Nk,
+                                              &labeled_expand_info);
 
-               ret = gnutls_hkdf_expand(mac, &secret_datum, &expand_info,
+               ret = gnutls_hkdf_expand(mac, &secret, &labeled_expand_info,
                                         ctx->key.data, ctx->key.size);
                if (ret < 0) {
                        gnutls_assert_val(ret);
@@ -648,15 +601,15 @@ static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
                }
                ctx->base_nonce.size = Nn;
 
-               _gnutls_hpke_build_expand_info(
-                       suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE,
-                       base_nonce_expand_label,
-                       sizeof(base_nonce_expand_label) - 1,
-                       key_schedule_context, key_schedule_context_size, Nn,
-                       labeled_expand_info, &labeled_expand_info_size);
-               expand_info.data = labeled_expand_info;
-               expand_info.size = labeled_expand_info_size;
-               ret = gnutls_hkdf_expand(mac, &secret_datum, &expand_info,
+               const gnutls_datum_t base_nonce_expand_label = {
+                       (void *)"base_nonce", sizeof("base_nonce") - 1
+               };
+
+               _gnutls_hpke_build_expand_info(&suite_id,
+                                              &base_nonce_expand_label,
+                                              &key_schedule_context, Nn,
+                                              &labeled_expand_info);
+               ret = gnutls_hkdf_expand(mac, &secret, &labeled_expand_info,
                                         ctx->base_nonce.data,
                                         ctx->base_nonce.size);
                if (ret < 0) {
@@ -672,16 +625,14 @@ static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
        }
        ctx->exporter_secret.size = Nh;
 
-       _gnutls_hpke_build_expand_info(suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE,
-                                      exporter_secret_expand_label,
-                                      sizeof(exporter_secret_expand_label) - 1,
-                                      key_schedule_context,
-                                      key_schedule_context_size, Nh,
-                                      labeled_expand_info,
-                                      &labeled_expand_info_size);
-       expand_info.data = labeled_expand_info;
-       expand_info.size = labeled_expand_info_size;
-       ret = gnutls_hkdf_expand(mac, &secret_datum, &expand_info,
+       const gnutls_datum_t exporter_secret_expand_label = {
+               (void *)"exp", sizeof("exp") - 1
+       };
+
+       _gnutls_hpke_build_expand_info(&suite_id, &exporter_secret_expand_label,
+                                      &key_schedule_context, Nh,
+                                      &labeled_expand_info);
+       ret = gnutls_hkdf_expand(mac, &secret, &labeled_expand_info,
                                 ctx->exporter_secret.data,
                                 ctx->exporter_secret.size);
        if (ret < 0) {
@@ -692,34 +643,16 @@ static int _gnutls_hpke_schedule(const unsigned char *shared_secret,
        return ret;
 
 error:
-       if (ctx->key.data != NULL) {
-               gnutls_memset(ctx->key.data, 0, ctx->key.size);
-               gnutls_free(ctx->key.data);
-               ctx->key.data = NULL;
-               ctx->key.size = 0;
-       }
-
-       if (ctx->base_nonce.data != NULL) {
-               gnutls_memset(ctx->base_nonce.data, 0, ctx->base_nonce.size);
-               gnutls_free(ctx->base_nonce.data);
-               ctx->base_nonce.data = NULL;
-               ctx->base_nonce.size = 0;
-       }
+       _gnutls_free_key_datum(&ctx->key);
+       _gnutls_free_key_datum(&ctx->base_nonce);
+       _gnutls_free_key_datum(&ctx->exporter_secret);
 
-       if (ctx->exporter_secret.data != NULL) {
-               gnutls_memset(ctx->exporter_secret.data, 0,
-                             ctx->exporter_secret.size);
-               gnutls_free(ctx->exporter_secret.data);
-               ctx->exporter_secret.data = NULL;
-               ctx->exporter_secret.size = 0;
-       }
 cleanup:
-
-       gnutls_memset(psk_id_hash, 0, psk_id_hash_size);
-       gnutls_memset(info_hash, 0, info_hash_size);
-       gnutls_memset(secret, 0, secret_size);
-       gnutls_memset(key_schedule_context, 0, key_schedule_context_size);
-       gnutls_memset(labeled_expand_info, 0, labeled_expand_info_size);
+       zeroize_key(psk_id_hash.data, psk_id_hash.size);
+       zeroize_key(info_hash.data, info_hash.size);
+       zeroize_key(secret.data, secret.size);
+       zeroize_key(key_schedule_context.data, key_schedule_context.size);
+       zeroize_key(labeled_expand_info.data, labeled_expand_info.size);
 
        return ret;
 }
@@ -797,54 +730,25 @@ int gnutls_hpke_context_deinit(gnutls_hpke_context_t ctx)
        }
 
        if (ctx->psk != NULL) {
-               if (ctx->psk->data != NULL) {
-                       gnutls_memset(ctx->psk->data, 0, ctx->psk->size);
-                       gnutls_free(ctx->psk->data);
-                       ctx->psk->data = NULL;
-                       ctx->psk->size = 0;
-               }
+               _gnutls_free_key_datum(ctx->psk);
                gnutls_free(ctx->psk);
        }
 
        if (ctx->psk_id != NULL) {
-               if (ctx->psk_id->data != NULL) {
-                       gnutls_memset(ctx->psk_id->data, 0, ctx->psk_id->size);
-                       gnutls_free(ctx->psk_id->data);
-                       ctx->psk_id->data = NULL;
-                       ctx->psk_id->size = 0;
-               }
+               _gnutls_free_key_datum(ctx->psk_id);
                gnutls_free(ctx->psk_id);
        }
 
-       if (ctx->key.data != NULL) {
-               gnutls_memset(ctx->key.data, 0, ctx->key.size);
-               gnutls_free(ctx->key.data);
-       }
-
-       if (ctx->base_nonce.data != NULL) {
-               gnutls_memset(ctx->base_nonce.data, 0, ctx->base_nonce.size);
-               gnutls_free(ctx->base_nonce.data);
-       }
-
-       if (ctx->exporter_secret.data != NULL) {
-               gnutls_memset(ctx->exporter_secret.data, 0,
-                             ctx->exporter_secret.size);
-               gnutls_free(ctx->exporter_secret.data);
-       }
+       _gnutls_free_key_datum(&ctx->key);
+       _gnutls_free_key_datum(&ctx->base_nonce);
+       _gnutls_free_key_datum(&ctx->exporter_secret);
 
        gnutls_pubkey_deinit(ctx->sender_pubkey);
        gnutls_privkey_deinit(ctx->sender_privkey);
 
        if (ctx->ikme != NULL) {
-               if (ctx->ikme->data != NULL) {
-                       gnutls_memset(ctx->ikme->data, 0, ctx->ikme->size);
-                       gnutls_free(ctx->ikme->data);
-                       ctx->ikme->data = NULL;
-                       ctx->ikme->size = 0;
-               }
-
+               _gnutls_free_key_datum(ctx->ikme);
                gnutls_free(ctx->ikme);
-               ctx->ikme = NULL;
        }
 
        gnutls_free(ctx);
@@ -872,7 +776,7 @@ int gnutls_hpke_context_set_psk(gnutls_hpke_context_t ctx,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       if (!_gnutls_hpke_is_psk_mode(ctx->mode)) {
+       if (!is_psk_mode(ctx->mode)) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
@@ -888,19 +792,13 @@ int gnutls_hpke_context_set_psk(gnutls_hpke_context_t ctx,
        int ret = 0;
 
        if (ctx->psk != NULL) {
-               gnutls_memset(ctx->psk->data, 0, ctx->psk->size);
-               gnutls_free(ctx->psk->data);
-               ctx->psk->data = NULL;
-               ctx->psk->size = 0;
+               _gnutls_free_key_datum(ctx->psk);
                gnutls_free(ctx->psk);
                ctx->psk = NULL;
        }
 
        if (ctx->psk_id != NULL) {
-               gnutls_memset(ctx->psk_id->data, 0, ctx->psk_id->size);
-               gnutls_free(ctx->psk_id->data);
-               ctx->psk_id->data = NULL;
-               ctx->psk_id->size = 0;
+               _gnutls_free_key_datum(ctx->psk_id);
                gnutls_free(ctx->psk_id);
                ctx->psk_id = NULL;
        }
@@ -936,25 +834,13 @@ int gnutls_hpke_context_set_psk(gnutls_hpke_context_t ctx,
        return ret;
 error:
        if (ctx->psk != NULL) {
-               if (ctx->psk->data != NULL) {
-                       gnutls_memset(ctx->psk->data, 0, ctx->psk->size);
-                       gnutls_free(ctx->psk->data);
-                       ctx->psk->data = NULL;
-                       ctx->psk->size = 0;
-               }
-
+               _gnutls_free_key_datum(ctx->psk);
                gnutls_free(ctx->psk);
                ctx->psk = NULL;
        }
 
        if (ctx->psk_id != NULL) {
-               if (ctx->psk_id->data != NULL) {
-                       gnutls_memset(ctx->psk_id->data, 0, ctx->psk_id->size);
-                       gnutls_free(ctx->psk_id->data);
-                       ctx->psk_id->data = NULL;
-                       ctx->psk_id->size = 0;
-               }
-
+               _gnutls_free_key_datum(ctx->psk_id);
                gnutls_free(ctx->psk_id);
                ctx->psk_id = NULL;
        }
@@ -983,7 +869,7 @@ int gnutls_hpke_context_set_sender_privkey(gnutls_hpke_context_t ctx,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       if (!_gnutls_hpke_is_auth_mode(ctx->mode)) {
+       if (!is_auth_mode(ctx->mode)) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
@@ -1018,7 +904,7 @@ int gnutls_hpke_context_set_sender_pubkey(gnutls_hpke_context_t ctx,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       if (!_gnutls_hpke_is_auth_mode(ctx->mode)) {
+       if (!is_auth_mode(ctx->mode)) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
@@ -1093,19 +979,18 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       if (_gnutls_hpke_is_auth_mode(ctx->mode)) {
+       if (is_auth_mode(ctx->mode)) {
                if (ctx->sender_privkey == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               ret = _gnutls_hpke_validate_privkey_for_kem(ctx->sender_privkey,
-                                                           ctx->kem);
+               ret = validate_privkey_for_kem(ctx->sender_privkey, ctx->kem);
                if (ret < 0) {
                        return gnutls_assert_val(ret);
                }
        }
 
-       if (_gnutls_hpke_is_psk_mode(ctx->mode)) {
+       if (is_psk_mode(ctx->mode)) {
                if (ctx->psk == NULL || ctx->psk_id == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
@@ -1116,17 +1001,16 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = _gnutls_hpke_validate_pubkey_for_kem(receiver_pubkey, ctx->kem);
+       ret = validate_pubkey_for_kem(receiver_pubkey, ctx->kem);
        if (ret < 0) {
                return gnutls_assert_val(ret);
        }
 
-       unsigned char shared_secret[HPKE_MAX_SHARED_SECRET_SIZE];
-       size_t shared_secret_size = 0;
+       unsigned char shared_secret_buf[HPKE_MAX_SHARED_SECRET_SIZE];
+       gnutls_datum_t shared_secret = { shared_secret_buf, 0 };
+
        if (_gnutls_is_kem_dh(ctx->kem)) {
-               ret = _gnutls_hpke_dhkem_encap(ctx, receiver_pubkey, enc,
-                                              shared_secret,
-                                              &shared_secret_size);
+               ret = dhkem_encap(ctx, receiver_pubkey, enc, &shared_secret);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto error;
@@ -1136,8 +1020,7 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = _gnutls_hpke_schedule(shared_secret, shared_secret_size, info,
-                                   ctx);
+       ret = schedule(&shared_secret, info, ctx);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto error;
@@ -1151,16 +1034,15 @@ error:
                enc->size = 0;
        }
 cleanup:
-       if (shared_secret_size > 0) {
-               gnutls_memset(shared_secret, 0, shared_secret_size);
+       if (shared_secret.size > 0) {
+               zeroize_key(shared_secret.data, shared_secret.size);
        }
 
        return ret;
 }
 
-static void _gnutls_hpke_get_seq_nonce(const gnutls_datum_t *base_nonce,
-                                      uint64_t seq, unsigned char *nonce,
-                                      size_t *nonce_size)
+static void get_seq_nonce(const gnutls_datum_t *base_nonce, uint64_t seq,
+                         unsigned char *nonce, size_t *nonce_size)
 {
        memcpy(nonce, base_nonce->data, base_nonce->size);
        *nonce_size = base_nonce->size;
@@ -1234,8 +1116,7 @@ int gnutls_hpke_seal(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
 
        unsigned char nonce[HPKE_MAX_NONCE_SIZE] = { 0 };
        size_t nonce_size = 0;
-       _gnutls_hpke_get_seq_nonce(&ctx->base_nonce, ctx->seq, nonce,
-                                  &nonce_size);
+       get_seq_nonce(&ctx->base_nonce, ctx->seq, nonce, &nonce_size);
 
        ret = gnutls_aead_cipher_init(&hd, cipher, &ctx->key);
        if (ret != 0) {
@@ -1267,12 +1148,10 @@ int gnutls_hpke_seal(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
        ctx->seq++;
 
 cleanup:
-       gnutls_memset(nonce, 0, nonce_size);
+       zeroize_key(nonce, nonce_size);
 
-       if (ret < 0 && ciphertext->data != NULL) {
-               gnutls_free(ciphertext->data);
-               ciphertext->data = NULL;
-               ciphertext->size = 0;
+       if (ret < 0) {
+               _gnutls_free_datum(ciphertext);
        }
 
        if (hd != NULL) {
@@ -1319,19 +1198,18 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       if (_gnutls_hpke_is_auth_mode(ctx->mode)) {
+       if (is_auth_mode(ctx->mode)) {
                if (ctx->sender_pubkey == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               ret = _gnutls_hpke_validate_pubkey_for_kem(ctx->sender_pubkey,
-                                                          ctx->kem);
+               ret = validate_pubkey_for_kem(ctx->sender_pubkey, ctx->kem);
                if (ret < 0) {
                        return gnutls_assert_val(ret);
                }
        }
 
-       if (_gnutls_hpke_is_psk_mode(ctx->mode)) {
+       if (is_psk_mode(ctx->mode)) {
                if (ctx->psk == NULL || ctx->psk_id == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
@@ -1342,19 +1220,18 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = _gnutls_hpke_validate_privkey_for_kem(receiver_privkey, ctx->kem);
+       ret = validate_privkey_for_kem(receiver_privkey, ctx->kem);
        if (ret < 0) {
                return gnutls_assert_val(ret);
        }
 
-       unsigned char shared_secret[HPKE_MAX_SHARED_SECRET_SIZE];
-       size_t shared_secret_size = 0;
+       unsigned char shared_secret_buf[HPKE_MAX_SHARED_SECRET_SIZE];
+       gnutls_datum_t shared_secret = { shared_secret_buf, 0 };
+
        if (_gnutls_is_kem_dh(ctx->kem)) {
-               ret = _gnutls_hpke_dhkem_decap(ctx->kem, ctx->kdf, ctx->mode,
-                                              receiver_privkey,
-                                              ctx->sender_pubkey, enc,
-                                              shared_secret,
-                                              &shared_secret_size);
+               ret = dhkem_decap(ctx->kem, ctx->kdf, ctx->mode,
+                                 receiver_privkey, ctx->sender_pubkey, enc,
+                                 &shared_secret);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto cleanup;
@@ -1365,16 +1242,15 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = _gnutls_hpke_schedule(shared_secret, shared_secret_size, info,
-                                   ctx);
+       ret = schedule(&shared_secret, info, ctx);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
        }
 
 cleanup:
-       if (shared_secret_size > 0) {
-               gnutls_memset(shared_secret, 0, shared_secret_size);
+       if (shared_secret.size > 0) {
+               zeroize_key(shared_secret.data, shared_secret.size);
        }
 
        return ret;
@@ -1444,8 +1320,7 @@ int gnutls_hpke_open(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
 
        unsigned char nonce[HPKE_MAX_NONCE_SIZE] = { 0 };
        size_t nonce_size = 0;
-       _gnutls_hpke_get_seq_nonce(&ctx->base_nonce, ctx->seq, nonce,
-                                  &nonce_size);
+       get_seq_nonce(&ctx->base_nonce, ctx->seq, nonce, &nonce_size);
 
        ret = gnutls_aead_cipher_init(&hd, cipher, &ctx->key);
        if (ret != 0) {
@@ -1473,16 +1348,13 @@ int gnutls_hpke_open(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
                                         ciphertext->size, plaintext->data,
                                         &plaintext_size);
        if (ret != 0) {
-               gnutls_memset(plaintext->data, 0, plaintext->size);
-               gnutls_free(plaintext->data);
-               plaintext->data = NULL;
-               plaintext->size = 0;
+               _gnutls_free_key_datum(plaintext);
                goto cleanup;
        }
 
        ctx->seq++;
 cleanup:
-       gnutls_memset(nonce, 0, nonce_size);
+       zeroize_key(nonce, nonce_size);
 
        if (hd != NULL) {
                gnutls_aead_cipher_deinit(hd);
@@ -1518,12 +1390,7 @@ int gnutls_hpke_context_set_ikme(gnutls_hpke_context_t ctx,
        }
 
        if (ctx->ikme != NULL) {
-               if (ctx->ikme->data != NULL) {
-                       gnutls_memset(ctx->ikme->data, 0, ctx->ikme->size);
-                       gnutls_free(ctx->ikme->data);
-                       ctx->ikme->data = NULL;
-                       ctx->ikme->size = 0;
-               }
+               _gnutls_free_key_datum(ctx->ikme);
                gnutls_free(ctx->ikme);
                ctx->ikme = NULL;
        }
@@ -1663,39 +1530,38 @@ int gnutls_hpke_export(gnutls_hpke_context_t ctx,
        }
 
        int ret;
-       unsigned char suite_id[HPKE_SCHEDULING_SUITE_ID_SIZE];
+       unsigned char suite_id_buf[HPKE_SCHEDULING_SUITE_ID_SIZE];
+       unsigned char
+               labeled_export_info_buf[HPKE_MAX_LABELED_EXPORT_INFO_MAX_SIZE];
+
+       gnutls_datum_t suite_id = { suite_id_buf,
+                                   HPKE_SCHEDULING_SUITE_ID_SIZE };
+       gnutls_datum_t labeled_export_info = { labeled_export_info_buf, 0 };
 
        _gnutls_hpke_build_suite_id_for_scheduling(ctx->kem, ctx->kdf,
-                                                  ctx->aead, suite_id);
+                                                  ctx->aead, suite_id.data);
 
-       unsigned char labeled_export_info[HPKE_MAX_LABELED_EXPORT_INFO_MAX_SIZE];
-       size_t labeled_export_info_size = 0;
+       const gnutls_datum_t export_secret_label = { (void *)"sec",
+                                                    sizeof("sec") - 1 };
 
-       _gnutls_hpke_build_expand_info(
-               suite_id, HPKE_SCHEDULING_SUITE_ID_SIZE, export_secret_label,
-               sizeof(export_secret_label) - 1, exporter_context->data,
-               exporter_context->size, L, labeled_export_info,
-               &labeled_export_info_size);
+       _gnutls_hpke_build_expand_info(&suite_id, &export_secret_label,
+                                      exporter_context, L,
+                                      &labeled_export_info);
 
        const gnutls_mac_algorithm_t mac = _gnutls_hpke_kdf_to_mac(ctx->kdf);
        if (mac == GNUTLS_MAC_UNKNOWN) {
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       gnutls_datum_t expand_info = { labeled_export_info,
-                                      labeled_export_info_size };
        secret->data = gnutls_malloc(L);
        if (secret->data == NULL) {
                return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
        }
 
-       ret = gnutls_hkdf_expand(mac, &ctx->exporter_secret, &expand_info,
-                                secret->data, L);
+       ret = gnutls_hkdf_expand(mac, &ctx->exporter_secret,
+                                &labeled_export_info, secret->data, L);
        if (ret < 0) {
-               gnutls_memset(secret->data, 0, L);
-               gnutls_free(secret->data);
-               secret->data = NULL;
-               secret->size = 0;
+               _gnutls_free_key_datum(secret);
                return gnutls_assert_val(ret);
        }