diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-17 10:52:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-17 10:52:33 +0000 |
commit | 2c3307fb903f427be3d021c5780b75cac9af2ce8 (patch) | |
tree | 65cf431f40b7481d81ae2dfce9576342686448f7 /upstream/debian-unstable/man3/OSSL_HPKE_CTX_new.3ssl | |
parent | Releasing progress-linux version 4.22.0-1~progress7.99u1. (diff) | |
download | manpages-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.3ssl | 593 |
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>. |