]> git.ipfire.org Git - thirdparty/openssl.git/blob - doc/man3/OSSL_HPKE_CTX_new.pod
Copyright year updates
[thirdparty/openssl.git] / doc / man3 / OSSL_HPKE_CTX_new.pod
1 =pod
2
3 =head1 NAME
4
5 OSSL_HPKE_CTX_new, OSSL_HPKE_CTX_free,
6 OSSL_HPKE_encap, OSSL_HPKE_decap,
7 OSSL_HPKE_seal, OSSL_HPKE_open, OSSL_HPKE_export,
8 OSSL_HPKE_suite_check, OSSL_HPKE_str2suite,
9 OSSL_HPKE_keygen, OSSL_HPKE_get_grease_value,
10 OSSL_HPKE_get_ciphertext_size, OSSL_HPKE_get_public_encap_size,
11 OSSL_HPKE_get_recommended_ikmelen,
12 OSSL_HPKE_CTX_set1_psk, OSSL_HPKE_CTX_set1_ikme,
13 OSSL_HPKE_CTX_set1_authpriv, OSSL_HPKE_CTX_set1_authpub,
14 OSSL_HPKE_CTX_get_seq, OSSL_HPKE_CTX_set_seq
15 - Hybrid Public Key Encryption (HPKE) functions
16
17 =head1 SYNOPSIS
18
19 #include <openssl/hpke.h>
20
21 typedef struct {
22 uint16_t kem_id;
23 uint16_t kdf_id;
24 uint16_t aead_id;
25 } OSSL_HPKE_SUITE;
26
27 OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role,
28 OSSL_LIB_CTX *libctx, const char *propq);
29 void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx);
30
31 int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx,
32 unsigned char *enc, size_t *enclen,
33 const unsigned char *pub, size_t publen,
34 const unsigned char *info, size_t infolen);
35 int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx,
36 unsigned char *ct, size_t *ctlen,
37 const unsigned char *aad, size_t aadlen,
38 const unsigned char *pt, size_t ptlen);
39
40 int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite,
41 unsigned char *pub, size_t *publen, EVP_PKEY **priv,
42 const unsigned char *ikm, size_t ikmlen,
43 OSSL_LIB_CTX *libctx, const char *propq);
44 int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx,
45 const unsigned char *enc, size_t enclen,
46 EVP_PKEY *recippriv,
47 const unsigned char *info, size_t infolen);
48 int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx,
49 unsigned char *pt, size_t *ptlen,
50 const unsigned char *aad, size_t aadlen,
51 const unsigned char *ct, size_t ctlen);
52
53 int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx,
54 unsigned char *secret, size_t secretlen,
55 const unsigned char *label, size_t labellen);
56
57 int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv);
58 int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx,
59 unsigned char *pub, size_t publen);
60 int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx,
61 const char *pskid,
62 const unsigned char *psk, size_t psklen);
63
64 int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq);
65 int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq);
66
67 int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx,
68 const unsigned char *ikme, size_t ikmelen);
69
70 int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite);
71 int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in,
72 OSSL_HPKE_SUITE *suite,
73 unsigned char *enc, size_t *enclen,
74 unsigned char *ct, size_t ctlen,
75 OSSL_LIB_CTX *libctx, const char *propq);
76
77 int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite);
78 size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen);
79 size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite);
80 size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite);
81
82 =head1 DESCRIPTION
83
84 These functions provide an API for using the form of Hybrid Public Key
85 Encryption (HPKE) defined in RFC9180. Understanding the HPKE specification
86 is likely required before using these APIs. HPKE is used by various
87 other IETF specifications, including the TLS Encrypted Client
88 Hello (ECH) specification and others.
89
90 HPKE is a standardised, highly flexible construct for encrypting "to" a public
91 key that supports combinations of a key encapsulation method (KEM), a key
92 derivation function (KDF) and an authenticated encryption with additional data
93 (AEAD) algorithm, with optional sender authentication.
94
95 The sender and a receiver here will generally be using some application or
96 protocol making use of HPKE. For example, with ECH,
97 the sender will be a browser and the receiver will be a web server.
98
99 =head2 Data Structures
100
101 B<OSSL_HPKE_SUITE> is a structure that holds identifiers for the algorithms
102 used for KEM, KDF and AEAD operations.
103
104 B<OSSL_HPKE_CTX> is a context that maintains internal state as HPKE
105 operations are carried out. Separate B<OSSL_HPKE_CTX> objects must be used for
106 the sender and receiver. Attempting to use a single context for both will
107 result in errors.
108
109 =head2 OSSL_HPKE_SUITE Identifiers
110
111 The identifiers used by B<OSSL_HPKE_SUITE> are:
112
113 The KEM identifier I<kem_id> is one of the following:
114
115 =over 4
116
117 =item 0x10 B<OSSL_HPKE_KEM_ID_P256>
118
119 =item 0x11 B<OSSL_HPKE_KEM_ID_P384>
120
121 =item 0x12 B<OSSL_HPKE_KEM_ID_P521>
122
123 =item 0x20 B<OSSL_HPKE_KEM_ID_X25519>
124
125 =item 0x21 B<OSSL_HPKE_KEM_ID_X448>
126
127 =back
128
129 The KDF identifier I<kdf_id> is one of the following:
130
131 =over 4
132
133 =item 0x01 B<OSSL_HPKE_KDF_ID_HKDF_SHA256>
134
135 =item 0x02 B<OSSL_HPKE_KDF_ID_HKDF_SHA384>
136
137 =item 0x03 B<OSSL_HPKE_KDF_ID_HKDF_SHA512>
138
139 =back
140
141 The AEAD identifier I<aead_id> is one of the following:
142
143 =over 4
144
145 =item 0x01 B<OSSL_HPKE_AEAD_ID_AES_GCM_128>
146
147 =item 0x02 B<OSSL_HPKE_AEAD_ID_AES_GCM_256>
148
149 =item 0x03 B<OSSL_HPKE_AEAD_ID_CHACHA_POLY1305>
150
151 =item 0xFFFF B<OSSL_HPKE_AEAD_ID_EXPORTONLY>
152
153 The last identifier above indicates that AEAD operations are not needed.
154 OSSL_HPKE_export() can be used, but OSSL_HPKE_open() and OSSL_HPKE_seal() will
155 return an error if called with a context using that AEAD identifier.
156
157 =back
158
159 =head2 HPKE Modes
160
161 HPKE supports the following variants of Authentication using a mode Identifier:
162
163 =over 4
164
165 =item B<OSSL_HPKE_MODE_BASE>, 0x00
166
167 Authentication is not used.
168
169 =item B<OSSL_HPKE_MODE_PSK>, 0x01
170
171 Authenticates possession of a pre-shared key (PSK).
172
173 =item B<OSSL_HPKE_MODE_AUTH>, 0x02
174
175 Authenticates possession of a KEM-based sender private key.
176
177 =item B<OSSL_HPKE_MODE_PSKAUTH>, 0x03
178
179 A combination of B<OSSL_HPKE_MODE_PSK> and B<OSSL_HPKE_MODE_AUTH>.
180 Both the PSK and the senders authentication public/private must be
181 supplied before the encapsulation/decapsulation operation will work.
182
183 =back
184
185 For further information related to authentication see L</Pre-Shared Key HPKE
186 modes> and L</Sender-authenticated HPKE Modes>.
187
188 =head2 HPKE Roles
189
190 HPKE contexts have a role - either sender or receiver. This is used
191 to control which functions can be called and so that senders do not
192 reuse a key and nonce with different plaintexts.
193
194 OSSL_HPKE_CTX_free(), OSSL_HPKE_export(), OSSL_HPKE_CTX_set1_psk(),
195 and OSSL_HPKE_CTX_get_seq() can be called regardless of role.
196
197 =over 4
198
199 =item B<OSSL_HPKE_ROLE_SENDER>, 0
200
201 An I<OSSL_HPKE_CTX> with this role can be used with
202 OSSL_HPKE_encap(), OSSL_HPKE_seal(), OSSL_HPKE_CTX_set1_ikme() and
203 OSSL_HPKE_CTX_set1_authpriv().
204
205 =item B<OSSL_HPKE_ROLE_RECEIVER>, 1
206
207 An I<OSSL_HPKE_CTX> with this role can be used with OSSL_HPKE_decap(),
208 OSSL_HPKE_open(), OSSL_HPKE_CTX_set1_authpub() and OSSL_HPKE_CTX_set_seq().
209
210 =back
211
212 Calling a function with an incorrect role set on I<OSSL_HPKE_CTX> will result
213 in an error.
214
215 =head2 Parameter Size Limits
216
217 In order to improve interoperability, RFC9180, section 7.2.1 suggests a
218 RECOMMENDED maximum size of 64 octets for various input parameters. In this
219 implementation we apply a limit of 66 octets for the I<ikmlen>, I<psklen>, and
220 I<labellen> parameters, and for the length of the string I<pskid> for HPKE
221 functions below. The constant I<OSSL_HPKE_MAX_PARMLEN> is defined as the limit
222 of this value. (We chose 66 octets so that we can validate all the test
223 vectors present in RFC9180, Appendix A.)
224
225 While RFC9180 also RECOMMENDS a 64 octet limit for the I<infolen> parameter,
226 that is not sufficient for TLS Encrypted ClientHello (ECH) processing, so we
227 enforce a limit of I<OSSL_HPKE_MAX_INFOLEN> with a value of 1024 as the limit
228 for the I<infolen> parameter.
229
230 =head2 Context Construct/Free
231
232 OSSL_HPKE_CTX_new() creates a B<OSSL_HPKE_CTX> context object used for
233 subsequent HPKE operations, given a I<mode> (See L</HPKE Modes>), I<suite> (see
234 L</OSSL_HPKE_SUITE Identifiers>) and a I<role> (see L</HPKE Roles>). The
235 I<libctx> and I<propq> are used when fetching algorithms from providers and may
236 be set to NULL.
237
238 OSSL_HPKE_CTX_free() frees the I<ctx> B<OSSL_HPKE_CTX> that was created
239 previously by a call to OSSL_HPKE_CTX_new().
240
241 =head2 Sender APIs
242
243 A sender's goal is to use HPKE to encrypt using a public key, via use of a
244 KEM, then a KDF and finally an AEAD. The first step is to encapsulate (using
245 OSSL_HPKE_encap()) the sender's public value using the recipient's public key,
246 (I<pub>) and to internally derive secrets. This produces the encapsulated public value
247 (I<enc>) to be sent to the recipient in whatever protocol is using HPKE. Having done the
248 encapsulation step, the sender can then make one or more calls to
249 OSSL_HPKE_seal() to encrypt plaintexts using the secret stored within I<ctx>.
250
251 OSSL_HPKE_encap() uses the HPKE context I<ctx>, the recipient public value
252 I<pub> of size I<publen>, and an optional I<info> parameter of size I<infolen>,
253 to produce the encapsulated public value I<enc>.
254 On input I<enclen> should contain the maximum size of the I<enc> buffer, and returns
255 the output size. An error will occur if the input I<enclen> is
256 smaller than the value returned from OSSL_HPKE_get_public_encap_size().
257 I<info> may be used to bind other protocol or application artefacts such as identifiers.
258 Generally, the encapsulated public value I<enc> corresponds to a
259 single-use ephemeral private value created as part of the encapsulation
260 process. Only a single call to OSSL_HPKE_encap() is allowed for a given
261 B<OSSL_HPKE_CTX>.
262
263 OSSL_HPKE_seal() takes the B<OSSL_HPKE_CTX> context I<ctx>, the plaintext
264 buffer I<pt> of size I<ptlen> and optional additional authenticated data buffer
265 I<aad> of size I<aadlen>, and returns the ciphertext I<ct> of size I<ctlen>.
266 On input I<ctlen> should contain the maximum size of the I<ct> buffer, and returns
267 the output size. An error will occur if the input I<ctlen> is
268 smaller than the value returned from OSSL_HPKE_get_public_encap_size().
269
270 OSSL_HPKE_encap() must be called before the OSSL_HPKE_seal(). OSSL_HPKE_seal()
271 may be called multiple times, with an internal "nonce" being incremented by one
272 after each call.
273
274 =head2 Recipient APIs
275
276 Recipients using HPKE require a typically less ephemeral private value so that
277 the public value can be distributed to potential senders via whatever protocol
278 is using HPKE. For this reason, recipients will generally first generate a key
279 pair and will need to manage their private key value using standard mechanisms
280 outside the scope of this API. Private keys use normal L<EVP_PKEY(3)> pointers
281 so normal private key management mechanisms can be used for the relevant
282 values.
283
284 In order to enable encapsulation, the recipient needs to make it's public value
285 available to the sender. There is no generic HPKE format defined for that - the
286 relevant formatting is intended to be defined by the application/protocols that
287 makes use of HPKE. ECH for example defines an ECHConfig data structure that
288 combines the public value with other ECH data items. Normal library functions
289 must therefore be used to extract the public value in the required format based
290 on the L<EVP_PKEY(3)> for the private value.
291
292 OSSL_HPKE_keygen() provides a way for recipients to generate a key pair based
293 on the HPKE I<suite> to be used. It returns a L<EVP_PKEY(3)> pointer
294 for the private value I<priv> and a encoded public key I<pub> of size I<publen>.
295 On input I<publen> should contain the maximum size of the I<pub> buffer, and
296 returns the output size. An error will occur if the input I<publen> is too small.
297 The I<libctx> and I<propq> are used when fetching algorithms from providers
298 and may be set to NULL.
299 The HPKE specification also defines a deterministic key generation scheme where
300 the private value is derived from initial keying material (IKM), so
301 OSSL_HPKE_keygen() also has an option to use that scheme, using the I<ikm>
302 parameter of size I<ikmlen>. If either I<ikm> is NULL or I<ikmlen> is zero,
303 then a randomly generated key for the relevant I<suite> will be produced.
304 If required I<ikmlen> should be greater than or equal to
305 OSSL_HPKE_get_recommended_ikmelen().
306
307 OSSL_HPKE_decap() takes as input the sender's encapsulated public value
308 produced by OSSL_HPKE_encap() (I<enc>) and the recipient's L<EVP_PKEY(3)>
309 pointer (I<prov>), and then re-generates the internal secret derived by the
310 sender. As before, an optional I<info> parameter allows binding that derived
311 secret to other application/protocol artefacts. Only a single call to
312 OSSL_HPKE_decap() is allowed for a given B<OSSL_HPKE_CTX>.
313
314 OSSL_HPKE_open() is used by the recipient to decrypt the ciphertext I<ct> of
315 size I<ctlen> using the I<ctx> and additional authenticated data I<aad> of
316 size I<aadlen>, to produce the plaintext I<pt> of size I<ptlen>.
317 On input I<ptlen> should contain the maximum size of the I<pt> buffer, and
318 returns the output size. A I<pt> buffer that is the same size as the
319 I<ct> buffer will suffice - generally the plaintext output will be
320 a little smaller than the ciphertext input.
321 An error will occur if the input I<ptlen> is too small.
322 OSSL_HPKE_open() may be called multiple times, but as with OSSL_HPKE_seal()
323 there is an internally incrementing nonce value so ciphertexts need to be
324 presented in the same order as used by the OSSL_HPKE_seal().
325 See L</Re-sequencing> if you need to process multiple ciphertexts in a
326 different order.
327
328 =head2 Exporting Secrets
329
330 HPKE defines a way to produce exported secrets for use by the
331 application.
332
333 OSSL_HPKE_export() takes as input the B<OSSL_HPKE_CTX>, and an application
334 supplied label I<label> of size I<labellen>, to produce a secret I<secret>
335 of size I<secretlen>. The sender must first call OSSL_HPKE_encap(), and the
336 receiver must call OSSL_HPKE_decap() in order to derive the same shared secret.
337
338 Multiple calls to OSSL_HPKE_export() with the same inputs will produce the
339 same secret.
340 I<OSSL_HPKE_AEAD_ID_EXPORTONLY> may be used as the B<OSSL_HPKE_SUITE> I<aead_id>
341 that is passed to OSSL_HPKE_CTX_new() if the user needs to produce a shared
342 secret, but does not wish to perform HPKE encryption.
343
344 =head2 Sender-authenticated HPKE Modes
345
346 HPKE defines modes that support KEM-based sender-authentication
347 B<OSSL_HPKE_MODE_AUTH> and B<OSSL_HPKE_MODE_PSKAUTH>. This works by binding
348 the sender's authentication private/public values into the encapsulation and
349 decapsulation operations. The key used for such modes must also use the same
350 KEM as used for the overall exchange. OSSL_HPKE_keygen() can be used to
351 generate the private value required.
352
353 OSSL_HPKE_CTX_set1_authpriv() can be used by the sender to set the senders
354 private I<priv> B<EVP_PKEY> key into the B<OSSL_HPKE_CTX> I<ctx> before calling
355 OSSL_HPKE_encap().
356
357 OSSL_HPKE_CTX_set1_authpub() can be used by the receiver to set the senders
358 encoded pub key I<pub> of size I<publen> into the B<OSSL_HPKE_CTX> I<ctx> before
359 calling OSSL_HPKE_decap().
360
361 =head2 Pre-Shared Key HPKE modes
362
363 HPKE also defines a symmetric equivalent to the authentication described above
364 using a pre-shared key (PSK) and a PSK identifier. PSKs can be used with the
365 B<OSSL_HPKE_MODE_PSK> and B<OSSL_HPKE_MODE_PSKAUTH> modes.
366
367 OSSL_HPKE_CTX_set1_psk() sets the PSK identifier I<pskid> string, and PSK buffer
368 I<psk> of size I<psklen> into the I<ctx>. If required this must be called
369 before OSSL_HPKE_encap() or OSSL_HPKE_decap().
370 As per RFC9180, if required, both I<psk> and I<pskid> must be set to non-NULL values.
371 As PSKs are symmetric the same calls must happen on both sender and receiver
372 sides.
373
374 =head2 Deterministic key generation for senders
375
376 Normally the senders ephemeral private key is generated randomly inside
377 OSSL_HPKE_encap() and remains secret.
378 OSSL_HPKE_CTX_set1_ikme() allows the user to override this behaviour by
379 setting a deterministic input key material I<ikm> of size I<ikmlen> into
380 the B<OSSL_HPKE_CTX> I<ctx>.
381 If required OSSL_HPKE_CTX_set1_ikme() can optionally be called before
382 OSSL_HPKE_encap().
383 I<ikmlen> should be greater than or equal to OSSL_HPKE_get_recommended_ikmelen().
384
385 It is generally undesirable to use OSSL_HPKE_CTX_set1_ikme(), since it
386 exposes the relevant secret to the application rather then preserving it
387 within the library, and is more likely to result in use of predictable values
388 or values that leak.
389
390 =head2 Re-sequencing
391
392 Some protocols may have to deal with packet loss while still being able to
393 decrypt arriving packets later. We provide a way to set the increment used for
394 the nonce to the next subsequent call to OSSL_HPKE_open() (but not to
395 OSSL_HPKE_seal() as explained below). The OSSL_HPKE_CTX_set_seq() API can be
396 used for such purposes with the I<seq> parameter value resetting the internal
397 nonce increment to be used for the next call.
398
399 A baseline nonce value is established based on the encapsulation or
400 decapsulation operation and is then incremented by 1 for each call to seal or
401 open. (In other words, the first I<seq> increment defaults to zero.)
402
403 If a caller needs to determine how many calls to seal or open have been made
404 the OSSL_HPKE_CTX_get_seq() API can be used to retrieve the increment (in the
405 I<seq> output) that will be used in the next call to seal or open. That would
406 return 0 before the first call a sender made to OSSL_HPKE_seal() and 1 after
407 that first call.
408
409 Note that reuse of the same nonce and key with different plaintexts would
410 be very dangerous and could lead to loss of confidentiality and integrity.
411 We therefore only support application control over I<seq> for decryption
412 (i.e. OSSL_HPKE_open()) operations.
413
414 For compatibility with other implementations these I<seq> increments are
415 represented as I<uint64_t>.
416
417 =head2 Protocol Convenience Functions
418
419 Additional convenience APIs allow the caller to access internal details of
420 local HPKE support and/or algorithms, such as parameter lengths.
421
422 OSSL_HPKE_suite_check() checks if a specific B<OSSL_HPKE_SUITE> I<suite>
423 is supported locally.
424
425 To assist with memory allocation, OSSL_HPKE_get_ciphertext_size() provides a
426 way for the caller to know by how much ciphertext will be longer than a
427 plaintext of length I<clearlen>. (AEAD algorithms add a data integrity tag,
428 so there is a small amount of ciphertext expansion.)
429
430 OSSL_HPKE_get_public_encap_size() provides a way for senders to know how big
431 the encapsulated public value will be for a given HPKE I<suite>.
432
433 OSSL_HPKE_get_recommended_ikmelen() returns the recommended Input Key Material
434 size (in bytes) for a given I<suite>. This is needed in cases where the same
435 public value needs to be regenerated by a sender before calling OSSL_HPKE_seal().
436 I<ikmlen> should be at least this size.
437
438 OSSL_HPKE_get_grease_value() produces values of the appropriate length for a
439 given I<suite_in> value (or a random value if I<suite_in> is NULL) so that a
440 protocol using HPKE can send so-called GREASE (see RFC8701) values that are
441 harder to distinguish from a real use of HPKE. The buffer sizes should
442 be supplied on input. The output I<enc> value will have an appropriate
443 length for I<suite_out> and a random value, and the I<ct> output will be
444 a random value. The relevant sizes for buffers can be found using
445 OSSL_HPKE_get_ciphertext_size() and OSSL_HPKE_get_public_encap_size().
446
447 OSSL_HPKE_str2suite() maps input I<str> strings to an B<OSSL_HPKE_SUITE> object.
448 The input I<str> should be a comma-separated string with a KEM,
449 KDF and AEAD name in that order, for example "x25519,hkdf-sha256,aes128gcm".
450 This can be used by command line tools that accept string form names for HPKE
451 codepoints. Valid (case-insensitive) names are:
452 "p256", "p384", "p521", "x25519" and "x448" for KEM,
453 "hkdf-SHA256", "hkdf-SHA384" and "hkdf-SHA512" for KDF, and
454 "aes-gcm-128", "aes-gcm-256" and "chacha20-poly1305" for AEAD.
455 String variants of the numbers listed in L</OSSL_HPKE_SUITE Identifiers>
456 can also be used.
457
458 =head1 RETURN VALUES
459
460 OSSL_HPKE_CTX_new() returns an OSSL_HPKE_CTX pointer or NULL on error.
461
462 OSSL_HPKE_get_ciphertext_size(), OSSL_HPKE_get_public_encap_size(),
463 OSSL_HPKE_get_recommended_ikmelen() all return a size_t with the
464 relevant value or zero on error.
465
466 All other functions return 1 for success or zero for error.
467
468 =head1 EXAMPLES
469
470 This example demonstrates a minimal round-trip using HPKE.
471
472 #include <stddef.h>
473 #include <string.h>
474 #include <openssl/hpke.h>
475 #include <openssl/evp.h>
476
477 /*
478 * this is big enough for this example, real code would need different
479 * handling
480 */
481 #define LBUFSIZE 48
482
483 /* Do a round-trip, generating a key, encrypting and decrypting */
484 int main(int argc, char **argv)
485 {
486 int ok = 0;
487 int hpke_mode = OSSL_HPKE_MODE_BASE;
488 OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT;
489 OSSL_HPKE_CTX *sctx = NULL, *rctx = NULL;
490 EVP_PKEY *priv = NULL;
491 unsigned char pub[LBUFSIZE];
492 size_t publen = sizeof(pub);
493 unsigned char enc[LBUFSIZE];
494 size_t enclen = sizeof(enc);
495 unsigned char ct[LBUFSIZE];
496 size_t ctlen = sizeof(ct);
497 unsigned char clear[LBUFSIZE];
498 size_t clearlen = sizeof(clear);
499 const unsigned char *pt = "a message not in a bottle";
500 size_t ptlen = strlen((char *)pt);
501 const unsigned char *info = "Some info";
502 size_t infolen = strlen((char *)info);
503 unsigned char aad[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
504 size_t aadlen = sizeof(aad);
505
506 /*
507 * Generate receiver's key pair.
508 * The receiver gives this public key to the sender.
509 */
510 if (OSSL_HPKE_keygen(hpke_suite, pub, &publen, &priv,
511 NULL, 0, NULL, NULL) != 1)
512 goto err;
513
514 /* sender's actions - encrypt data using the receivers public key */
515 if ((sctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite,
516 OSSL_HPKE_ROLE_SENDER,
517 NULL, NULL)) == NULL)
518 goto err;
519 if (OSSL_HPKE_encap(sctx, enc, &enclen, pub, publen, info, infolen) != 1)
520 goto err;
521 if (OSSL_HPKE_seal(sctx, ct, &ctlen, aad, aadlen, pt, ptlen) != 1)
522 goto err;
523
524 /* receiver's actions - decrypt data using the receivers private key */
525 if ((rctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite,
526 OSSL_HPKE_ROLE_RECEIVER,
527 NULL, NULL)) == NULL)
528 goto err;
529 if (OSSL_HPKE_decap(rctx, enc, enclen, priv, info, infolen) != 1)
530 goto err;
531 if (OSSL_HPKE_open(rctx, clear, &clearlen, aad, aadlen, ct, ctlen) != 1)
532 goto err;
533 ok = 1;
534 err:
535 /* clean up */
536 printf(ok ? "All Good!\n" : "Error!\n");
537 OSSL_HPKE_CTX_free(rctx);
538 OSSL_HPKE_CTX_free(sctx);
539 EVP_PKEY_free(priv);
540 return 0;
541 }
542
543 =head1 WARNINGS
544
545 Note that the OSSL_HPKE_CTX_set_seq() API could be dangerous - if used with GCM
546 that could lead to nonce-reuse, which is a known danger. So avoid that
547 entirely, or be very very careful when using that API.
548
549 Use of an IKM value for deterministic key generation (via
550 OSSL_HPKE_CTX_set1_ikme() or OSSL_HPKE_keygen()) creates the potential for
551 leaking keys (or IKM values). Only use that if really needed and if you
552 understand how keys or IKM values could be abused.
553
554 =head1 SEE ALSO
555
556 The RFC9180 specification: https://datatracker.ietf.org/doc/rfc9180/
557
558 =head1 HISTORY
559
560 This functionality described here was added in OpenSSL 3.2.
561
562 =head1 COPYRIGHT
563
564 Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
565
566 Licensed under the Apache License 2.0 (the "License"). You may not use
567 this file except in compliance with the License. You can obtain a copy
568 in the file LICENSE in the source distribution or at
569 L<https://www.openssl.org/source/license.html>.
570
571 =cut