]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
hpke: give all additional information to encap/decap at once
authorDaiki Ueno <ueno@gnu.org>
Mon, 20 Apr 2026 12:30:32 +0000 (21:30 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sat, 25 Apr 2026 01:31:03 +0000 (10:31 +0900)
This merges gnutls_hpke_set_{psk,sender_privkey,sender_pubkey} into
gnutls_hpke_encap and gnutls_hpke_decap to avoid copying keys.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
NEWS
devel/symbols.last
doc/Makefile.am
doc/manpages/Makefile.am
lib/hpke/hpke-key-management.c
lib/hpke/hpke-key-management.h
lib/hpke/hpke.c
lib/includes/gnutls/hpke.h
lib/libgnutls.map
tests/hpke-tests.c

diff --git a/NEWS b/NEWS
index 4d94730808462fe0714749c2b40dba9ac37e3136..f19019b0270275ef0b0177bff0bff7dc628ff422 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -36,9 +36,6 @@ gnutls_hpke_role_t: New enum
 gnutls_hpke_context_st: New context structure
 gnutls_hpke_init: New function
 gnutls_hpke_deinit: New function
-gnutls_hpke_set_psk: New function
-gnutls_hpke_set_sender_privkey: New function
-gnutls_hpke_set_sender_pubkey: New function
 gnutls_hpke_get_enc_size: New function
 gnutls_hpke_encap: New function
 gnutls_hpke_seal: New function
index 766a8da0296966ca3188231c0f1be3c4839fd502..0b38f48f3a44e9b6e834162bcdd6adeec4269939 100644 (file)
@@ -337,20 +337,17 @@ gnutls_hmac_get_len@GNUTLS_3_4
 gnutls_hmac_init@GNUTLS_3_4
 gnutls_hmac_output@GNUTLS_3_4
 gnutls_hmac_set_nonce@GNUTLS_3_4
-gnutls_hpke_deinit@GNUTLS_3_8_13
-gnutls_hpke_get_enc_size@GNUTLS_3_8_13
-gnutls_hpke_init@GNUTLS_3_8_13
-gnutls_hpke_set_ikme@GNUTLS_3_8_13
-gnutls_hpke_set_psk@GNUTLS_3_8_13
-gnutls_hpke_set_sender_privkey@GNUTLS_3_8_13
-gnutls_hpke_set_sender_pubkey@GNUTLS_3_8_13
 gnutls_hpke_decap@GNUTLS_3_8_13
+gnutls_hpke_deinit@GNUTLS_3_8_13
 gnutls_hpke_encap@GNUTLS_3_8_13
 gnutls_hpke_export@GNUTLS_3_8_13
 gnutls_hpke_generate_keypair@GNUTLS_3_8_13
+gnutls_hpke_get_enc_size@GNUTLS_3_8_13
 gnutls_hpke_get_seq@GNUTLS_3_8_13
+gnutls_hpke_init@GNUTLS_3_8_13
 gnutls_hpke_open@GNUTLS_3_8_13
 gnutls_hpke_seal@GNUTLS_3_8_13
+gnutls_hpke_set_ikme@GNUTLS_3_8_13
 gnutls_hpke_set_seq@GNUTLS_3_8_13
 gnutls_idna_map@GNUTLS_3_4
 gnutls_idna_reverse_map@GNUTLS_3_4
index 8b6cc9658738fd152a51992677174b77f0999549..d6bb57793daf72aa1735deeacd7ebf8239d1ad71 100644 (file)
@@ -579,6 +579,11 @@ ENUMS += enums/gnutls_fips_mode_t
 ENUMS += enums/gnutls_gost_paramset_t
 ENUMS += enums/gnutls_group_t
 ENUMS += enums/gnutls_handshake_description_t
+ENUMS += enums/gnutls_hpke_aead_t
+ENUMS += enums/gnutls_hpke_kdf_t
+ENUMS += enums/gnutls_hpke_kem_t
+ENUMS += enums/gnutls_hpke_mode_t
+ENUMS += enums/gnutls_hpke_role_t
 ENUMS += enums/gnutls_info_access_what_t
 ENUMS += enums/gnutls_init_flags_t
 ENUMS += enums/gnutls_keygen_types_t
@@ -1225,34 +1230,28 @@ FUNCS += functions/gnutls_hmac_output
 FUNCS += functions/gnutls_hmac_output.short
 FUNCS += functions/gnutls_hmac_set_nonce
 FUNCS += functions/gnutls_hmac_set_nonce.short
-FUNCS += functions/gnutls_hpke_deinit
-FUNCS += functions/gnutls_hpke_deinit.short
-FUNCS += functions/gnutls_hpke_get_enc_size
-FUNCS += functions/gnutls_hpke_get_enc_size.short
-FUNCS += functions/gnutls_hpke_init
-FUNCS += functions/gnutls_hpke_init.short
-FUNCS += functions/gnutls_hpke_set_ikme
-FUNCS += functions/gnutls_hpke_set_ikme.short
-FUNCS += functions/gnutls_hpke_set_psk
-FUNCS += functions/gnutls_hpke_set_psk.short
-FUNCS += functions/gnutls_hpke_set_sender_privkey
-FUNCS += functions/gnutls_hpke_set_sender_privkey.short
-FUNCS += functions/gnutls_hpke_set_sender_pubkey
-FUNCS += functions/gnutls_hpke_set_sender_pubkey.short
 FUNCS += functions/gnutls_hpke_decap
 FUNCS += functions/gnutls_hpke_decap.short
+FUNCS += functions/gnutls_hpke_deinit
+FUNCS += functions/gnutls_hpke_deinit.short
 FUNCS += functions/gnutls_hpke_encap
 FUNCS += functions/gnutls_hpke_encap.short
 FUNCS += functions/gnutls_hpke_export
 FUNCS += functions/gnutls_hpke_export.short
 FUNCS += functions/gnutls_hpke_generate_keypair
 FUNCS += functions/gnutls_hpke_generate_keypair.short
+FUNCS += functions/gnutls_hpke_get_enc_size
+FUNCS += functions/gnutls_hpke_get_enc_size.short
 FUNCS += functions/gnutls_hpke_get_seq
 FUNCS += functions/gnutls_hpke_get_seq.short
+FUNCS += functions/gnutls_hpke_init
+FUNCS += functions/gnutls_hpke_init.short
 FUNCS += functions/gnutls_hpke_open
 FUNCS += functions/gnutls_hpke_open.short
 FUNCS += functions/gnutls_hpke_seal
 FUNCS += functions/gnutls_hpke_seal.short
+FUNCS += functions/gnutls_hpke_set_ikme
+FUNCS += functions/gnutls_hpke_set_ikme.short
 FUNCS += functions/gnutls_hpke_set_seq
 FUNCS += functions/gnutls_hpke_set_seq.short
 FUNCS += functions/gnutls_idna_map
index a01de8cc8738f64bc8bc250cdf55da0aedbe79cb..a61c7e7370940f3e48f5298e254b457136cfb04a 100644 (file)
@@ -446,20 +446,17 @@ APIMANS += gnutls_hmac_get_len.3
 APIMANS += gnutls_hmac_init.3
 APIMANS += gnutls_hmac_output.3
 APIMANS += gnutls_hmac_set_nonce.3
-APIMANS += gnutls_hpke_deinit.3
-APIMANS += gnutls_hpke_get_enc_size.3
-APIMANS += gnutls_hpke_init.3
-APIMANS += gnutls_hpke_set_ikme.3
-APIMANS += gnutls_hpke_set_psk.3
-APIMANS += gnutls_hpke_set_sender_privkey.3
-APIMANS += gnutls_hpke_set_sender_pubkey.3
 APIMANS += gnutls_hpke_decap.3
+APIMANS += gnutls_hpke_deinit.3
 APIMANS += gnutls_hpke_encap.3
 APIMANS += gnutls_hpke_export.3
 APIMANS += gnutls_hpke_generate_keypair.3
+APIMANS += gnutls_hpke_get_enc_size.3
 APIMANS += gnutls_hpke_get_seq.3
+APIMANS += gnutls_hpke_init.3
 APIMANS += gnutls_hpke_open.3
 APIMANS += gnutls_hpke_seal.3
+APIMANS += gnutls_hpke_set_ikme.3
 APIMANS += gnutls_hpke_set_seq.3
 APIMANS += gnutls_idna_map.3
 APIMANS += gnutls_idna_reverse_map.3
index f923eb7cb1074c78cd13313a18130602a53e2116..92a9d6d6c3cbbaf47e6096b9e2138071db2fd4c0 100644 (file)
@@ -495,58 +495,3 @@ int _gnutls_hpke_generate_keypair(const gnutls_datum_t *ikme,
 
        return ret;
 }
-
-int _gnutls_hpke_privkey_clone(gnutls_privkey_t src, gnutls_privkey_t *dst)
-{
-       int ret;
-       gnutls_x509_privkey_t xkey = NULL;
-
-       ret = gnutls_privkey_export_x509(src, &xkey);
-       if (ret < 0)
-               return gnutls_assert_val(ret);
-
-       ret = gnutls_privkey_init(dst);
-       if (ret < 0) {
-               gnutls_x509_privkey_deinit(xkey);
-               return gnutls_assert_val(ret);
-       }
-
-       ret = gnutls_privkey_import_x509(*dst, xkey,
-                                        GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
-       if (ret < 0) {
-               gnutls_privkey_deinit(*dst);
-               *dst = NULL;
-               gnutls_x509_privkey_deinit(xkey);
-               return gnutls_assert_val(ret);
-       }
-
-       return 0;
-}
-
-int _gnutls_hpke_pubkey_clone(gnutls_pubkey_t src, gnutls_pubkey_t *dst)
-{
-       int ret;
-       gnutls_datum_t der = { NULL, 0 };
-
-       ret = gnutls_pubkey_export2(src, GNUTLS_X509_FMT_DER, &der);
-       if (ret < 0) {
-               return gnutls_assert_val(ret);
-       }
-
-       ret = gnutls_pubkey_init(dst);
-       if (ret < 0) {
-               gnutls_free(der.data);
-               return gnutls_assert_val(ret);
-       }
-
-       ret = gnutls_pubkey_import(*dst, &der, GNUTLS_X509_FMT_DER);
-       gnutls_free(der.data);
-
-       if (ret < 0) {
-               gnutls_pubkey_deinit(*dst);
-               *dst = NULL;
-               return gnutls_assert_val(ret);
-       }
-
-       return 0;
-}
index c2bf49750c54c2d6b2db9b574289845ed509eac9..7d0e6b11d5225b00b1e27ba382878d67bfa5caad 100644 (file)
@@ -53,8 +53,4 @@ int _gnutls_hpke_generate_keypair(const gnutls_datum_t *ikme,
                                  gnutls_privkey_t ephemeral_privkey,
                                  gnutls_pubkey_t ephemeral_pubkey);
 
-int _gnutls_hpke_privkey_clone(gnutls_privkey_t src, gnutls_privkey_t *dst);
-
-int _gnutls_hpke_pubkey_clone(gnutls_pubkey_t src, gnutls_pubkey_t *dst);
-
 #endif /* HPKE_KEY_MANAGEMENT_HELPER_H */
index 39d8c29da00db8c9c16641e26c792fd3b6b00542..53f29326cdc579357c3aa47e8655c28de86224fa 100644 (file)
@@ -61,14 +61,8 @@ struct gnutls_hpke_context_st {
        gnutls_hpke_kdf_t kdf;
        gnutls_hpke_aead_t aead;
 
-       gnutls_datum_t *psk;
-       gnutls_datum_t *psk_id;
-
        gnutls_datum_t *ikme;
 
-       gnutls_pubkey_t sender_pubkey;
-       gnutls_privkey_t sender_privkey;
-
        gnutls_datum_t key;
        gnutls_datum_t base_nonce;
        gnutls_datum_t exporter_secret;
@@ -291,6 +285,7 @@ cleanup:
 
 static int dhkem_encap(const gnutls_hpke_context_t ctx,
                       const gnutls_pubkey_t receiver_pubkey,
+                      const gnutls_privkey_t sender_privkey,
                       gnutls_datum_t *enc, gnutls_datum_t *shared_secret)
 {
        int ret = 0;
@@ -338,7 +333,7 @@ static int dhkem_encap(const gnutls_hpke_context_t ctx,
        memcpy(enc->data, pubkey_raw.data, pubkey_raw.size);
 
        ret = encap_get_dh(ctx->mode, receiver_pubkey, ephemeral_privkey,
-                          ctx->sender_privkey, &dh);
+                          sender_privkey, &dh);
        if (ret < 0) {
                ret = gnutls_assert_val(ret);
                goto error;
@@ -351,7 +346,7 @@ static int dhkem_encap(const gnutls_hpke_context_t ctx,
                        goto error;
                }
                ret = gnutls_pubkey_import_privkey(sender_pubkey,
-                                                  ctx->sender_privkey, 0, 0);
+                                                  sender_privkey, 0, 0);
                if (ret < 0) {
                        ret = gnutls_assert_val(ret);
                        goto error;
@@ -509,8 +504,10 @@ cleanup:
        return ret;
 }
 
-static int schedule(const gnutls_datum_t *shared_secret,
-                   const gnutls_datum_t *info, gnutls_hpke_context_t ctx)
+static int schedule(gnutls_hpke_context_t ctx,
+                   const gnutls_datum_t *shared_secret,
+                   const gnutls_datum_t *info, const gnutls_datum_t *psk,
+                   const gnutls_datum_t *psk_id)
 {
        int ret = 0;
 
@@ -553,7 +550,7 @@ static int schedule(const gnutls_datum_t *shared_secret,
                                                   ctx->aead, suite_id_buf);
 
        ret = _gnutls_hpke_labeled_extract(mac, &suite_id, &salt,
-                                          &psk_id_hash_label, ctx->psk_id,
+                                          &psk_id_hash_label, psk_id,
                                           &psk_id_hash);
        if (ret < 0) {
                gnutls_assert_val(ret);
@@ -571,8 +568,7 @@ static int schedule(const gnutls_datum_t *shared_secret,
                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);
+                                          &secret_hash_label, psk, &secret);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
@@ -710,14 +706,8 @@ int gnutls_hpke_init(gnutls_hpke_context_t *ctx, gnutls_hpke_mode_t mode,
        (*ctx)->kdf = kdf;
        (*ctx)->aead = aead;
 
-       (*ctx)->psk = NULL;
-       (*ctx)->psk_id = NULL;
-
        (*ctx)->ikme = NULL;
 
-       (*ctx)->sender_pubkey = NULL;
-       (*ctx)->sender_privkey = NULL;
-
        (*ctx)->key.data = NULL;
        (*ctx)->key.size = 0;
        (*ctx)->base_nonce.data = NULL;
@@ -745,23 +735,10 @@ int gnutls_hpke_deinit(gnutls_hpke_context_t ctx)
                return 0;
        }
 
-       if (ctx->psk != NULL) {
-               _gnutls_free_key_datum(ctx->psk);
-               gnutls_free(ctx->psk);
-       }
-
-       if (ctx->psk_id != NULL) {
-               _gnutls_free_key_datum(ctx->psk_id);
-               gnutls_free(ctx->psk_id);
-       }
-
        _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) {
                _gnutls_free_key_datum(ctx->ikme);
                gnutls_free(ctx->ikme);
@@ -771,168 +748,6 @@ int gnutls_hpke_deinit(gnutls_hpke_context_t ctx)
        return 0;
 }
 
-/**
- * gnutls_hpke_set_psk:
- * @ctx: The HPKE context to set the PSK for.
- * @psk: A pointer to a gnutls_datum_t structure containing the PSK value and its size.
- * @psk_id: A pointer to a gnutls_datum_t structure containing the PSK identifier and its size.
- *
- * This function sets the PSK and its identifier in the HPKE context.
- * It securely erases any existing PSK and PSK identifier in the context before setting the new values.
- * The function checks that the provided PSK and PSK identifier are valid and that the context is in
- * a mode that supports PSKs.
- *
- * It returns 0 on success, or a negative error code on failure.
- */
-int gnutls_hpke_set_psk(gnutls_hpke_context_t ctx, const gnutls_datum_t *psk,
-                       const gnutls_datum_t *psk_id)
-{
-       if (ctx == NULL || psk == NULL || psk_id == NULL) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (!is_psk_mode(ctx->mode)) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (psk->size < HPKE_PSK_MIN_SIZE ||
-           psk->size > HPKE_MAX_PARAMETER_SIZE) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (psk_id->size == 0 || psk_id->size > HPKE_MAX_PARAMETER_SIZE) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       int ret = 0;
-
-       if (ctx->psk != NULL) {
-               _gnutls_free_key_datum(ctx->psk);
-               gnutls_free(ctx->psk);
-               ctx->psk = NULL;
-       }
-
-       if (ctx->psk_id != NULL) {
-               _gnutls_free_key_datum(ctx->psk_id);
-               gnutls_free(ctx->psk_id);
-               ctx->psk_id = NULL;
-       }
-
-       ctx->psk = gnutls_malloc(sizeof(*ctx->psk));
-       if (ctx->psk == NULL) {
-               ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-               goto error;
-       }
-
-       ctx->psk_id = gnutls_malloc(sizeof(*ctx->psk_id));
-       if (ctx->psk_id == NULL) {
-               ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-               goto error;
-       }
-
-       ctx->psk->size = psk->size;
-       ctx->psk->data = gnutls_malloc(ctx->psk->size);
-       if (ctx->psk->data == NULL) {
-               ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-               goto error;
-       }
-       memcpy(ctx->psk->data, psk->data, psk->size);
-
-       ctx->psk_id->size = psk_id->size;
-       ctx->psk_id->data = gnutls_malloc(ctx->psk_id->size);
-       if (ctx->psk_id->data == NULL) {
-               ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-               goto error;
-       }
-       memcpy(ctx->psk_id->data, psk_id->data, psk_id->size);
-
-       return ret;
-error:
-       if (ctx->psk != NULL) {
-               _gnutls_free_key_datum(ctx->psk);
-               gnutls_free(ctx->psk);
-               ctx->psk = NULL;
-       }
-
-       if (ctx->psk_id != NULL) {
-               _gnutls_free_key_datum(ctx->psk_id);
-               gnutls_free(ctx->psk_id);
-               ctx->psk_id = NULL;
-       }
-
-       return ret;
-}
-
-/**
- * gnutls_hpke_set_sender_privkey:
- * @ctx: The HPKE context to set the sender's private key for.
- * @sender_privkey: The sender's private key to set in the context.
- *
- * This function should be used by the sender in authenticated modes (Auth and AuthPSK) to set their private key in the
- * HPKE context.
- *
- * This function sets the sender's private key in the HPKE context. It securely erases any existing sender's private key
- * in the context before setting the new value. The function checks that the provided sender's private key is valid and
- * that the context is in a mode that supports authentication and that the role of the context is Sender.
- *
- * It returns 0 on success, or a negative error code on failure.
- */
-int gnutls_hpke_set_sender_privkey(gnutls_hpke_context_t ctx,
-                                  gnutls_privkey_t sender_privkey)
-{
-       if (ctx == NULL || sender_privkey == NULL) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (!is_auth_mode(ctx->mode)) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (ctx->role != GNUTLS_HPKE_ROLE_SENDER) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       gnutls_privkey_deinit(ctx->sender_privkey);
-       ctx->sender_privkey = NULL;
-
-       return _gnutls_hpke_privkey_clone(sender_privkey, &ctx->sender_privkey);
-}
-
-/**
- * gnutls_hpke_set_sender_pubkey:
- * @ctx: The HPKE context to set the sender's public key for.
- * @sender_pubkey: The sender's public key to set in the context.
- *
- * This function should be used by the receiver in authenticated modes (Auth and AuthPSK) to set the sender's public key
- * in the HPKE context.
- *
- * This function sets the sender's public key in the HPKE context. It securely erases any existing sender's public key
- * in the context before setting the new value. The function checks that the provided sender's public key is valid and
- * that the context is in a mode that supports authentication and that the role of the context is Receiver.
- *
- * It returns 0 on success, or a negative error code on failure.
- */
-int gnutls_hpke_set_sender_pubkey(gnutls_hpke_context_t ctx,
-                                 gnutls_pubkey_t sender_pubkey)
-{
-       if (ctx == NULL || sender_pubkey == NULL) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (!is_auth_mode(ctx->mode)) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       if (ctx->role != GNUTLS_HPKE_ROLE_RECEIVER) {
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-       }
-
-       gnutls_pubkey_deinit(ctx->sender_pubkey);
-       ctx->sender_pubkey = NULL;
-
-       return _gnutls_hpke_pubkey_clone(sender_pubkey, &ctx->sender_pubkey);
-}
-
 /**
  * gnutls_hpke_get_enc_size:
  * @ctx: The HPKE context to get the encapsulated key size for.
@@ -968,6 +783,9 @@ size_t gnutls_hpke_get_enc_size(const gnutls_hpke_context_t ctx)
  * no longer needed.
  * @receiver_pubkey: The receiver's public key to use for encapsulation. This must be a valid public key that is
  * compatible with the KEM algorithm specified in the HPKE context.
+ * @sender_privkey: The sender's private key needed for AuthEncap operation (optional).
+ * @psk: The pre-shared key (optional).
+ * @psk_id: The pre-shared key identifier (optional).
  *
  * This function performs the encapsulation operation of HPKE. It generates an encapsulated key (enc) that can be sent
  * to the receiver, who can then use it to derive the shared secret. The function checks that the context is properly
@@ -980,7 +798,9 @@ size_t gnutls_hpke_get_enc_size(const gnutls_hpke_context_t ctx)
  */
 int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                      gnutls_datum_t *enc,
-                     const gnutls_pubkey_t receiver_pubkey)
+                     const gnutls_pubkey_t receiver_pubkey,
+                     const gnutls_privkey_t sender_privkey,
+                     const gnutls_datum_t *psk, const gnutls_datum_t *psk_id)
 {
        int ret;
        if (ctx == NULL || enc == NULL || receiver_pubkey == NULL) {
@@ -996,18 +816,26 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
        }
 
        if (is_auth_mode(ctx->mode)) {
-               if (ctx->sender_privkey == NULL) {
+               if (sender_privkey == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               ret = validate_privkey_for_kem(ctx->sender_privkey, ctx->kem);
+               ret = validate_privkey_for_kem(sender_privkey, ctx->kem);
                if (ret < 0) {
                        return gnutls_assert_val(ret);
                }
        }
 
        if (is_psk_mode(ctx->mode)) {
-               if (ctx->psk == NULL || ctx->psk_id == NULL) {
+               if (psk == NULL || psk_id == NULL) {
+                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               }
+               if (psk->size < HPKE_PSK_MIN_SIZE ||
+                   psk->size > HPKE_MAX_PARAMETER_SIZE) {
+                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               }
+               if (psk_id->size == 0 ||
+                   psk_id->size > HPKE_MAX_PARAMETER_SIZE) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
        }
@@ -1026,7 +854,8 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
        gnutls_datum_t shared_secret = { shared_secret_buf, 0 };
 
        if (_gnutls_is_kem_dh(ctx->kem)) {
-               ret = dhkem_encap(ctx, receiver_pubkey, enc, &shared_secret);
+               ret = dhkem_encap(ctx, receiver_pubkey, sender_privkey, enc,
+                                 &shared_secret);
                if (ret < 0) {
                        gnutls_assert_val(ret);
                        goto error;
@@ -1036,7 +865,7 @@ int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = schedule(&shared_secret, info, ctx);
+       ret = schedule(ctx, &shared_secret, info, psk, psk_id);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto error;
@@ -1187,6 +1016,9 @@ cleanup:
  * @receiver_privkey: The receiver's private key to use for decapsulation. This must be a valid private key that is
  * compatible with the KEM algorithm specified in the HPKE context and that corresponds to the receiver's public key used
  * during encapsulation.
+ * @sender_pubkey: The sender's public key for AuthDecap operation (optional).
+ * @psk: The pre-shared key (optional).
+ * @psk_id: The pre-shared key identifier (optional).
  *
  * This function performs the decapsulation operation of HPKE. It takes the encapsulated key (enc) received from the
  * sender and uses it along with the receiver's private key to derive the shared secret. It then uses this shared secret
@@ -1199,7 +1031,9 @@ cleanup:
  */
 int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                      const gnutls_datum_t *enc,
-                     const gnutls_privkey_t receiver_privkey)
+                     const gnutls_privkey_t receiver_privkey,
+                     const gnutls_pubkey_t sender_pubkey,
+                     const gnutls_datum_t *psk, const gnutls_datum_t *psk_id)
 {
        int ret;
        if (ctx == NULL || enc == NULL || receiver_privkey == NULL) {
@@ -1215,18 +1049,26 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
        }
 
        if (is_auth_mode(ctx->mode)) {
-               if (ctx->sender_pubkey == NULL) {
+               if (sender_pubkey == NULL) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
 
-               ret = validate_pubkey_for_kem(ctx->sender_pubkey, ctx->kem);
+               ret = validate_pubkey_for_kem(sender_pubkey, ctx->kem);
                if (ret < 0) {
                        return gnutls_assert_val(ret);
                }
        }
 
        if (is_psk_mode(ctx->mode)) {
-               if (ctx->psk == NULL || ctx->psk_id == NULL) {
+               if (psk == NULL || psk_id == NULL) {
+                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               }
+               if (psk->size < HPKE_PSK_MIN_SIZE ||
+                   psk->size > HPKE_MAX_PARAMETER_SIZE) {
+                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               }
+               if (psk_id->size == 0 ||
+                   psk_id->size > HPKE_MAX_PARAMETER_SIZE) {
                        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                }
        }
@@ -1246,7 +1088,7 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
 
        if (_gnutls_is_kem_dh(ctx->kem)) {
                ret = dhkem_decap(ctx->kem, ctx->kdf, ctx->mode,
-                                 receiver_privkey, ctx->sender_pubkey, enc,
+                                 receiver_privkey, sender_pubkey, enc,
                                  &shared_secret);
                if (ret < 0) {
                        gnutls_assert_val(ret);
@@ -1258,7 +1100,7 @@ int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       ret = schedule(&shared_secret, info, ctx);
+       ret = schedule(ctx, &shared_secret, info, psk, psk_id);
        if (ret < 0) {
                gnutls_assert_val(ret);
                goto cleanup;
index 4e51d1b78a509dc3355ec3c62824fdcd14d8e9b7..6865e4993044ca37bbb499c4410e9cbc3d7a9865 100644 (file)
@@ -110,20 +110,13 @@ int gnutls_hpke_init(gnutls_hpke_context_t *ctx, gnutls_hpke_mode_t mode,
 
 int gnutls_hpke_deinit(gnutls_hpke_context_t ctx);
 
-int gnutls_hpke_set_psk(gnutls_hpke_context_t ctx, const gnutls_datum_t *psk,
-                       const gnutls_datum_t *psk_id);
-
-int gnutls_hpke_set_sender_privkey(gnutls_hpke_context_t ctx,
-                                  const gnutls_privkey_t sender_privkey);
-
-int gnutls_hpke_set_sender_pubkey(gnutls_hpke_context_t ctx,
-                                 const gnutls_pubkey_t sender_pubkey);
-
 size_t gnutls_hpke_get_enc_size(const gnutls_hpke_context_t ctx);
 
 int gnutls_hpke_encap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                      gnutls_datum_t *enc,
-                     const gnutls_pubkey_t receiver_pubkey);
+                     const gnutls_pubkey_t receiver_pubkey,
+                     const gnutls_privkey_t sender_privkey,
+                     const gnutls_datum_t *psk, const gnutls_datum_t *psk_id);
 
 int gnutls_hpke_seal(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
                     const gnutls_datum_t *plaintext,
@@ -131,7 +124,9 @@ int gnutls_hpke_seal(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
 
 int gnutls_hpke_decap(gnutls_hpke_context_t ctx, const gnutls_datum_t *info,
                      const gnutls_datum_t *enc,
-                     const gnutls_privkey_t receiver_privkey);
+                     const gnutls_privkey_t receiver_privkey,
+                     const gnutls_pubkey_t sender_pubkey,
+                     const gnutls_datum_t *psk, const gnutls_datum_t *psk_id);
 
 int gnutls_hpke_open(gnutls_hpke_context_t ctx, const gnutls_datum_t *aad,
                     const gnutls_datum_t *ciphertext,
index b901bad4883ac3f3e71c18b5acc381f029111849..f6ffdcf1a0bb5ce3950ab714e6881e63ab3ac849 100644 (file)
@@ -1472,9 +1472,6 @@ GNUTLS_3_8_13
     gnutls_hpke_decap;
     gnutls_hpke_init;
     gnutls_hpke_deinit;
-    gnutls_hpke_set_psk;
-    gnutls_hpke_set_sender_privkey;
-    gnutls_hpke_set_sender_pubkey;
     gnutls_hpke_get_enc_size;
     gnutls_hpke_seal;
     gnutls_hpke_open;
index 54da99cbc9d171e940f986ca622d0c4681e1c28b..7e1b9b7fca738be7bbd97b61d8cba6e9310e0a68 100644 (file)
@@ -133,16 +133,6 @@ static void test_hpke(const hpke_test_parameters_st *params)
                     gnutls_strerror(ret));
        }
 
-       if (params->psk != NULL && params->psk_id != NULL) {
-               ret = gnutls_hpke_set_psk(sender_ctx, params->psk,
-                                         params->psk_id);
-               if (ret < 0) {
-                       fail("gnutls_hpke_set_psk (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
-                            params->mode, params->kem, params->kdf,
-                            params->aead, gnutls_strerror(ret));
-               }
-       }
-
        if (params->ikmS != NULL) {
                ret = gnutls_privkey_init(&skS);
                if (ret < 0) {
@@ -159,13 +149,6 @@ static void test_hpke(const hpke_test_parameters_st *params)
                             params->mode, params->kem, params->kdf,
                             params->aead, gnutls_strerror(ret));
                }
-
-               ret = gnutls_hpke_set_sender_privkey(sender_ctx, skS);
-               if (ret < 0) {
-                       fail("gnutls_hpke_set_sender_privkey (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
-                            params->mode, params->kem, params->kdf,
-                            params->aead, gnutls_strerror(ret));
-               }
        }
 
        ret = gnutls_privkey_init(&skR);
@@ -184,7 +167,8 @@ static void test_hpke(const hpke_test_parameters_st *params)
                     gnutls_strerror(ret));
        }
 
-       ret = gnutls_hpke_encap(sender_ctx, &params->info, &enc, pkR);
+       ret = gnutls_hpke_encap(sender_ctx, &params->info, &enc, pkR, skS,
+                               params->psk, params->psk_id);
        if (ret < 0) {
                fail("gnutls_hpke_encap (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
                     params->mode, params->kem, params->kdf, params->aead,
@@ -206,26 +190,8 @@ static void test_hpke(const hpke_test_parameters_st *params)
                     gnutls_strerror(ret));
        }
 
-       if (params->psk != NULL && params->psk_id != NULL) {
-               ret = gnutls_hpke_set_psk(receiver_ctx, params->psk,
-                                         params->psk_id);
-               if (ret < 0) {
-                       fail("gnutls_hpke_set_psk (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
-                            params->mode, params->kem, params->kdf,
-                            params->aead, gnutls_strerror(ret));
-               }
-       }
-
-       if (params->ikmS != NULL) {
-               ret = gnutls_hpke_set_sender_pubkey(receiver_ctx, pkS);
-               if (ret < 0) {
-                       fail("gnutls_hpke_set_sender_pubkey (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
-                            params->mode, params->kem, params->kdf,
-                            params->aead, gnutls_strerror(ret));
-               }
-       }
-
-       ret = gnutls_hpke_decap(receiver_ctx, &params->info, &enc, skR);
+       ret = gnutls_hpke_decap(receiver_ctx, &params->info, &enc, skR, pkS,
+                               params->psk, params->psk_id);
        if (ret < 0) {
                fail("gnutls_hpke_decap (mode %d, kem: %d, kdf: %d, aead: %d) failed: %s\n",
                     params->mode, params->kem, params->kdf, params->aead,