9.4 Hybrid Public Key Encryption

Hybrid Public Key Encryption (HPKE) is a flexible cryptographic protocol which enables to encrypt arbitrary data to a recipient, by combining key encapsulation mechanisms (KEM) and authenticated encryption with additional data (AEAD). It is standardized as RFC 9180.

In GnuTLS, the basic functions to initialize, deinitialize, and derive a key pair are listed below.

int gnutls_hpke_init (gnutls_hpke_context_t * ctx, gnutls_hpke_mode_t mode, gnutls_hpke_role_t role, gnutls_hpke_kem_t kem, gnutls_hpke_kdf_t kdf, gnutls_hpke_aead_t aead)
int gnutls_hpke_deinit (gnutls_hpke_context_t ctx)
int gnutls_hpke_derive_keypair (gnutls_hpke_kem_t kem, const gnutls_datum_t * ikm, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey)

To encrypt data, each peer first needs to agree on a shared secret. This can be done using a given KEM algorithm, with the encapsulation and decapsulation operations.

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_privkey_t sender_privkey, const gnutls_datum_t * psk, const gnutls_datum_t * psk_id)
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_pubkey_t sender_pubkey, const gnutls_datum_t * psk, const gnutls_datum_t * psk_id)

Afterwards, data can be encrypted to a recipient using gnutls_hpke_seal and the recipient can decrypt it using gnutls_hpke_open. Applications can also export the keying material without actually encrypting or decrypting data, using gnutls_hpke_export.

int gnutls_hpke_seal (gnutls_hpke_context_t ctx, const gnutls_datum_t * aad, const gnutls_datum_t * plaintext, gnutls_datum_t * ciphertext)
int gnutls_hpke_open (gnutls_hpke_context_t ctx, const gnutls_datum_t * aad, const gnutls_datum_t * ciphertext, gnutls_datum_t * plaintext)
int gnutls_hpke_export (gnutls_hpke_context_t ctx, const gnutls_datum_t * exporter_context, size_t length, gnutls_datum_t * secret)