summaryrefslogtreecommitdiffstats
path: root/upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-17 10:52:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-17 10:52:33 +0000
commit2c3307fb903f427be3d021c5780b75cac9af2ce8 (patch)
tree65cf431f40b7481d81ae2dfce9576342686448f7 /upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl
parentReleasing progress-linux version 4.22.0-1~progress7.99u1. (diff)
downloadmanpages-l10n-2c3307fb903f427be3d021c5780b75cac9af2ce8.tar.xz
manpages-l10n-2c3307fb903f427be3d021c5780b75cac9af2ce8.zip
Merging upstream version 4.23.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl')
-rw-r--r--upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl593
1 files changed, 593 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl b/upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl
new file mode 100644
index 00000000..4ae668c6
--- /dev/null
+++ b/upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl
@@ -0,0 +1,593 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "OSSL_HPKE_CTX_NEW 3SSL"
+.TH OSSL_HPKE_CTX_NEW 3SSL 2024-04-04 3.2.2-dev OpenSSL
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+OSSL_HPKE_CTX_new, OSSL_HPKE_CTX_free,
+OSSL_HPKE_encap, OSSL_HPKE_decap,
+OSSL_HPKE_seal, OSSL_HPKE_open, OSSL_HPKE_export,
+OSSL_HPKE_suite_check, OSSL_HPKE_str2suite,
+OSSL_HPKE_keygen, OSSL_HPKE_get_grease_value,
+OSSL_HPKE_get_ciphertext_size, OSSL_HPKE_get_public_encap_size,
+OSSL_HPKE_get_recommended_ikmelen,
+OSSL_HPKE_CTX_set1_psk, OSSL_HPKE_CTX_set1_ikme,
+OSSL_HPKE_CTX_set1_authpriv, OSSL_HPKE_CTX_set1_authpub,
+OSSL_HPKE_CTX_get_seq, OSSL_HPKE_CTX_set_seq
+\&\- Hybrid Public Key Encryption (HPKE) functions
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 1
+\& #include <openssl/hpke.h>
+\&
+\& typedef struct {
+\& uint16_t kem_id;
+\& uint16_t kdf_id;
+\& uint16_t aead_id;
+\& } OSSL_HPKE_SUITE;
+\&
+\& OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role,
+\& OSSL_LIB_CTX *libctx, const char *propq);
+\& void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx);
+\&
+\& int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx,
+\& unsigned char *enc, size_t *enclen,
+\& const unsigned char *pub, size_t publen,
+\& const unsigned char *info, size_t infolen);
+\& int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx,
+\& unsigned char *ct, size_t *ctlen,
+\& const unsigned char *aad, size_t aadlen,
+\& const unsigned char *pt, size_t ptlen);
+\&
+\& int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite,
+\& unsigned char *pub, size_t *publen, EVP_PKEY **priv,
+\& const unsigned char *ikm, size_t ikmlen,
+\& OSSL_LIB_CTX *libctx, const char *propq);
+\& int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx,
+\& const unsigned char *enc, size_t enclen,
+\& EVP_PKEY *recippriv,
+\& const unsigned char *info, size_t infolen);
+\& int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx,
+\& unsigned char *pt, size_t *ptlen,
+\& const unsigned char *aad, size_t aadlen,
+\& const unsigned char *ct, size_t ctlen);
+\&
+\& int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx,
+\& unsigned char *secret, size_t secretlen,
+\& const unsigned char *label, size_t labellen);
+\&
+\& int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv);
+\& int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx,
+\& unsigned char *pub, size_t publen);
+\& int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx,
+\& const char *pskid,
+\& const unsigned char *psk, size_t psklen);
+\&
+\& int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq);
+\& int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq);
+\&
+\& int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx,
+\& const unsigned char *ikme, size_t ikmelen);
+\&
+\& int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite);
+\& int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in,
+\& OSSL_HPKE_SUITE *suite,
+\& unsigned char *enc, size_t *enclen,
+\& unsigned char *ct, size_t ctlen,
+\& OSSL_LIB_CTX *libctx, const char *propq);
+\&
+\& int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite);
+\& size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen);
+\& size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite);
+\& size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite);
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+These functions provide an API for using the form of Hybrid Public Key
+Encryption (HPKE) defined in RFC9180. Understanding the HPKE specification
+is likely required before using these APIs. HPKE is used by various
+other IETF specifications, including the TLS Encrypted Client
+Hello (ECH) specification and others.
+.PP
+HPKE is a standardised, highly flexible construct for encrypting "to" a public
+key that supports combinations of a key encapsulation method (KEM), a key
+derivation function (KDF) and an authenticated encryption with additional data
+(AEAD) algorithm, with optional sender authentication.
+.PP
+The sender and a receiver here will generally be using some application or
+protocol making use of HPKE. For example, with ECH,
+the sender will be a browser and the receiver will be a web server.
+.SS "Data Structures"
+.IX Subsection "Data Structures"
+\&\fBOSSL_HPKE_SUITE\fR is a structure that holds identifiers for the algorithms
+used for KEM, KDF and AEAD operations.
+.PP
+\&\fBOSSL_HPKE_CTX\fR is a context that maintains internal state as HPKE
+operations are carried out. Separate \fBOSSL_HPKE_CTX\fR objects must be used for
+the sender and receiver. Attempting to use a single context for both will
+result in errors.
+.SS "OSSL_HPKE_SUITE Identifiers"
+.IX Subsection "OSSL_HPKE_SUITE Identifiers"
+The identifiers used by \fBOSSL_HPKE_SUITE\fR are:
+.PP
+The KEM identifier \fIkem_id\fR is one of the following:
+.IP "0x10 \fBOSSL_HPKE_KEM_ID_P256\fR" 4
+.IX Item "0x10 OSSL_HPKE_KEM_ID_P256"
+.PD 0
+.IP "0x11 \fBOSSL_HPKE_KEM_ID_P384\fR" 4
+.IX Item "0x11 OSSL_HPKE_KEM_ID_P384"
+.IP "0x12 \fBOSSL_HPKE_KEM_ID_P521\fR" 4
+.IX Item "0x12 OSSL_HPKE_KEM_ID_P521"
+.IP "0x20 \fBOSSL_HPKE_KEM_ID_X25519\fR" 4
+.IX Item "0x20 OSSL_HPKE_KEM_ID_X25519"
+.IP "0x21 \fBOSSL_HPKE_KEM_ID_X448\fR" 4
+.IX Item "0x21 OSSL_HPKE_KEM_ID_X448"
+.PD
+.PP
+The KDF identifier \fIkdf_id\fR is one of the following:
+.IP "0x01 \fBOSSL_HPKE_KDF_ID_HKDF_SHA256\fR" 4
+.IX Item "0x01 OSSL_HPKE_KDF_ID_HKDF_SHA256"
+.PD 0
+.IP "0x02 \fBOSSL_HPKE_KDF_ID_HKDF_SHA384\fR" 4
+.IX Item "0x02 OSSL_HPKE_KDF_ID_HKDF_SHA384"
+.IP "0x03 \fBOSSL_HPKE_KDF_ID_HKDF_SHA512\fR" 4
+.IX Item "0x03 OSSL_HPKE_KDF_ID_HKDF_SHA512"
+.PD
+.PP
+The AEAD identifier \fIaead_id\fR is one of the following:
+.IP "0x01 \fBOSSL_HPKE_AEAD_ID_AES_GCM_128\fR" 4
+.IX Item "0x01 OSSL_HPKE_AEAD_ID_AES_GCM_128"
+.PD 0
+.IP "0x02 \fBOSSL_HPKE_AEAD_ID_AES_GCM_256\fR" 4
+.IX Item "0x02 OSSL_HPKE_AEAD_ID_AES_GCM_256"
+.IP "0x03 \fBOSSL_HPKE_AEAD_ID_CHACHA_POLY1305\fR" 4
+.IX Item "0x03 OSSL_HPKE_AEAD_ID_CHACHA_POLY1305"
+.IP "0xFFFF \fBOSSL_HPKE_AEAD_ID_EXPORTONLY\fR" 4
+.IX Item "0xFFFF OSSL_HPKE_AEAD_ID_EXPORTONLY"
+.PD
+The last identifier above indicates that AEAD operations are not needed.
+\&\fBOSSL_HPKE_export()\fR can be used, but \fBOSSL_HPKE_open()\fR and \fBOSSL_HPKE_seal()\fR will
+return an error if called with a context using that AEAD identifier.
+.SS "HPKE Modes"
+.IX Subsection "HPKE Modes"
+HPKE supports the following variants of Authentication using a mode Identifier:
+.IP "\fBOSSL_HPKE_MODE_BASE\fR, 0x00" 4
+.IX Item "OSSL_HPKE_MODE_BASE, 0x00"
+Authentication is not used.
+.IP "\fBOSSL_HPKE_MODE_PSK\fR, 0x01" 4
+.IX Item "OSSL_HPKE_MODE_PSK, 0x01"
+Authenticates possession of a pre-shared key (PSK).
+.IP "\fBOSSL_HPKE_MODE_AUTH\fR, 0x02" 4
+.IX Item "OSSL_HPKE_MODE_AUTH, 0x02"
+Authenticates possession of a KEM-based sender private key.
+.IP "\fBOSSL_HPKE_MODE_PSKAUTH\fR, 0x03" 4
+.IX Item "OSSL_HPKE_MODE_PSKAUTH, 0x03"
+A combination of \fBOSSL_HPKE_MODE_PSK\fR and \fBOSSL_HPKE_MODE_AUTH\fR.
+Both the PSK and the senders authentication public/private must be
+supplied before the encapsulation/decapsulation operation will work.
+.PP
+For further information related to authentication see "Pre-Shared Key HPKE
+modes" and "Sender-authenticated HPKE Modes".
+.SS "HPKE Roles"
+.IX Subsection "HPKE Roles"
+HPKE contexts have a role \- either sender or receiver. This is used
+to control which functions can be called and so that senders do not
+reuse a key and nonce with different plaintexts.
+.PP
+\&\fBOSSL_HPKE_CTX_free()\fR, \fBOSSL_HPKE_export()\fR, \fBOSSL_HPKE_CTX_set1_psk()\fR,
+and \fBOSSL_HPKE_CTX_get_seq()\fR can be called regardless of role.
+.IP "\fBOSSL_HPKE_ROLE_SENDER\fR, 0" 4
+.IX Item "OSSL_HPKE_ROLE_SENDER, 0"
+An \fIOSSL_HPKE_CTX\fR with this role can be used with
+\&\fBOSSL_HPKE_encap()\fR, \fBOSSL_HPKE_seal()\fR, \fBOSSL_HPKE_CTX_set1_ikme()\fR and
+\&\fBOSSL_HPKE_CTX_set1_authpriv()\fR.
+.IP "\fBOSSL_HPKE_ROLE_RECEIVER\fR, 1" 4
+.IX Item "OSSL_HPKE_ROLE_RECEIVER, 1"
+An \fIOSSL_HPKE_CTX\fR with this role can be used with \fBOSSL_HPKE_decap()\fR,
+\&\fBOSSL_HPKE_open()\fR, \fBOSSL_HPKE_CTX_set1_authpub()\fR and \fBOSSL_HPKE_CTX_set_seq()\fR.
+.PP
+Calling a function with an incorrect role set on \fIOSSL_HPKE_CTX\fR will result
+in an error.
+.SS "Parameter Size Limits"
+.IX Subsection "Parameter Size Limits"
+In order to improve interoperability, RFC9180, section 7.2.1 suggests a
+RECOMMENDED maximum size of 64 octets for various input parameters. In this
+implementation we apply a limit of 66 octets for the \fIikmlen\fR, \fIpsklen\fR, and
+\&\fIlabellen\fR parameters, and for the length of the string \fIpskid\fR for HPKE
+functions below. The constant \fIOSSL_HPKE_MAX_PARMLEN\fR is defined as the limit
+of this value. (We chose 66 octets so that we can validate all the test
+vectors present in RFC9180, Appendix A.)
+.PP
+In accordance with RFC9180, section 9.5, we define a constant
+\&\fIOSSL_HPKE_MIN_PSKLEN\fR with a value of 32 for the minimum length of a
+pre-shared key, passed in \fIpsklen\fR.
+.PP
+While RFC9180 also RECOMMENDS a 64 octet limit for the \fIinfolen\fR parameter,
+that is not sufficient for TLS Encrypted ClientHello (ECH) processing, so we
+enforce a limit of \fIOSSL_HPKE_MAX_INFOLEN\fR with a value of 1024 as the limit
+for the \fIinfolen\fR parameter.
+.SS "Context Construct/Free"
+.IX Subsection "Context Construct/Free"
+\&\fBOSSL_HPKE_CTX_new()\fR creates a \fBOSSL_HPKE_CTX\fR context object used for
+subsequent HPKE operations, given a \fImode\fR (See "HPKE Modes"), \fIsuite\fR (see
+"OSSL_HPKE_SUITE Identifiers") and a \fIrole\fR (see "HPKE Roles"). The
+\&\fIlibctx\fR and \fIpropq\fR are used when fetching algorithms from providers and may
+be set to NULL.
+.PP
+\&\fBOSSL_HPKE_CTX_free()\fR frees the \fIctx\fR \fBOSSL_HPKE_CTX\fR that was created
+previously by a call to \fBOSSL_HPKE_CTX_new()\fR.
+.SS "Sender APIs"
+.IX Subsection "Sender APIs"
+A sender's goal is to use HPKE to encrypt using a public key, via use of a
+KEM, then a KDF and finally an AEAD. The first step is to encapsulate (using
+\&\fBOSSL_HPKE_encap()\fR) the sender's public value using the recipient's public key,
+(\fIpub\fR) and to internally derive secrets. This produces the encapsulated public value
+(\fIenc\fR) to be sent to the recipient in whatever protocol is using HPKE. Having done the
+encapsulation step, the sender can then make one or more calls to
+\&\fBOSSL_HPKE_seal()\fR to encrypt plaintexts using the secret stored within \fIctx\fR.
+.PP
+\&\fBOSSL_HPKE_encap()\fR uses the HPKE context \fIctx\fR, the recipient public value
+\&\fIpub\fR of size \fIpublen\fR, and an optional \fIinfo\fR parameter of size \fIinfolen\fR,
+to produce the encapsulated public value \fIenc\fR.
+On input \fIenclen\fR should contain the maximum size of the \fIenc\fR buffer, and returns
+the output size. An error will occur if the input \fIenclen\fR is
+smaller than the value returned from \fBOSSL_HPKE_get_public_encap_size()\fR.
+\&\fIinfo\fR may be used to bind other protocol or application artefacts such as identifiers.
+Generally, the encapsulated public value \fIenc\fR corresponds to a
+single-use ephemeral private value created as part of the encapsulation
+process. Only a single call to \fBOSSL_HPKE_encap()\fR is allowed for a given
+\&\fBOSSL_HPKE_CTX\fR.
+.PP
+\&\fBOSSL_HPKE_seal()\fR takes the \fBOSSL_HPKE_CTX\fR context \fIctx\fR, the plaintext
+buffer \fIpt\fR of size \fIptlen\fR and optional additional authenticated data buffer
+\&\fIaad\fR of size \fIaadlen\fR, and returns the ciphertext \fIct\fR of size \fIctlen\fR.
+On input \fIctlen\fR should contain the maximum size of the \fIct\fR buffer, and returns
+the output size. An error will occur if the input \fIctlen\fR is
+smaller than the value returned from \fBOSSL_HPKE_get_public_encap_size()\fR.
+.PP
+\&\fBOSSL_HPKE_encap()\fR must be called before the \fBOSSL_HPKE_seal()\fR. \fBOSSL_HPKE_seal()\fR
+may be called multiple times, with an internal "nonce" being incremented by one
+after each call.
+.SS "Recipient APIs"
+.IX Subsection "Recipient APIs"
+Recipients using HPKE require a typically less ephemeral private value so that
+the public value can be distributed to potential senders via whatever protocol
+is using HPKE. For this reason, recipients will generally first generate a key
+pair and will need to manage their private key value using standard mechanisms
+outside the scope of this API. Private keys use normal \fBEVP_PKEY\fR\|(3) pointers
+so normal private key management mechanisms can be used for the relevant
+values.
+.PP
+In order to enable encapsulation, the recipient needs to make it's public value
+available to the sender. There is no generic HPKE format defined for that \- the
+relevant formatting is intended to be defined by the application/protocols that
+makes use of HPKE. ECH for example defines an ECHConfig data structure that
+combines the public value with other ECH data items. Normal library functions
+must therefore be used to extract the public value in the required format based
+on the \fBEVP_PKEY\fR\|(3) for the private value.
+.PP
+\&\fBOSSL_HPKE_keygen()\fR provides a way for recipients to generate a key pair based
+on the HPKE \fIsuite\fR to be used. It returns a \fBEVP_PKEY\fR\|(3) pointer
+for the private value \fIpriv\fR and a encoded public key \fIpub\fR of size \fIpublen\fR.
+On input \fIpublen\fR should contain the maximum size of the \fIpub\fR buffer, and
+returns the output size. An error will occur if the input \fIpublen\fR is too small.
+The \fIlibctx\fR and \fIpropq\fR are used when fetching algorithms from providers
+and may be set to NULL.
+The HPKE specification also defines a deterministic key generation scheme where
+the private value is derived from initial keying material (IKM), so
+\&\fBOSSL_HPKE_keygen()\fR also has an option to use that scheme, using the \fIikm\fR
+parameter of size \fIikmlen\fR. If either \fIikm\fR is NULL or \fIikmlen\fR is zero,
+then a randomly generated key for the relevant \fIsuite\fR will be produced.
+If required \fIikmlen\fR should be greater than or equal to
+\&\fBOSSL_HPKE_get_recommended_ikmelen()\fR.
+.PP
+\&\fBOSSL_HPKE_decap()\fR takes as input the sender's encapsulated public value
+produced by \fBOSSL_HPKE_encap()\fR (\fIenc\fR) and the recipient's \fBEVP_PKEY\fR\|(3)
+pointer (\fIprov\fR), and then re-generates the internal secret derived by the
+sender. As before, an optional \fIinfo\fR parameter allows binding that derived
+secret to other application/protocol artefacts. Only a single call to
+\&\fBOSSL_HPKE_decap()\fR is allowed for a given \fBOSSL_HPKE_CTX\fR.
+.PP
+\&\fBOSSL_HPKE_open()\fR is used by the recipient to decrypt the ciphertext \fIct\fR of
+size \fIctlen\fR using the \fIctx\fR and additional authenticated data \fIaad\fR of
+size \fIaadlen\fR, to produce the plaintext \fIpt\fR of size \fIptlen\fR.
+On input \fIptlen\fR should contain the maximum size of the \fIpt\fR buffer, and
+returns the output size. A \fIpt\fR buffer that is the same size as the
+\&\fIct\fR buffer will suffice \- generally the plaintext output will be
+a little smaller than the ciphertext input.
+An error will occur if the input \fIptlen\fR is too small.
+\&\fBOSSL_HPKE_open()\fR may be called multiple times, but as with \fBOSSL_HPKE_seal()\fR
+there is an internally incrementing nonce value so ciphertexts need to be
+presented in the same order as used by the \fBOSSL_HPKE_seal()\fR.
+See "Re-sequencing" if you need to process multiple ciphertexts in a
+different order.
+.SS "Exporting Secrets"
+.IX Subsection "Exporting Secrets"
+HPKE defines a way to produce exported secrets for use by the
+application.
+.PP
+\&\fBOSSL_HPKE_export()\fR takes as input the \fBOSSL_HPKE_CTX\fR, and an application
+supplied label \fIlabel\fR of size \fIlabellen\fR, to produce a secret \fIsecret\fR
+of size \fIsecretlen\fR. The sender must first call \fBOSSL_HPKE_encap()\fR, and the
+receiver must call \fBOSSL_HPKE_decap()\fR in order to derive the same shared secret.
+.PP
+Multiple calls to \fBOSSL_HPKE_export()\fR with the same inputs will produce the
+same secret.
+\&\fIOSSL_HPKE_AEAD_ID_EXPORTONLY\fR may be used as the \fBOSSL_HPKE_SUITE\fR \fIaead_id\fR
+that is passed to \fBOSSL_HPKE_CTX_new()\fR if the user needs to produce a shared
+secret, but does not wish to perform HPKE encryption.
+.SS "Sender-authenticated HPKE Modes"
+.IX Subsection "Sender-authenticated HPKE Modes"
+HPKE defines modes that support KEM-based sender-authentication
+\&\fBOSSL_HPKE_MODE_AUTH\fR and \fBOSSL_HPKE_MODE_PSKAUTH\fR. This works by binding
+the sender's authentication private/public values into the encapsulation and
+decapsulation operations. The key used for such modes must also use the same
+KEM as used for the overall exchange. \fBOSSL_HPKE_keygen()\fR can be used to
+generate the private value required.
+.PP
+\&\fBOSSL_HPKE_CTX_set1_authpriv()\fR can be used by the sender to set the senders
+private \fIpriv\fR \fBEVP_PKEY\fR key into the \fBOSSL_HPKE_CTX\fR \fIctx\fR before calling
+\&\fBOSSL_HPKE_encap()\fR.
+.PP
+\&\fBOSSL_HPKE_CTX_set1_authpub()\fR can be used by the receiver to set the senders
+encoded pub key \fIpub\fR of size \fIpublen\fR into the \fBOSSL_HPKE_CTX\fR \fIctx\fR before
+calling \fBOSSL_HPKE_decap()\fR.
+.SS "Pre-Shared Key HPKE modes"
+.IX Subsection "Pre-Shared Key HPKE modes"
+HPKE also defines a symmetric equivalent to the authentication described above
+using a pre-shared key (PSK) and a PSK identifier. PSKs can be used with the
+\&\fBOSSL_HPKE_MODE_PSK\fR and \fBOSSL_HPKE_MODE_PSKAUTH\fR modes.
+.PP
+\&\fBOSSL_HPKE_CTX_set1_psk()\fR sets the PSK identifier \fIpskid\fR string, and PSK buffer
+\&\fIpsk\fR of size \fIpsklen\fR into the \fIctx\fR. If required this must be called
+before \fBOSSL_HPKE_encap()\fR or \fBOSSL_HPKE_decap()\fR.
+As per RFC9180, if required, both \fIpsk\fR and \fIpskid\fR must be set to non-NULL values.
+As PSKs are symmetric the same calls must happen on both sender and receiver
+sides.
+.SS "Deterministic key generation for senders"
+.IX Subsection "Deterministic key generation for senders"
+Normally the senders ephemeral private key is generated randomly inside
+\&\fBOSSL_HPKE_encap()\fR and remains secret.
+\&\fBOSSL_HPKE_CTX_set1_ikme()\fR allows the user to override this behaviour by
+setting a deterministic input key material \fIikm\fR of size \fIikmlen\fR into
+the \fBOSSL_HPKE_CTX\fR \fIctx\fR.
+If required \fBOSSL_HPKE_CTX_set1_ikme()\fR can optionally be called before
+\&\fBOSSL_HPKE_encap()\fR.
+\&\fIikmlen\fR should be greater than or equal to \fBOSSL_HPKE_get_recommended_ikmelen()\fR.
+.PP
+It is generally undesirable to use \fBOSSL_HPKE_CTX_set1_ikme()\fR, since it
+exposes the relevant secret to the application rather then preserving it
+within the library, and is more likely to result in use of predictable values
+or values that leak.
+.SS Re-sequencing
+.IX Subsection "Re-sequencing"
+Some protocols may have to deal with packet loss while still being able to
+decrypt arriving packets later. We provide a way to set the increment used for
+the nonce to the next subsequent call to \fBOSSL_HPKE_open()\fR (but not to
+\&\fBOSSL_HPKE_seal()\fR as explained below). The \fBOSSL_HPKE_CTX_set_seq()\fR API can be
+used for such purposes with the \fIseq\fR parameter value resetting the internal
+nonce increment to be used for the next call.
+.PP
+A baseline nonce value is established based on the encapsulation or
+decapsulation operation and is then incremented by 1 for each call to seal or
+open. (In other words, the first \fIseq\fR increment defaults to zero.)
+.PP
+If a caller needs to determine how many calls to seal or open have been made
+the \fBOSSL_HPKE_CTX_get_seq()\fR API can be used to retrieve the increment (in the
+\&\fIseq\fR output) that will be used in the next call to seal or open. That would
+return 0 before the first call a sender made to \fBOSSL_HPKE_seal()\fR and 1 after
+that first call.
+.PP
+Note that reuse of the same nonce and key with different plaintexts would
+be very dangerous and could lead to loss of confidentiality and integrity.
+We therefore only support application control over \fIseq\fR for decryption
+(i.e. \fBOSSL_HPKE_open()\fR) operations.
+.PP
+For compatibility with other implementations these \fIseq\fR increments are
+represented as \fIuint64_t\fR.
+.SS "Protocol Convenience Functions"
+.IX Subsection "Protocol Convenience Functions"
+Additional convenience APIs allow the caller to access internal details of
+local HPKE support and/or algorithms, such as parameter lengths.
+.PP
+\&\fBOSSL_HPKE_suite_check()\fR checks if a specific \fBOSSL_HPKE_SUITE\fR \fIsuite\fR
+is supported locally.
+.PP
+To assist with memory allocation, \fBOSSL_HPKE_get_ciphertext_size()\fR provides a
+way for the caller to know by how much ciphertext will be longer than a
+plaintext of length \fIclearlen\fR. (AEAD algorithms add a data integrity tag,
+so there is a small amount of ciphertext expansion.)
+.PP
+\&\fBOSSL_HPKE_get_public_encap_size()\fR provides a way for senders to know how big
+the encapsulated public value will be for a given HPKE \fIsuite\fR.
+.PP
+\&\fBOSSL_HPKE_get_recommended_ikmelen()\fR returns the recommended Input Key Material
+size (in bytes) for a given \fIsuite\fR. This is needed in cases where the same
+public value needs to be regenerated by a sender before calling \fBOSSL_HPKE_seal()\fR.
+\&\fIikmlen\fR should be at least this size.
+.PP
+\&\fBOSSL_HPKE_get_grease_value()\fR produces values of the appropriate length for a
+given \fIsuite_in\fR value (or a random value if \fIsuite_in\fR is NULL) so that a
+protocol using HPKE can send so-called GREASE (see RFC8701) values that are
+harder to distinguish from a real use of HPKE. The buffer sizes should
+be supplied on input. The output \fIenc\fR value will have an appropriate
+length for \fIsuite_out\fR and a random value, and the \fIct\fR output will be
+a random value. The relevant sizes for buffers can be found using
+\&\fBOSSL_HPKE_get_ciphertext_size()\fR and \fBOSSL_HPKE_get_public_encap_size()\fR.
+.PP
+\&\fBOSSL_HPKE_str2suite()\fR maps input \fIstr\fR strings to an \fBOSSL_HPKE_SUITE\fR object.
+The input \fIstr\fR should be a comma-separated string with a KEM,
+KDF and AEAD name in that order, for example "x25519,hkdf\-sha256,aes128gcm".
+This can be used by command line tools that accept string form names for HPKE
+codepoints. Valid (case-insensitive) names are:
+"p256", "p384", "p521", "x25519" and "x448" for KEM,
+"hkdf\-SHA256", "hkdf\-SHA384" and "hkdf\-SHA512" for KDF, and
+"aes\-gcm\-128", "aes\-gcm\-256" and "chacha20\-poly1305" for AEAD.
+String variants of the numbers listed in "OSSL_HPKE_SUITE Identifiers"
+can also be used.
+.SH "RETURN VALUES"
+.IX Header "RETURN VALUES"
+\&\fBOSSL_HPKE_CTX_new()\fR returns an OSSL_HPKE_CTX pointer or NULL on error.
+.PP
+\&\fBOSSL_HPKE_get_ciphertext_size()\fR, \fBOSSL_HPKE_get_public_encap_size()\fR,
+\&\fBOSSL_HPKE_get_recommended_ikmelen()\fR all return a size_t with the
+relevant value or zero on error.
+.PP
+All other functions return 1 for success or zero for error.
+.SH EXAMPLES
+.IX Header "EXAMPLES"
+This example demonstrates a minimal round-trip using HPKE.
+.PP
+.Vb 4
+\& #include <stddef.h>
+\& #include <string.h>
+\& #include <openssl/hpke.h>
+\& #include <openssl/evp.h>
+\&
+\& /*
+\& * this is big enough for this example, real code would need different
+\& * handling
+\& */
+\& #define LBUFSIZE 48
+\&
+\& /* Do a round\-trip, generating a key, encrypting and decrypting */
+\& int main(int argc, char **argv)
+\& {
+\& int ok = 0;
+\& int hpke_mode = OSSL_HPKE_MODE_BASE;
+\& OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT;
+\& OSSL_HPKE_CTX *sctx = NULL, *rctx = NULL;
+\& EVP_PKEY *priv = NULL;
+\& unsigned char pub[LBUFSIZE];
+\& size_t publen = sizeof(pub);
+\& unsigned char enc[LBUFSIZE];
+\& size_t enclen = sizeof(enc);
+\& unsigned char ct[LBUFSIZE];
+\& size_t ctlen = sizeof(ct);
+\& unsigned char clear[LBUFSIZE];
+\& size_t clearlen = sizeof(clear);
+\& const unsigned char *pt = "a message not in a bottle";
+\& size_t ptlen = strlen((char *)pt);
+\& const unsigned char *info = "Some info";
+\& size_t infolen = strlen((char *)info);
+\& unsigned char aad[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+\& size_t aadlen = sizeof(aad);
+\&
+\& /*
+\& * Generate receiver\*(Aqs key pair.
+\& * The receiver gives this public key to the sender.
+\& */
+\& if (OSSL_HPKE_keygen(hpke_suite, pub, &publen, &priv,
+\& NULL, 0, NULL, NULL) != 1)
+\& goto err;
+\&
+\& /* sender\*(Aqs actions \- encrypt data using the receivers public key */
+\& if ((sctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite,
+\& OSSL_HPKE_ROLE_SENDER,
+\& NULL, NULL)) == NULL)
+\& goto err;
+\& if (OSSL_HPKE_encap(sctx, enc, &enclen, pub, publen, info, infolen) != 1)
+\& goto err;
+\& if (OSSL_HPKE_seal(sctx, ct, &ctlen, aad, aadlen, pt, ptlen) != 1)
+\& goto err;
+\&
+\& /* receiver\*(Aqs actions \- decrypt data using the receivers private key */
+\& if ((rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite,
+\& OSSL_HPKE_ROLE_RECEIVER,
+\& NULL, NULL)) == NULL)
+\& goto err;
+\& if (OSSL_HPKE_decap(rctx, enc, enclen, priv, info, infolen) != 1)
+\& goto err;
+\& if (OSSL_HPKE_open(rctx, clear, &clearlen, aad, aadlen, ct, ctlen) != 1)
+\& goto err;
+\& ok = 1;
+\& err:
+\& /* clean up */
+\& printf(ok ? "All Good!\en" : "Error!\en");
+\& OSSL_HPKE_CTX_free(rctx);
+\& OSSL_HPKE_CTX_free(sctx);
+\& EVP_PKEY_free(priv);
+\& return 0;
+\& }
+.Ve
+.SH WARNINGS
+.IX Header "WARNINGS"
+Note that the \fBOSSL_HPKE_CTX_set_seq()\fR API could be dangerous \- if used with GCM
+that could lead to nonce-reuse, which is a known danger. So avoid that
+entirely, or be very very careful when using that API.
+.PP
+Use of an IKM value for deterministic key generation (via
+\&\fBOSSL_HPKE_CTX_set1_ikme()\fR or \fBOSSL_HPKE_keygen()\fR) creates the potential for
+leaking keys (or IKM values). Only use that if really needed and if you
+understand how keys or IKM values could be abused.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+The RFC9180 specification: https://datatracker.ietf.org/doc/rfc9180/
+.SH HISTORY
+.IX Header "HISTORY"
+This functionality described here was added in OpenSSL 3.2.
+.SH COPYRIGHT
+.IX Header "COPYRIGHT"
+Copyright 2022\-2023 The OpenSSL Project Authors. All Rights Reserved.
+.PP
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+<https://www.openssl.org/source/license.html>.