OSSL_HPKE_CTX_NEW(3ossl)
okay bestie, welcome to OSSL_HPKE_CTX_NEW(3ossl) β the OpenSSL 3ossl manual page for the HPKE glow-up, part 1. no cap, weβre keeping every function, every value, and every little detail. π
π 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. π
β¨ SYNOPSIS β¨
#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);
πΈ DESCRIPTION πΈ
okay so these functions give you an API for using the form of Hybrid Public Key Encryption (HPKE) defined in RFC9180. bestie, understanding the HPKE specification is likely required before using these APIs β no cap, itβs giving βread the spec firstβ energy. HPKE is used by various other IETF specifications, including the TLS Encrypted Client Hello (ECH) specification and others. π¦
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. π₯
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. π
𧬠Data Structures π§¬
OSSL_HPKE_SUITE is a structure that holds identifiers for the algorithms used for KEM, KDF and AEAD operations. π
OSSL_HPKE_CTX is a context that maintains internal state as HPKE operations are carried out. Separate OSSL_HPKE_CTX objects must be used for the sender and receiver. Attempting to use a single context for both will result in errors.
β οΈ bestie, this is the warning: separate contexts for sender and receiver. one context for both = errors, periodt. π
π§ OSSL_HPKE_SUITE Identifiers π§
The identifiers used by OSSL_HPKE_SUITE are:
The KEM identifier kem_id is one of the following:
0x10βOSSL_HPKE_KEM_ID_P2560x11βOSSL_HPKE_KEM_ID_P3840x12βOSSL_HPKE_KEM_ID_P5210x20βOSSL_HPKE_KEM_ID_X255190x21βOSSL_HPKE_KEM_ID_X448
The KDF identifier kdf_id is one of the following:
0x01βOSSL_HPKE_KDF_ID_HKDF_SHA2560x02βOSSL_HPKE_KDF_ID_HKDF_SHA3840x03βOSSL_HPKE_KDF_ID_HKDF_SHA512
The AEAD identifier aead_id is one of the following:
0x01βOSSL_HPKE_AEAD_ID_AES_GCM_1280x02βOSSL_HPKE_AEAD_ID_AES_GCM_2560x03βOSSL_HPKE_AEAD_ID_CHACHA_POLY13050xFFFFβOSSL_HPKE_AEAD_ID_EXPORTONLY
The last identifier above indicates that AEAD operations are not needed. OSSL_HPKE_export() can be used, but OSSL_HPKE_open() and OSSL_HPKE_seal() will return an error if called with a context using that AEAD identifier. π«Ά
π HPKE Modes π
HPKE supports the following variants of Authentication using a mode Identifier:
OSSL_HPKE_MODE_BASE,0x00β Authentication is not used.OSSL_HPKE_MODE_PSK,0x01β Authenticates possession of a pre-shared key (PSK).OSSL_HPKE_MODE_AUTH,0x02β Authenticates possession of a KEM-based sender private key.OSSL_HPKE_MODE_PSKAUTH,0x03β A combination ofOSSL_HPKE_MODE_PSKandOSSL_HPKE_MODE_AUTH. Both the PSK and the senders authentication public/private must be supplied before the encapsulation/decapsulation operation will work.
For further information related to authentication see βPre-Shared Key HPKE modesβ and βSender-authenticated HPKE Modesβ. π
π 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. π
OSSL_HPKE_CTX_free(), OSSL_HPKE_export(), OSSL_HPKE_CTX_set1_psk(), and OSSL_HPKE_CTX_get_seq() can be called regardless of role. β¨
OSSL_HPKE_ROLE_SENDER,0β AnOSSL_HPKE_CTXwith this role can be used withOSSL_HPKE_encap(),OSSL_HPKE_seal(),OSSL_HPKE_CTX_set1_ikme()andOSSL_HPKE_CTX_set1_authpriv().OSSL_HPKE_ROLE_RECEIVER,1β AnOSSL_HPKE_CTXwith this role can be used withOSSL_HPKE_decap(),OSSL_HPKE_open(),OSSL_HPKE_CTX_set1_authpub()andOSSL_HPKE_CTX_set_seq().
Calling a function with an incorrect role set on OSSL_HPKE_CTX will result in an error. π
π 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 ikmlen, psklen, and labellen parameters, and for the length of the string pskid for HPKE functions below. The constant OSSL_HPKE_MAX_PARMLEN 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.) π
In accordance with RFC9180, section 9.5, we define a constant OSSL_HPKE_MIN_PSKLEN with a value of 32 for the minimum length of a pre-shared key, passed in psklen. π
While RFC9180 also RECOMMENDS a 64 octet limit for the infolen parameter, that is not sufficient for TLS Encrypted ClientHello (ECH) processing, so we enforce a limit of OSSL_HPKE_MAX_INFOLEN with a value of 1024 as the limit for the infolen parameter. π
π οΈ Context Construct/Free π οΈ
OSSL_HPKE_CTX_new() creates a OSSL_HPKE_CTX context object used for subsequent HPKE operations, given a mode (See βHPKE Modesβ), suite (see βOSSL_HPKE_SUITE Identifiersβ) and a role (see βHPKE Rolesβ). The libctx and propq are used when fetching algorithms from providers and may be set to NULL. β¨
OSSL_HPKE_CTX_free() frees the ctx OSSL_HPKE_CTX that was created previously by a call to OSSL_HPKE_CTX_new(). If the argument to OSSL_HPKE_CTX_free() is NULL, nothing is done. π«Ά
π€ 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 OSSL_HPKE_encap()) the senderβs public value using the recipientβs public key, (pub) and to internally derive secrets. This produces the encapsulated public value (enc) 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 OSSL_HPKE_seal() to encrypt plaintexts using the secret stored within ctx. π₯
OSSL_HPKE_encap() uses the HPKE context ctx, the recipient public value pub of size publen, and an optional info parameter of size infolen, to produce the encapsulated public value enc. On input enclen should contain the maximum size of the enc buffer, and returns the output size. An error will occur if the input enclen is smaller than the value returned from OSSL_HPKE_get_public_encap_size(). info may be used to bind other protocol or application artefacts such as identifiers. Generally, the encapsulated public value enc corresponds to a single-use ephemeral private value created as part of the encapsulation process. Only a single call to OSSL_HPKE_encap() is allowed for a given OSSL_HPKE_CTX. π
OSSL_HPKE_seal() takes the OSSL_HPKE_CTX context ctx, the plaintext buffer pt of size ptlen and optional additional authenticated data buffer aad of size aadlen, and returns the ciphertext ct of size ctlen. On input ctlen should contain the maximum size of the ct buffer, and returns the output size. An error will occur if the input ctlen is smaller than the value returned from OSSL_HPKE_get_public_encap_size(). π
OSSL_HPKE_encap() must be called before the OSSL_HPKE_seal(). OSSL_HPKE_seal() may be called multiple times, with an internal βnonceβ being incremented by one after each call. π«
π Recipient APIs π
okay so recipients are a whole different vibe from senders, bestie. π
a recipient's private value is typically less ephemeral, and that's on purpose β the whole point is that the public value can get handed out to potential senders through whatever protocol is riding on HPKE. so recipients will generally first generate a key pair and then have to manage their private key value using standard mechanisms outside the scope of this API. and here's the cute part: private keys use normal EVP_PKEY(3) pointers, so the normal private key management mechanisms can be used for the relevant values. slay, no new key-handling lore to learn. π
so to enable encapsulation, the recipient needs to make its public value available to the sender. and like β there is no generic HPKE format defined for that. none. the relevant formatting is intended to be defined by the application/protocols that make use of HPKE. ECH for example defines an ECHConfig data structure that combines the public value with other ECH data items. so normal library functions must be used to extract the public value in the required format, based on the EVP_PKEY(3) for the private value. iykyk. π¦
OSSL_HPKE_keygen()β this is the glow-up where recipients generate a key pair based on the HPKE suite to be used. it returns anEVP_PKEY(3)pointer for the private value priv and an encoded public key pub of size publen. on input, publen should contain the maximum size of the pub buffer, and it returns the output size. an error will occur if the input publen is too small π. the libctx and propq are used when fetching algorithms from providers and may be set toNULL. and because the HPKE specification also defines a deterministic key generation scheme where the private value is derived from initial keying material (IKM),OSSL_HPKE_keygen()also has an option to use that scheme, using the ikm parameter of size ikmlen. if either ikm isNULLor ikmlen is zero, then a randomly generated key for the relevant suite will be produced. if required, ikmlen should be greater than or equal toOSSL_HPKE_get_recommended_ikmelen().OSSL_HPKE_decap()β takes as input the sender's encapsulated public value produced byOSSL_HPKE_encap()(enc) and the recipient'sEVP_PKEY(3)pointer (prov), and then re-generates the internal secret derived by the sender. as before, an optional info parameter allows binding that derived secret to other application/protocol artefacts. β οΈ only a single call toOSSL_HPKE_decap()is allowed for a givenOSSL_HPKE_CTX. one. that's the rule, bestie.OSSL_HPKE_open()β this is the recipient's moment, the main character energy π«. it decrypts the ciphertext ct of size ctlen using the ctx and additional authenticated data aad of size aadlen, to produce the plaintext pt of size ptlen. on input, ptlen should contain the maximum size of the pt buffer, and it returns the output size. a pt buffer that is the same size as the ct buffer will suffice β generally the plaintext output will be a little smaller than the ciphertext input. an error will occur if the input ptlen is too small π.OSSL_HPKE_open()may be called multiple times, but as withOSSL_HPKE_seal()there is an internally incrementing nonce value, so ciphertexts need to be presented in the same order as used by theOSSL_HPKE_seal(). see "Re-sequencing" if you need to process multiple ciphertexts in a different order. π₯
πΈ Exporting Secrets πΈ
HPKE defines a way to produce exported secrets for use by the application. like, a little gift for your protocol. π
OSSL_HPKE_export() takes as input the OSSL_HPKE_CTX, and an application supplied label label of size labellen, to produce a secret secret of size secretlen. the sender must first call OSSL_HPKE_encap(), and the receiver must call OSSL_HPKE_decap() in order to derive the same shared secret. no skipping steps, that's the whole bit. π
multiple calls to OSSL_HPKE_export() with the same inputs will produce the same secret. OSSL_HPKE_AEAD_ID_EXPORTONLY may be used as the OSSL_HPKE_SUITE aead_id that is passed to OSSL_HPKE_CTX_new() if the user needs to produce a shared secret, but does not wish to perform HPKE encryption. iconique β¨
π Sender-authenticated HPKE Modes π
HPKE defines modes that support KEM-based sender-authentication: OSSL_HPKE_MODE_AUTH and OSSL_HPKE_MODE_PSKAUTH. 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 β no mixing, no matching, fr fr. OSSL_HPKE_keygen() can be used to generate the private value required.
OSSL_HPKE_CTX_set1_authpriv()β can be used by the sender to set the sender's private privEVP_PKEYkey into theOSSL_HPKE_CTXctx before callingOSSL_HPKE_encap().OSSL_HPKE_CTX_set1_authpub()β can be used by the receiver to set the sender's encoded pub key pub of size publen into theOSSL_HPKE_CTXctx before callingOSSL_HPKE_decap().
π 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 OSSL_HPKE_MODE_PSK and OSSL_HPKE_MODE_PSKAUTH modes. π«Ά
OSSL_HPKE_CTX_set1_psk() sets the PSK identifier pskid string, and PSK buffer psk of size psklen into the ctx. if required this must be called before OSSL_HPKE_encap() or OSSL_HPKE_decap(). as per RFC9180, if required, both psk and pskid must be set to non-NULL values. and since PSKs are symmetric, the same calls must happen on both sender and receiver sides β matching outfits, always. π
π§ Deterministic key generation for senders π§
normally the sender's ephemeral private key is generated randomly inside OSSL_HPKE_encap() and remains secret. OSSL_HPKE_CTX_set1_ikme() allows the user to override this behaviour by setting a deterministic input key material ikm of size ikmlen into the OSSL_HPKE_CTX ctx. if required, OSSL_HPKE_CTX_set1_ikme() can optionally be called before OSSL_HPKE_encap(). ikmlen should be greater than or equal to OSSL_HPKE_get_recommended_ikmelen().
β οΈ it is generally undesirable to use OSSL_HPKE_CTX_set1_ikme(), since it exposes the relevant secret to the application rather than preserving it within the library, and is more likely to result in use of predictable values or values that leak. likeβ¦ don't do this unless you genuinely have to, bestie. π
π¦ Re-sequencing π¦
some protocols may have to deal with packet loss while still being able to decrypt arriving packets later. relatable, honestly. we provide a way to set the increment used for the nonce to the next subsequent call to OSSL_HPKE_open() (but not to OSSL_HPKE_seal() as explained below). the OSSL_HPKE_CTX_set_seq() API can be used for such purposes, with the seq parameter value resetting the internal nonce increment to be used for the next call.
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 seq increment defaults to zero.)
if a caller needs to determine how many calls to seal or open have been made, the OSSL_HPKE_CTX_get_seq() API can be used to retrieve the increment (in the seq 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 OSSL_HPKE_seal() and 1 after that first call. counting era π
β οΈ 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 seq for decryption (i.e. OSSL_HPKE_open()) operations. this is not a drill, bestie. π
for compatibility with other implementations these seq increments are represented as uint64_t. β¨
π Protocol Convenience Functions π
additional convenience APIs allow the caller to access internal details of local HPKE support and/or algorithms, such as parameter lengths. little quality-of-life servitude. π«Ά
OSSL_HPKE_suite_check()β checks if a specificOSSL_HPKE_SUITEsuite is supported locally. vibe check on your suite πOSSL_HPKE_get_ciphertext_size()β to assist with memory allocation, this gives the caller a way to know by how much ciphertext will be longer than a plaintext of length clearlen. (AEAD algorithms add a data integrity tag, so there is a small amount of ciphertext expansion.) yes, the ciphertext is thicc-er, it's giving tag. π₯OSSL_HPKE_get_public_encap_size()β provides a way for senders to know how big the encapsulated public value will be for a given HPKE suite.OSSL_HPKE_get_recommended_ikmelen()β returns the recommended Input Key Material size (in bytes) for a given suite. this is needed in cases where the same public value needs to be regenerated by a sender before callingOSSL_HPKE_seal(). ikmlen should be at least this size.OSSL_HPKE_get_grease_value()β produces values of the appropriate length for a given suite_in value (or a random value if suite_in isNULL) 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 enc value will have an appropriate length for suite_out and a random value, and the ct output will be a random value. the relevant sizes for buffers can be found usingOSSL_HPKE_get_ciphertext_size()andOSSL_HPKE_get_public_encap_size(). sneak attack but make it cryptographic π§OSSL_HPKE_str2suite()β maps input str strings to anOSSL_HPKE_SUITEobject. the input str 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:
- KEM:
"p-256","p-384","p-521","x25519"and"x448" - KDF:
"hkdf-sha256","hkdf-sha384"and"hkdf-sha512" - AEAD:
"aes-gcm-128","aes-gcm-256","chacha20-poly1305"and"exporter"
string variants of the numbers listed in "OSSL_HPKE_SUITE Identifiers" can also be used. both spellings, we support her. π
β RETURN VALUES β
OSSL_HPKE_CTX_new()returns anOSSL_HPKE_CTXpointer orNULLon error. πOSSL_HPKE_get_ciphertext_size(),OSSL_HPKE_get_public_encap_size(),OSSL_HPKE_get_recommended_ikmelen()all return asize_twith the relevant value or zero on error.- all other functions return
1for success or zero for error. that's it, that's the whole reporting system. π
π§ͺ EXAMPLES β¨
okay so this is the moment you've been waiting for, bestie β a whole entire minimal round-trip using HPKE, like generate a key, encrypt, decrypt, done. it's giving "hello world but make it cryptography" π
#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's 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's 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's 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!\n" : "Error!\n");
OSSL_HPKE_CTX_free(rctx);
OSSL_HPKE_CTX_free(sctx);
EVP_PKEY_free(priv);
return 0;
}
like, that's literally the whole flow? keygen β OSSL_HPKE_encap β OSSL_HPKE_seal on the sender side, then OSSL_HPKE_decap β OSSL_HPKE_open on the receiver side. the receiver hands their public key to the sender, the sender does their thing, the receiver does their thing, and everybody goes home happy π«Ά
also a lil heads up about LBUFSIZE 48 β the comment in the code fr fr says it's "big enough for this example, real code would need different handling", so don't go copy-pasting that number into your production app, bestie, i'm begging π
π WARNINGS π
β οΈ listen to me. this section is not a vibe, it's a warning, and warnings are serious.
- the
OSSL_HPKE_CTX_set_seq()API could be dangerous β if it's used with GCM that could lead to nonce-reuse, which is a known danger. so like... avoid that entirely, or be very very careful when using that API. no cap, nonce-reuse will absolutely wreck your whole day π - using an IKM value for deterministic key generation (via
OSSL_HPKE_CTX_set1_ikme()orOSSL_HPKE_keygen()) creates the potential for leaking keys (or IKM values). only use that if it's really needed and if you understand how keys or IKM values could be abused. like, understand the risk before you press go, please π₯Ί
π SEE ALSO π
- the RFC9180 specification:
https://datatracker.ietf.org/doc/rfc9180/
go read it, it's iconic, it's the whole source of truth π
π¦ HISTORY π¦
the functionality described here was added in OpenSSL 3.2. so if you're on something ancient, that's why it's not working, bestie π
π COPYRIGHT π
Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
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.
and that's a wrap, bestie!! πβ¨ this whole page is from OpenSSL 3.5.0, dated 2026-09-25, and it's the OSSL_HPKE_CTX_NEW(3ossl) man page β go forth and do your round-trips responsibly ππΈπ«Ά
π¦ where this page comes from
- opensuse-leap 16.0: openssl-3-doc 3.5.0-160000.11.1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms