]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls_hpke_generate_keypair: expect initialized keys
authorDaiki Ueno <ueno@gnu.org>
Mon, 20 Apr 2026 11:21:42 +0000 (20:21 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sat, 25 Apr 2026 01:31:03 +0000 (10:31 +0900)
This moves responsibility of initializing gnutls_pubkey_t or
gnutls_privkey_t to the caller of the function, to match the existing
convention in gnutls_privkey_generate*.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/hpke/hpke-key-management.c
lib/hpke/hpke-key-management.h
lib/hpke/hpke.c
lib/includes/gnutls/hpke.h
tests/hpke-tests.c

index 6a7ec23cad478b1257ae844d8106b120086f1328..f923eb7cb1074c78cd13313a18130602a53e2116 100644 (file)
@@ -147,7 +147,7 @@ static int extract_coordinates_from_pubkey_datum(const gnutls_ecc_curve_t curve,
 
 int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                                 const gnutls_datum_t *datum,
-                                gnutls_pubkey_t *pk)
+                                gnutls_pubkey_t pubkey)
 {
        int ret;
 
@@ -162,16 +162,9 @@ int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                return gnutls_assert_val(ret);
        }
 
-       ret = gnutls_pubkey_init(pk);
-       if (ret < 0) {
-               return gnutls_assert_val(ret);
-       }
-
-       ret = gnutls_pubkey_import_ecc_raw(*pk, curve, &x, &y);
+       ret = gnutls_pubkey_import_ecc_raw(pubkey, curve, &x, &y);
        if (ret < 0) {
                gnutls_assert_val(ret);
-               gnutls_pubkey_deinit(*pk);
-               *pk = NULL;
                return ret;
        }
 
@@ -200,8 +193,8 @@ static void clamp_sk(const gnutls_hpke_kem_t kem, unsigned char *sk_buf)
 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 gnutls_datum_t *suite_id, 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
@@ -231,36 +224,19 @@ static int montgomery_curve_keypair_from_raw_privkey(
        }
 
        clamp_sk(kem, sk.data);
-       ret = gnutls_privkey_init(privkey);
-       if (ret < 0) {
-               gnutls_assert_val(ret);
-               goto cleanup;
-       }
 
-       ret = gnutls_privkey_import_ecc_raw(*privkey, curve, NULL, NULL, &sk);
+       ret = gnutls_privkey_import_ecc_raw(privkey, curve, NULL, NULL, &sk);
        if (ret < 0) {
                gnutls_assert_val(ret);
-               goto error;
-       }
-
-       ret = gnutls_pubkey_init(pubkey);
-       if (ret < 0) {
-               gnutls_assert_val(ret);
-               goto error;
+               goto cleanup;
        }
 
-       ret = gnutls_pubkey_import_privkey(*pubkey, *privkey, 0, 0);
+       ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
        if (ret < 0) {
                gnutls_assert_val(ret);
-               goto error;
+               goto cleanup;
        }
 
-       goto cleanup;
-
-error:
-       gnutls_privkey_deinit(*privkey);
-       gnutls_pubkey_deinit(*pubkey);
-
 cleanup:
 
        zeroize_key(sk.data, sk.size);
@@ -311,8 +287,8 @@ static int be_lt(const unsigned char *a, const unsigned char *b, size_t len)
 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 gnutls_datum_t *suite_id, 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
@@ -365,40 +341,22 @@ static int prime_curve_keypair_from_raw_privkey(
                        continue;
                }
 
-               ret = gnutls_privkey_init(privkey);
-               if (ret < 0) {
-                       ret = gnutls_assert_val(ret);
-                       goto cleanup;
-               }
-
-               ret = gnutls_privkey_import_ecc_raw(*privkey, curve, NULL, NULL,
+               ret = gnutls_privkey_import_ecc_raw(privkey, curve, NULL, NULL,
                                                    &sk);
                if (ret < 0) {
                        gnutls_assert_val(ret);
-                       goto error;
-               }
-
-               ret = gnutls_pubkey_init(pubkey);
-               if (ret < 0) {
-                       gnutls_assert_val(ret);
-                       goto error;
+                       goto cleanup;
                }
 
-               ret = gnutls_pubkey_import_privkey(*pubkey, *privkey, 0, 0);
+               ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
                if (ret < 0) {
                        gnutls_assert_val(ret);
-                       goto error;
+                       goto cleanup;
                }
 
                break;
        }
 
-       goto cleanup;
-
-error:
-       gnutls_privkey_deinit(*privkey);
-       gnutls_pubkey_deinit(*pubkey);
-
 cleanup:
        zeroize_key(sk.data, sk.size);
        zeroize_key(labeled_expand_info.data, labeled_expand_info.size);
@@ -408,8 +366,8 @@ cleanup:
 
 int _gnutls_hpke_keypair_from_ikm(const gnutls_hpke_kem_t kem,
                                  const gnutls_datum_t *ikme,
-                                 gnutls_privkey_t *privkey,
-                                 gnutls_pubkey_t *pubkey)
+                                 gnutls_privkey_t privkey,
+                                 gnutls_pubkey_t pubkey)
 {
        int ret;
        unsigned char dkp_prk_buf[HPKE_MAX_HASH_SIZE] = { 0 };
@@ -466,8 +424,8 @@ cleanup:
 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)
+                               gnutls_privkey_t ephemeral_privkey,
+                               gnutls_pubkey_t ephemeral_pubkey)
 {
        int ret;
 
@@ -478,21 +436,15 @@ static int generate_new_keypair(const gnutls_ecc_curve_t curve,
                return ret;
        }
 
-       ret = gnutls_privkey_generate(*ephemeral_privkey, pk_algo,
+       ret = gnutls_privkey_generate(ephemeral_privkey, pk_algo,
                                      GNUTLS_CURVE_TO_BITS(curve), 0);
        if (ret < 0) {
                gnutls_assert_val(ret);
                return ret;
        }
 
-       ret = gnutls_pubkey_init(ephemeral_pubkey);
-       if (ret < 0) {
-               gnutls_assert_val(ret);
-               return ret;
-       }
-
-       ret = gnutls_pubkey_import_privkey(*ephemeral_pubkey,
-                                          *ephemeral_privkey, 0, 0);
+       ret = gnutls_pubkey_import_privkey(ephemeral_pubkey, ephemeral_privkey,
+                                          0, 0);
        if (ret < 0) {
                gnutls_assert_val(ret);
                return ret;
@@ -504,8 +456,8 @@ static int generate_new_keypair(const gnutls_ecc_curve_t curve,
 int _gnutls_hpke_generate_keypair(const gnutls_datum_t *ikme,
                                  const gnutls_hpke_kem_t kem,
                                  const gnutls_pubkey_t receiver_pubkey,
-                                 gnutls_privkey_t *ephemeral_privkey,
-                                 gnutls_pubkey_t *ephemeral_pubkey)
+                                 gnutls_privkey_t ephemeral_privkey,
+                                 gnutls_pubkey_t ephemeral_pubkey)
 {
        int ret;
        if (ikme == NULL) {
index 53695a0f19e41e3b87d1af73fcfbbc4fa2084c4a..c2bf49750c54c2d6b2db9b574289845ed509eac9 100644 (file)
@@ -40,18 +40,18 @@ int _gnutls_hpke_pubkey_to_datum(const gnutls_pubkey_t pk,
 
 int _gnutls_hpke_datum_to_pubkey(const gnutls_ecc_curve_t curve,
                                 const gnutls_datum_t *datum,
-                                gnutls_pubkey_t *pk);
+                                gnutls_pubkey_t pubkey);
 
 int _gnutls_hpke_keypair_from_ikm(const gnutls_hpke_kem_t kem,
                                  const gnutls_datum_t *ikme,
-                                 gnutls_privkey_t *privkey,
-                                 gnutls_pubkey_t *pubkey);
+                                 gnutls_privkey_t privkey,
+                                 gnutls_pubkey_t pubkey);
 
 int _gnutls_hpke_generate_keypair(const gnutls_datum_t *ikme,
                                  const gnutls_hpke_kem_t kem,
                                  const gnutls_pubkey_t receiver_pubkey,
-                                 gnutls_privkey_t *ephemeral_privkey,
-                                 gnutls_pubkey_t *ephemeral_pubkey);
+                                 gnutls_privkey_t ephemeral_privkey,
+                                 gnutls_pubkey_t ephemeral_pubkey);
 
 int _gnutls_hpke_privkey_clone(gnutls_privkey_t src, gnutls_privkey_t *dst);
 
index a182cec2f5847eff9eb10b4d27cabd22a6cf3666..39d8c29da00db8c9c16641e26c792fd3b6b00542 100644 (file)
@@ -300,9 +300,21 @@ static int dhkem_encap(const gnutls_hpke_context_t ctx,
        unsigned char dh_buf[HPKE_MAX_DH_SIZE];
        gnutls_datum_t dh = { dh_buf, 0 };
 
+       ret = gnutls_pubkey_init(&ephemeral_pubkey);
+       if (ret < 0) {
+               ret = gnutls_assert_val(ret);
+               goto cleanup;
+       }
+
+       ret = gnutls_privkey_init(&ephemeral_privkey);
+       if (ret < 0) {
+               ret = gnutls_assert_val(ret);
+               goto cleanup;
+       }
+
        ret = _gnutls_hpke_generate_keypair(ctx->ikme, ctx->kem,
-                                           receiver_pubkey, &ephemeral_privkey,
-                                           &ephemeral_pubkey);
+                                           receiver_pubkey, ephemeral_privkey,
+                                           ephemeral_pubkey);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
@@ -440,7 +452,13 @@ static int dhkem_decap(gnutls_hpke_kem_t kem, gnutls_hpke_kdf_t kdf,
                goto cleanup;
        }
 
-       ret = _gnutls_hpke_datum_to_pubkey(curve, enc, &ephemeral_pubkey);
+       ret = gnutls_pubkey_init(&ephemeral_pubkey);
+       if (ret < 0) {
+               ret = gnutls_assert_val(ret);
+               goto cleanup;
+       }
+
+       ret = _gnutls_hpke_datum_to_pubkey(curve, enc, ephemeral_pubkey);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
@@ -1415,8 +1433,8 @@ int gnutls_hpke_set_ikme(gnutls_hpke_context_t ctx, const gnutls_datum_t *ikme)
  * @kem: The KEM algorithm to use for key pair generation.
  * @ikm: A pointer to a gnutls_datum_t structure containing the input key material (IKM) to be used for key pair
  * generation. This should be a non-empty byte string that serves as the seed for key pair generation.
- * @privkey: A pointer to a gnutls_privkey_t variable where the generated private key will be stored. The function will initialize this variable with the generated private key.
- * @pubkey: A pointer to a gnutls_pubkey_t variable where the generated public key will be stored. The function will initialize this variable with the generated public key.
+ * @privkey: An initialized private key.
+ * @pubkey: An initialized public key.
  *
  * This function generates a key pair (private key and public key) for the specified KEM algorithm using the provided
  * input key material (IKM). The IKM is used as a seed for the key generation process, allowing for deterministic key
@@ -1427,8 +1445,8 @@ int gnutls_hpke_set_ikme(gnutls_hpke_context_t ctx, const gnutls_datum_t *ikme)
  */
 int gnutls_hpke_generate_keypair(gnutls_hpke_kem_t kem,
                                 const gnutls_datum_t *ikm,
-                                gnutls_privkey_t *privkey,
-                                gnutls_pubkey_t *pubkey)
+                                gnutls_privkey_t privkey,
+                                gnutls_pubkey_t pubkey)
 {
        int ret;
        if (ikm == NULL || ikm->data == NULL || ikm->size == 0 ||
index b59cc51c0cb910cd8ea5b97053620fa98c20dfd6..4e51d1b78a509dc3355ec3c62824fdcd14d8e9b7 100644 (file)
@@ -141,8 +141,8 @@ int gnutls_hpke_set_ikme(gnutls_hpke_context_t ctx, const gnutls_datum_t *ikme);
 
 int gnutls_hpke_generate_keypair(gnutls_hpke_kem_t kem,
                                 const gnutls_datum_t *ikm,
-                                gnutls_privkey_t *privkey,
-                                gnutls_pubkey_t *pubkey);
+                                gnutls_privkey_t privkey,
+                                gnutls_pubkey_t pubkey);
 
 int gnutls_hpke_get_seq(gnutls_hpke_context_t ctx, uint64_t *seq);
 int gnutls_hpke_set_seq(gnutls_hpke_context_t ctx, uint64_t seq);
index 491bc5e24a26df7e6bcb5d511e643d5d9563bf37..54da99cbc9d171e940f986ca622d0c4681e1c28b 100644 (file)
@@ -144,8 +144,16 @@ static void test_hpke(const hpke_test_parameters_st *params)
        }
 
        if (params->ikmS != NULL) {
+               ret = gnutls_privkey_init(&skS);
+               if (ret < 0) {
+                       fail("gnutls_privkey_init: %s\n", gnutls_strerror(ret));
+               }
+               ret = gnutls_pubkey_init(&pkS);
+               if (ret < 0) {
+                       fail("gnutls_pubkey_init: %s\n", gnutls_strerror(ret));
+               }
                ret = gnutls_hpke_generate_keypair(params->kem, params->ikmS,
-                                                  &skS, &pkS);
+                                                  skS, pkS);
                if (ret < 0) {
                        fail("gnutls_hpke_generate_keypair (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
                             params->mode, params->kem, params->kdf,
@@ -160,8 +168,16 @@ static void test_hpke(const hpke_test_parameters_st *params)
                }
        }
 
-       ret = gnutls_hpke_generate_keypair(params->kem, &params->ikmR, &skR,
-                                          &pkR);
+       ret = gnutls_privkey_init(&skR);
+       if (ret < 0) {
+               fail("gnutls_privkey_init: %s\n", gnutls_strerror(ret));
+       }
+       ret = gnutls_pubkey_init(&pkR);
+       if (ret < 0) {
+               fail("gnutls_pubkey_init: %s\n", gnutls_strerror(ret));
+       }
+       ret = gnutls_hpke_generate_keypair(params->kem, &params->ikmR, skR,
+                                          pkR);
        if (ret < 0) {
                fail("gnutls_hpke_generate_keypair (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
                     params->mode, params->kem, params->kdf, params->aead,