xref: /openssl/test/dhkem_test.inc (revision da1c088f)
1/*
2 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10typedef struct {
11    const char *curvename;
12    /* seed */
13    const unsigned char *ikm;
14    size_t ikmlen;
15    /* expected public key */
16    const unsigned char *pub;
17    size_t publen;
18    /* expected private key */
19    const unsigned char *priv;
20    size_t privlen;
21} TEST_DERIVEKEY_DATA;
22
23typedef struct {
24    const char *curve;
25    /* The seed for the senders ephemeral key */
26    const unsigned char *ikmE;
27    size_t ikmElen;
28    /* Recipient key */
29    const unsigned char *rpub;
30    size_t rpublen;
31    const unsigned char *rpriv;
32    size_t rprivlen;
33    /* The senders generated ephemeral public key */
34    const unsigned char *expected_enc;
35    size_t expected_enclen;
36    /* The generated shared secret */
37    const unsigned char *expected_secret;
38    size_t expected_secretlen;
39    /* Senders Auth key */
40    const unsigned char *spub;
41    size_t spublen;
42    const unsigned char *spriv;
43    size_t sprivlen;
44} TEST_ENCAPDATA;
45
46static const char *dhkem_supported_curves[] = {
47    "P-256",
48    "P-384",
49    "P-521",
50#ifndef OPENSSL_NO_ECX
51    "X25519",
52    "X448",
53#endif
54};
55
56/* TEST vectors extracted from RFC 9180 */
57
58/* Base test values */
59#ifndef OPENSSL_NO_ECX
60static const unsigned char x25519_ikme[] = {
61    0x72, 0x68, 0x60, 0x0d, 0x40, 0x3f, 0xce, 0x43,
62    0x15, 0x61, 0xae, 0xf5, 0x83, 0xee, 0x16, 0x13,
63    0x52, 0x7c, 0xff, 0x65, 0x5c, 0x13, 0x43, 0xf2,
64    0x98, 0x12, 0xe6, 0x67, 0x06, 0xdf, 0x32, 0x34
65};
66static const unsigned char x25519_ikme_priv[] = {
67    0x52, 0xc4, 0xa7, 0x58, 0xa8, 0x02, 0xcd, 0x8b,
68    0x93, 0x6e, 0xce, 0xea, 0x31, 0x44, 0x32, 0x79,
69    0x8d, 0x5b, 0xaf, 0x2d, 0x7e, 0x92, 0x35, 0xdc,
70    0x08, 0x4a, 0xb1, 0xb9, 0xcf, 0xa2, 0xf7, 0x36
71};
72static const unsigned char x25519_ikme_pub[] = {
73    0x37, 0xfd, 0xa3, 0x56, 0x7b, 0xdb, 0xd6, 0x28,
74    0xe8, 0x86, 0x68, 0xc3, 0xc8, 0xd7, 0xe9, 0x7d,
75    0x1d, 0x12, 0x53, 0xb6, 0xd4, 0xea, 0x6d, 0x44,
76    0xc1, 0x50, 0xf7, 0x41, 0xf1, 0xbf, 0x44, 0x31
77};
78static const unsigned char x25519_rpub[] = {
79    0x39, 0x48, 0xcf, 0xe0, 0xad, 0x1d, 0xdb, 0x69,
80    0x5d, 0x78, 0x0e, 0x59, 0x07, 0x71, 0x95, 0xda,
81    0x6c, 0x56, 0x50, 0x6b, 0x02, 0x73, 0x29, 0x79,
82    0x4a, 0xb0, 0x2b, 0xca, 0x80, 0x81, 0x5c, 0x4d
83};
84static const unsigned char x25519_rpriv[] = {
85    0x46, 0x12, 0xc5, 0x50, 0x26, 0x3f, 0xc8, 0xad,
86    0x58, 0x37, 0x5d, 0xf3, 0xf5, 0x57, 0xaa, 0xc5,
87    0x31, 0xd2, 0x68, 0x50, 0x90, 0x3e, 0x55, 0xa9,
88    0xf2, 0x3f, 0x21, 0xd8, 0x53, 0x4e, 0x8a, 0xc8
89};
90static const unsigned char x25519_expected_enc[] = {
91    0x37, 0xfd, 0xa3, 0x56, 0x7b, 0xdb, 0xd6, 0x28,
92    0xe8, 0x86, 0x68, 0xc3, 0xc8, 0xd7, 0xe9, 0x7d,
93    0x1d, 0x12, 0x53, 0xb6, 0xd4, 0xea, 0x6d, 0x44,
94    0xc1, 0x50, 0xf7, 0x41, 0xf1, 0xbf, 0x44, 0x31
95};
96static const unsigned char x25519_expected_secret[] = {
97    0xfe, 0x0e, 0x18, 0xc9, 0xf0, 0x24, 0xce, 0x43,
98    0x79, 0x9a, 0xe3, 0x93, 0xc7, 0xe8, 0xfe, 0x8f,
99    0xce, 0x9d, 0x21, 0x88, 0x75, 0xe8, 0x22, 0x7b,
100    0x01, 0x87, 0xc0, 0x4e, 0x7d, 0x2e, 0xa1, 0xfc
101};
102
103static const unsigned char x25519_auth_ikme[] = {
104    0x6e, 0x6d, 0x8f, 0x20, 0x0e, 0xa2, 0xfb, 0x20,
105    0xc3, 0x0b, 0x00, 0x3a, 0x8b, 0x4f, 0x43, 0x3d,
106    0x2f, 0x4e, 0xd4, 0xc2, 0x65, 0x8d, 0x5b, 0xc8,
107    0xce, 0x2f, 0xef, 0x71, 0x80, 0x59, 0xc9, 0xf7
108};
109static const unsigned char x25519_auth_rpub[] = {
110    0x16, 0x32, 0xd5, 0xc2, 0xf7, 0x1c, 0x2b, 0x38,
111    0xd0, 0xa8, 0xfc, 0xc3, 0x59, 0x35, 0x52, 0x00,
112    0xca, 0xa8, 0xb1, 0xff, 0xdf, 0x28, 0x61, 0x80,
113    0x80, 0x46, 0x6c, 0x90, 0x9c, 0xb6, 0x9b, 0x2e
114};
115static const unsigned char x25519_auth_rpriv[] = {
116    0xfd, 0xea, 0x67, 0xcf, 0x83, 0x1f, 0x1c, 0xa9,
117    0x8d, 0x8e, 0x27, 0xb1, 0xf6, 0xab, 0xeb, 0x5b,
118    0x77, 0x45, 0xe9, 0xd3, 0x53, 0x48, 0xb8, 0x0f,
119    0xa4, 0x07, 0xff, 0x69, 0x58, 0xf9, 0x13, 0x7e
120};
121static const unsigned char x25519_auth_spub[] = {
122    0x8b, 0x0c, 0x70, 0x87, 0x3d, 0xc5, 0xae, 0xcb,
123    0x7f, 0x9e, 0xe4, 0xe6, 0x24, 0x06, 0xa3, 0x97,
124    0xb3, 0x50, 0xe5, 0x70, 0x12, 0xbe, 0x45, 0xcf,
125    0x53, 0xb7, 0x10, 0x5a, 0xe7, 0x31, 0x79, 0x0b
126};
127static const unsigned char x25519_auth_spriv[] = {
128    0xdc, 0x4a, 0x14, 0x63, 0x13, 0xcc, 0xe6, 0x0a,
129    0x27, 0x8a, 0x53, 0x23, 0xd3, 0x21, 0xf0, 0x51,
130    0xc5, 0x70, 0x7e, 0x9c, 0x45, 0xba, 0x21, 0xa3,
131    0x47, 0x9f, 0xec, 0xdf, 0x76, 0xfc, 0x69, 0xdd
132};
133static const unsigned char x25519_auth_expected_enc[] = {
134    0x23, 0xfb, 0x95, 0x25, 0x71, 0xa1, 0x4a, 0x25,
135    0xe3, 0xd6, 0x78, 0x14, 0x0c, 0xd0, 0xe5, 0xeb,
136    0x47, 0xa0, 0x96, 0x1b, 0xb1, 0x8a, 0xfc, 0xf8,
137    0x58, 0x96, 0xe5, 0x45, 0x3c, 0x31, 0x2e, 0x76
138};
139static const unsigned char x25519_auth_expected_secret[] = {
140    0x2d, 0x6d, 0xb4, 0xcf, 0x71, 0x9d, 0xc7, 0x29,
141    0x3f, 0xcb, 0xf3, 0xfa, 0x64, 0x69, 0x07, 0x08,
142    0xe4, 0x4e, 0x2b, 0xeb, 0xc8, 0x1f, 0x84, 0x60,
143    0x86, 0x77, 0x95, 0x8c, 0x0d, 0x44, 0x48, 0xa7
144};
145#endif
146
147static const unsigned char p256_ikme[] = {
148    0x42, 0x70, 0xe5, 0x4f, 0xfd, 0x08, 0xd7, 0x9d,
149    0x59, 0x28, 0x02, 0x0a, 0xf4, 0x68, 0x6d, 0x8f,
150    0x6b, 0x7d, 0x35, 0xdb, 0xe4, 0x70, 0x26, 0x5f,
151    0x1f, 0x5a, 0xa2, 0x28, 0x16, 0xce, 0x86, 0x0e
152};
153
154static const unsigned char p256_ikme_pub[] = {
155    0x04, 0xa9, 0x27, 0x19, 0xc6, 0x19, 0x5d, 0x50,
156    0x85, 0x10, 0x4f, 0x46, 0x9a, 0x8b, 0x98, 0x14,
157    0xd5, 0x83, 0x8f, 0xf7, 0x2b, 0x60, 0x50, 0x1e,
158    0x2c, 0x44, 0x66, 0xe5, 0xe6, 0x7b, 0x32, 0x5a,
159    0xc9, 0x85, 0x36, 0xd7, 0xb6, 0x1a, 0x1a, 0xf4,
160    0xb7, 0x8e, 0x5b, 0x7f, 0x95, 0x1c, 0x09, 0x00,
161    0xbe, 0x86, 0x3c, 0x40, 0x3c, 0xe6, 0x5c, 0x9b,
162    0xfc, 0xb9, 0x38, 0x26, 0x57, 0x22, 0x2d, 0x18,
163    0xc4
164};
165static const unsigned char p256_ikme_priv[] = {
166    0x49, 0x95, 0x78, 0x8e, 0xf4, 0xb9, 0xd6, 0x13,
167    0x2b, 0x24, 0x9c, 0xe5, 0x9a, 0x77, 0x28, 0x14,
168    0x93, 0xeb, 0x39, 0xaf, 0x37, 0x3d, 0x23, 0x6a,
169    0x1f, 0xe4, 0x15, 0xcb, 0x0c, 0x2d, 0x7b, 0xeb
170};
171
172static const unsigned char p256_ikmr[] = {
173    0x66, 0x8b, 0x37, 0x17, 0x1f, 0x10, 0x72, 0xf3,
174    0xcf, 0x12, 0xea, 0x8a, 0x23, 0x6a, 0x45, 0xdf,
175    0x23, 0xfc, 0x13, 0xb8, 0x2a, 0xf3, 0x60, 0x9a,
176    0xd1, 0xe3, 0x54, 0xf6, 0xef, 0x81, 0x75, 0x50
177};
178
179static const unsigned char p256_ikmr_pub[] = {
180    0x04, 0xfe, 0x8c, 0x19, 0xce, 0x09, 0x05, 0x19,
181    0x1e, 0xbc, 0x29, 0x8a, 0x92, 0x45, 0x79, 0x25,
182    0x31, 0xf2, 0x6f, 0x0c, 0xec, 0xe2, 0x46, 0x06,
183    0x39, 0xe8, 0xbc, 0x39, 0xcb, 0x7f, 0x70, 0x6a,
184    0x82, 0x6a, 0x77, 0x9b, 0x4c, 0xf9, 0x69, 0xb8,
185    0xa0, 0xe5, 0x39, 0xc7, 0xf6, 0x2f, 0xb3, 0xd3,
186    0x0a, 0xd6, 0xaa, 0x8f, 0x80, 0xe3, 0x0f, 0x1d,
187    0x12, 0x8a, 0xaf, 0xd6, 0x8a, 0x2c, 0xe7, 0x2e,
188    0xa0
189};
190
191static const unsigned char p256_ikmr_priv[] = {
192    0xf3, 0xce, 0x7f, 0xda, 0xe5, 0x7e, 0x1a, 0x31,
193    0x0d, 0x87, 0xf1, 0xeb, 0xbd, 0xe6, 0xf3, 0x28,
194    0xbe, 0x0a, 0x99, 0xcd, 0xbc, 0xad, 0xf4, 0xd6,
195    0x58, 0x9c, 0xf2, 0x9d, 0xe4, 0xb8, 0xff, 0xd2
196};
197
198static const unsigned char p256_expected_enc[] = {
199    0x04, 0xa9, 0x27, 0x19, 0xc6, 0x19, 0x5d, 0x50,
200    0x85, 0x10, 0x4f, 0x46, 0x9a, 0x8b, 0x98, 0x14,
201    0xd5, 0x83, 0x8f, 0xf7, 0x2b, 0x60, 0x50, 0x1e,
202    0x2c, 0x44, 0x66, 0xe5, 0xe6, 0x7b, 0x32, 0x5a,
203    0xc9, 0x85, 0x36, 0xd7, 0xb6, 0x1a, 0x1a, 0xf4,
204    0xb7, 0x8e, 0x5b, 0x7f, 0x95, 0x1c, 0x09, 0x00,
205    0xbe, 0x86, 0x3c, 0x40, 0x3c, 0xe6, 0x5c, 0x9b,
206    0xfc, 0xb9, 0x38, 0x26, 0x57, 0x22, 0x2d, 0x18,
207    0xc4
208};
209static const unsigned char p256_expected_secret[] = {
210    0xc0, 0xd2, 0x6a, 0xea, 0xb5, 0x36, 0x60, 0x9a,
211    0x57, 0x2b, 0x07, 0x69, 0x5d, 0x93, 0x3b, 0x58,
212    0x9d, 0xcf, 0x36, 0x3f, 0xf9, 0xd9, 0x3c, 0x93,
213    0xad, 0xea, 0x53, 0x7a, 0xea, 0xbb, 0x8c, 0xb8
214};
215
216static const unsigned char p521_ikme[] = {
217    0x7f, 0x06, 0xab, 0x82, 0x15, 0x10, 0x5f, 0xc4,
218    0x6a, 0xce, 0xeb, 0x2e, 0x3d, 0xc5, 0x02, 0x8b,
219    0x44, 0x36, 0x4f, 0x96, 0x04, 0x26, 0xeb, 0x0d,
220    0x8e, 0x40, 0x26, 0xc2, 0xf8, 0xb5, 0xd7, 0xe7,
221    0xa9, 0x86, 0x68, 0x8f, 0x15, 0x91, 0xab, 0xf5,
222    0xab, 0x75, 0x3c, 0x35, 0x7a, 0x5d, 0x6f, 0x04,
223    0x40, 0x41, 0x4b, 0x4e, 0xd4, 0xed, 0xe7, 0x13,
224    0x17, 0x77, 0x2a, 0xc9, 0x8d, 0x92, 0x39, 0xf7,
225    0x09, 0x04
226};
227
228static const unsigned char p521_ikme_pub[] = {
229    0x04, 0x01, 0x38, 0xb3, 0x85, 0xca, 0x16, 0xbb,
230    0x0d, 0x5f, 0xa0, 0xc0, 0x66, 0x5f, 0xbb, 0xd7,
231    0xe6, 0x9e, 0x3e, 0xe2, 0x9f, 0x63, 0x99, 0x1d,
232    0x3e, 0x9b, 0x5f, 0xa7, 0x40, 0xaa, 0xb8, 0x90,
233    0x0a, 0xae, 0xed, 0x46, 0xed, 0x73, 0xa4, 0x90,
234    0x55, 0x75, 0x84, 0x25, 0xa0, 0xce, 0x36, 0x50,
235    0x7c, 0x54, 0xb2, 0x9c, 0xc5, 0xb8, 0x5a, 0x5c,
236    0xee, 0x6b, 0xae, 0x0c, 0xf1, 0xc2, 0x1f, 0x27,
237    0x31, 0xec, 0xe2, 0x01, 0x3d, 0xc3, 0xfb, 0x7c,
238    0x8d, 0x21, 0x65, 0x4b, 0xb1, 0x61, 0xb4, 0x63,
239    0x96, 0x2c, 0xa1, 0x9e, 0x8c, 0x65, 0x4f, 0xf2,
240    0x4c, 0x94, 0xdd, 0x28, 0x98, 0xde, 0x12, 0x05,
241    0x1f, 0x1e, 0xd0, 0x69, 0x22, 0x37, 0xfb, 0x02,
242    0xb2, 0xf8, 0xd1, 0xdc, 0x1c, 0x73, 0xe9, 0xb3,
243    0x66, 0xb5, 0x29, 0xeb, 0x43, 0x6e, 0x98, 0xa9,
244    0x96, 0xee, 0x52, 0x2a, 0xef, 0x86, 0x3d, 0xd5,
245    0x73, 0x9d, 0x2f, 0x29, 0xb0
246};
247
248static const unsigned char p521_ikme_priv[] = {
249    0x01, 0x47, 0x84, 0xc6, 0x92, 0xda, 0x35, 0xdf,
250    0x6e, 0xcd, 0xe9, 0x8e, 0xe4, 0x3a, 0xc4, 0x25,
251    0xdb, 0xdd, 0x09, 0x69, 0xc0, 0xc7, 0x2b, 0x42,
252    0xf2, 0xe7, 0x08, 0xab, 0x9d, 0x53, 0x54, 0x15,
253    0xa8, 0x56, 0x9b, 0xda, 0xcf, 0xcc, 0x0a, 0x11,
254    0x4c, 0x85, 0xb8, 0xe3, 0xf2, 0x6a, 0xcf, 0x4d,
255    0x68, 0x11, 0x5f, 0x8c, 0x91, 0xa6, 0x61, 0x78,
256    0xcd, 0xbd, 0x03, 0xb7, 0xbc, 0xc5, 0x29, 0x1e,
257    0x37, 0x4b
258};
259
260static const unsigned char p521_ikmr_pub[] = {
261    0x04, 0x01, 0xb4, 0x54, 0x98, 0xc1, 0x71, 0x4e,
262    0x2d, 0xce, 0x16, 0x7d, 0x3c, 0xaf, 0x16, 0x2e,
263    0x45, 0xe0, 0x64, 0x2a, 0xfc, 0x7e, 0xd4, 0x35,
264    0xdf, 0x79, 0x02, 0xcc, 0xae, 0x0e, 0x84, 0xba,
265    0x0f, 0x7d, 0x37, 0x3f, 0x64, 0x6b, 0x77, 0x38,
266    0xbb, 0xbd, 0xca, 0x11, 0xed, 0x91, 0xbd, 0xea,
267    0xe3, 0xcd, 0xcb, 0xa3, 0x30, 0x1f, 0x24, 0x57,
268    0xbe, 0x45, 0x2f, 0x27, 0x1f, 0xa6, 0x83, 0x75,
269    0x80, 0xe6, 0x61, 0x01, 0x2a, 0xf4, 0x95, 0x83,
270    0xa6, 0x2e, 0x48, 0xd4, 0x4b, 0xed, 0x35, 0x0c,
271    0x71, 0x18, 0xc0, 0xd8, 0xdc, 0x86, 0x1c, 0x23,
272    0x8c, 0x72, 0xa2, 0xbd, 0xa1, 0x7f, 0x64, 0x70,
273    0x4f, 0x46, 0x4b, 0x57, 0x33, 0x8e, 0x7f, 0x40,
274    0xb6, 0x09, 0x59, 0x48, 0x0c, 0x0e, 0x58, 0xe6,
275    0x55, 0x9b, 0x19, 0x0d, 0x81, 0x66, 0x3e, 0xd8,
276    0x16, 0xe5, 0x23, 0xb6, 0xb6, 0xa4, 0x18, 0xf6,
277    0x6d, 0x24, 0x51, 0xec, 0x64
278};
279static const unsigned char p521_ikmr_priv[] = {
280    0x01, 0x46, 0x26, 0x80, 0x36, 0x9a, 0xe3, 0x75,
281    0xe4, 0xb3, 0x79, 0x10, 0x70, 0xa7, 0x45, 0x8e,
282    0xd5, 0x27, 0x84, 0x2f, 0x6a, 0x98, 0xa7, 0x9f,
283    0xf5, 0xe0, 0xd4, 0xcb, 0xde, 0x83, 0xc2, 0x71,
284    0x96, 0xa3, 0x91, 0x69, 0x56, 0x65, 0x55, 0x23,
285    0xa6, 0xa2, 0x55, 0x6a, 0x7a, 0xf6, 0x2c, 0x5c,
286    0xad, 0xab, 0xe2, 0xef, 0x9d, 0xa3, 0x76, 0x0b,
287    0xb2, 0x1e, 0x00, 0x52, 0x02, 0xf7, 0xb2, 0x46,
288    0x28, 0x47
289};
290
291static const unsigned char p521_expected_enc[] = {
292    0x04, 0x01, 0x38, 0xb3, 0x85, 0xca, 0x16, 0xbb,
293    0x0d, 0x5f, 0xa0, 0xc0, 0x66, 0x5f, 0xbb, 0xd7,
294    0xe6, 0x9e, 0x3e, 0xe2, 0x9f, 0x63, 0x99, 0x1d,
295    0x3e, 0x9b, 0x5f, 0xa7, 0x40, 0xaa, 0xb8, 0x90,
296    0x0a, 0xae, 0xed, 0x46, 0xed, 0x73, 0xa4, 0x90,
297    0x55, 0x75, 0x84, 0x25, 0xa0, 0xce, 0x36, 0x50,
298    0x7c, 0x54, 0xb2, 0x9c, 0xc5, 0xb8, 0x5a, 0x5c,
299    0xee, 0x6b, 0xae, 0x0c, 0xf1, 0xc2, 0x1f, 0x27,
300    0x31, 0xec, 0xe2, 0x01, 0x3d, 0xc3, 0xfb, 0x7c,
301    0x8d, 0x21, 0x65, 0x4b, 0xb1, 0x61, 0xb4, 0x63,
302    0x96, 0x2c, 0xa1, 0x9e, 0x8c, 0x65, 0x4f, 0xf2,
303    0x4c, 0x94, 0xdd, 0x28, 0x98, 0xde, 0x12, 0x05,
304    0x1f, 0x1e, 0xd0, 0x69, 0x22, 0x37, 0xfb, 0x02,
305    0xb2, 0xf8, 0xd1, 0xdc, 0x1c, 0x73, 0xe9, 0xb3,
306    0x66, 0xb5, 0x29, 0xeb, 0x43, 0x6e, 0x98, 0xa9,
307    0x96, 0xee, 0x52, 0x2a, 0xef, 0x86, 0x3d, 0xd5,
308    0x73, 0x9d, 0x2f, 0x29, 0xb0
309};
310static const unsigned char p521_expected_secret[] = {
311    0x77, 0x6a, 0xb4, 0x21, 0x30, 0x2f, 0x6e, 0xff,
312    0x7d, 0x7c, 0xb5, 0xcb, 0x1a, 0xda, 0xea, 0x0c,
313    0xd5, 0x08, 0x72, 0xc7, 0x1c, 0x2d, 0x63, 0xc3,
314    0x0c, 0x4f, 0x1d, 0x5e, 0x43, 0x65, 0x33, 0x36,
315    0xfe, 0xf3, 0x3b, 0x10, 0x3c, 0x67, 0xe7, 0xa9,
316    0x8a, 0xdd, 0x2d, 0x3b, 0x66, 0xe2, 0xfd, 0xa9,
317    0x5b, 0x5b, 0x2a, 0x66, 0x7a, 0xa9, 0xda, 0xc7,
318    0xe5, 0x9c, 0xc1, 0xd4, 0x6d, 0x30, 0xe8, 0x18
319};
320
321static const unsigned char p521_auth_ikme[] = {
322    0xfe, 0x1c, 0x58, 0x9c, 0x2a, 0x05, 0x89, 0x38,
323    0x95, 0xa5, 0x37, 0xf3, 0x8c, 0x7c, 0xb4, 0x30,
324    0x0b, 0x5a, 0x7e, 0x8f, 0xef, 0x3d, 0x6c, 0xcb,
325    0x8f, 0x07, 0xa4, 0x98, 0x02, 0x9c, 0x61, 0xe9,
326    0x02, 0x62, 0xe0, 0x09, 0xdc, 0x25, 0x4c, 0x7f,
327    0x62, 0x35, 0xf9, 0xc6, 0xb2, 0xfd, 0x6a, 0xef,
328    0xf0, 0xa7, 0x14, 0xdb, 0x13, 0x1b, 0x09, 0x25,
329    0x8c, 0x16, 0xe2, 0x17, 0xb7, 0xbd, 0x2a, 0xa6,
330    0x19, 0xb0
331};
332
333static const unsigned char p521_auth_ikmr_pub[] = {
334    0x04, 0x00, 0x7d, 0x41, 0x9b, 0x88, 0x34, 0xe7,
335    0x51, 0x3d, 0x0e, 0x7c, 0xc6, 0x64, 0x24, 0xa1,
336    0x36, 0xec, 0x5e, 0x11, 0x39, 0x5a, 0xb3, 0x53,
337    0xda, 0x32, 0x4e, 0x35, 0x86, 0x67, 0x3e, 0xe7,
338    0x3d, 0x53, 0xab, 0x34, 0xf3, 0x0a, 0x0b, 0x42,
339    0xa9, 0x2d, 0x05, 0x4d, 0x0d, 0xb3, 0x21, 0xb8,
340    0x0f, 0x62, 0x17, 0xe6, 0x55, 0xe3, 0x04, 0xf7,
341    0x27, 0x93, 0x76, 0x7c, 0x42, 0x31, 0x78, 0x5c,
342    0x4a, 0x4a, 0x6e, 0x00, 0x8f, 0x31, 0xb9, 0x3b,
343    0x7a, 0x4f, 0x2b, 0x8c, 0xd1, 0x2e, 0x5f, 0xe5,
344    0xa0, 0x52, 0x3d, 0xc7, 0x13, 0x53, 0xc6, 0x6c,
345    0xbd, 0xad, 0x51, 0xc8, 0x6b, 0x9e, 0x0b, 0xdf,
346    0xcd, 0x9a, 0x45, 0x69, 0x8f, 0x2d, 0xab, 0x18,
347    0x09, 0xab, 0x1b, 0x0f, 0x88, 0xf5, 0x42, 0x27,
348    0x23, 0x2c, 0x85, 0x8a, 0xcc, 0xc4, 0x4d, 0x9a,
349    0x8d, 0x41, 0x77, 0x5a, 0xc0, 0x26, 0x34, 0x15,
350    0x64, 0xa2, 0xd7, 0x49, 0xf4
351};
352
353static const unsigned char p521_auth_ikmr_priv[] = {
354    0x01, 0x3e, 0xf3, 0x26, 0x94, 0x09, 0x98, 0x54,
355    0x4a, 0x89, 0x9e, 0x15, 0xe1, 0x72, 0x65, 0x48,
356    0xff, 0x43, 0xbb, 0xdb, 0x23, 0xa8, 0x58, 0x7a,
357    0xa3, 0xbe, 0xf9, 0xd1, 0xb8, 0x57, 0x33, 0x8d,
358    0x87, 0x28, 0x7d, 0xf5, 0x66, 0x70, 0x37, 0xb5,
359    0x19, 0xd6, 0xa1, 0x46, 0x61, 0xe9, 0x50, 0x3c,
360    0xfc, 0x95, 0xa1, 0x54, 0xd9, 0x35, 0x66, 0xd8,
361    0xc8, 0x4e, 0x95, 0xce, 0x93, 0xad, 0x05, 0x29,
362    0x3a, 0x0b
363};
364
365static const unsigned char p521_auth_ikms_pub[] = {
366    0x04, 0x01, 0x5c, 0xc3, 0x63, 0x66, 0x32, 0xea,
367    0x9a, 0x38, 0x79, 0xe4, 0x32, 0x40, 0xbe, 0xae,
368    0x5d, 0x15, 0xa4, 0x4f, 0xba, 0x81, 0x92, 0x82,
369    0xfa, 0xc2, 0x6a, 0x19, 0xc9, 0x89, 0xfa, 0xfd,
370    0xd0, 0xf3, 0x30, 0xb8, 0x52, 0x1d, 0xff, 0x7d,
371    0xc3, 0x93, 0x10, 0x1b, 0x01, 0x8c, 0x1e, 0x65,
372    0xb0, 0x7b, 0xe9, 0xf5, 0xfc, 0x9a, 0x28, 0xa1,
373    0xf4, 0x50, 0xd6, 0xa5, 0x41, 0xee, 0x0d, 0x76,
374    0x22, 0x11, 0x33, 0x00, 0x1e, 0x8f, 0x0f, 0x6a,
375    0x05, 0xab, 0x79, 0xf9, 0xb9, 0xbb, 0x9c, 0xcc,
376    0xe1, 0x42, 0xa4, 0x53, 0xd5, 0x9c, 0x5a, 0xbe,
377    0xbb, 0x56, 0x74, 0x83, 0x9d, 0x93, 0x5a, 0x3c,
378    0xa1, 0xa3, 0xfb, 0xc3, 0x28, 0x53, 0x9a, 0x60,
379    0xb3, 0xbc, 0x3c, 0x05, 0xfe, 0xd2, 0x28, 0x38,
380    0x58, 0x4a, 0x72, 0x6b, 0x9c, 0x17, 0x67, 0x96,
381    0xca, 0xd0, 0x16, 0x9b, 0xa4, 0x09, 0x33, 0x32,
382    0xcb, 0xd2, 0xdc, 0x3a, 0x9f
383};
384
385static const unsigned char p521_auth_ikms_priv[] = {
386    0x00, 0x10, 0x18, 0x58, 0x45, 0x99, 0x62, 0x5f,
387    0xf9, 0x95, 0x3b, 0x93, 0x05, 0x84, 0x98, 0x50,
388    0xd5, 0xe3, 0x4b, 0xd7, 0x89, 0xd4, 0xb8, 0x11,
389    0x01, 0x13, 0x96, 0x62, 0xfb, 0xea, 0x8b, 0x65,
390    0x08, 0xdd, 0xb9, 0xd0, 0x19, 0xb0, 0xd6, 0x92,
391    0xe7, 0x37, 0xf6, 0x6b, 0xea, 0xe3, 0xf1, 0xf7,
392    0x83, 0xe7, 0x44, 0x20, 0x2a, 0xaf, 0x6f, 0xea,
393    0x01, 0x50, 0x6c, 0x27, 0x28, 0x7e, 0x35, 0x9f,
394    0xe7, 0x76
395};
396
397static const unsigned char p521_auth_expected_enc[] = {
398    0x04, 0x01, 0x7d, 0xe1, 0x2e, 0xde, 0x7f, 0x72,
399    0xcb, 0x10, 0x1d, 0xab, 0x36, 0xa1, 0x11, 0x26,
400    0x5c, 0x97, 0xb3, 0x65, 0x48, 0x16, 0xdc, 0xd6,
401    0x18, 0x3f, 0x80, 0x9d, 0x4b, 0x3d, 0x11, 0x1f,
402    0xe7, 0x59, 0x49, 0x7f, 0x8a, 0xef, 0xdc, 0x5d,
403    0xbb, 0x40, 0xd3, 0xe6, 0xd2, 0x1d, 0xb1, 0x5b,
404    0xdc, 0x60, 0xf1, 0x5f, 0x2a, 0x42, 0x07, 0x61,
405    0xbc, 0xae, 0xef, 0x73, 0xb8, 0x91, 0xc2, 0xb1,
406    0x17, 0xe9, 0xcf, 0x01, 0xe2, 0x93, 0x20, 0xb7,
407    0x99, 0xbb, 0xc8, 0x6a, 0xfd, 0xc5, 0xea, 0x97,
408    0xd9, 0x41, 0xea, 0x1c, 0x5b, 0xd5, 0xeb, 0xee,
409    0xac, 0x7a, 0x78, 0x4b, 0x3b, 0xab, 0x52, 0x47,
410    0x46, 0xf3, 0xe6, 0x40, 0xec, 0x26, 0xee, 0x1b,
411    0xd9, 0x12, 0x55, 0xf9, 0x33, 0x0d, 0x97, 0x4f,
412    0x84, 0x50, 0x84, 0x63, 0x7e, 0xe0, 0xe6, 0xfe,
413    0x9f, 0x50, 0x5c, 0x5b, 0x87, 0xc8, 0x6a, 0x4e,
414    0x1a, 0x6c, 0x30, 0x96, 0xdd
415};
416
417static const unsigned char p521_auth_expected_secret[] = {
418    0x26, 0x64, 0x8f, 0xa2, 0xa2, 0xde, 0xb0, 0xbf,
419    0xc5, 0x63, 0x49, 0xa5, 0x90, 0xfd, 0x4c, 0xb7,
420    0x10, 0x8a, 0x51, 0x79, 0x7b, 0x63, 0x46, 0x94,
421    0xfc, 0x02, 0x06, 0x1e, 0x8d, 0x91, 0xb3, 0x57,
422    0x6a, 0xc7, 0x36, 0xa6, 0x8b, 0xf8, 0x48, 0xfe,
423    0x2a, 0x58, 0xdf, 0xb1, 0x95, 0x6d, 0x26, 0x6e,
424    0x68, 0x20, 0x9a, 0x4d, 0x63, 0x1e, 0x51, 0x3b,
425    0xad, 0xf8, 0xf4, 0xdc, 0xfc, 0x00, 0xf3, 0x0a
426};
427
428static const TEST_DERIVEKEY_DATA ec_derivekey_data[] = {
429    {
430      "P-256",
431      p256_ikme, sizeof(p256_ikme),
432      p256_ikme_pub, sizeof(p256_ikme_pub),
433      p256_ikme_priv, sizeof(p256_ikme_priv)
434    },
435    {
436      "P-256",
437      p256_ikmr, sizeof(p256_ikmr),
438      p256_ikmr_pub, sizeof(p256_ikmr_pub),
439      p256_ikmr_priv, sizeof(p256_ikmr_priv)
440    },
441    {
442      "P-521",
443      p521_ikme, sizeof(p521_ikme),
444      p521_ikme_pub, sizeof(p521_ikme_pub),
445      p521_ikme_priv, sizeof(p521_ikme_priv)
446    }
447};
448
449static const TEST_ENCAPDATA ec_encapdata[] = {
450    {
451        "P-256",
452        p256_ikme, sizeof(p256_ikme),
453        p256_ikmr_pub, sizeof(p256_ikmr_pub),
454        p256_ikmr_priv, sizeof(p256_ikmr_priv),
455        p256_expected_enc, sizeof(p256_expected_enc),
456        p256_expected_secret, sizeof(p256_expected_secret),
457    },
458#ifndef OPENSSL_NO_ECX
459    {
460        "X25519",
461        x25519_ikme, sizeof(x25519_ikme),
462        x25519_rpub, sizeof(x25519_rpub),
463        x25519_rpriv, sizeof(x25519_rpriv),
464        x25519_expected_enc, sizeof(x25519_expected_enc),
465        x25519_expected_secret, sizeof(x25519_expected_secret),
466    },
467#endif
468    {
469        "P-521",
470        p521_ikme, sizeof(p521_ikme),
471        p521_ikmr_pub, sizeof(p521_ikmr_pub),
472        p521_ikmr_priv, sizeof(p521_ikmr_priv),
473        p521_expected_enc, sizeof(p521_expected_enc),
474        p521_expected_secret, sizeof(p521_expected_secret),
475    },
476    {
477        "P-521",
478        p521_auth_ikme, sizeof(p521_auth_ikme),
479        p521_auth_ikmr_pub, sizeof(p521_auth_ikmr_pub),
480        p521_auth_ikmr_priv, sizeof(p521_auth_ikmr_priv),
481        p521_auth_expected_enc, sizeof(p521_auth_expected_enc),
482        p521_auth_expected_secret, sizeof(p521_auth_expected_secret),
483        p521_auth_ikms_pub, sizeof(p521_auth_ikms_pub),
484        p521_auth_ikms_priv, sizeof(p521_auth_ikms_priv)
485    },
486#ifndef OPENSSL_NO_ECX
487    {
488        "X25519",
489        x25519_auth_ikme, sizeof(x25519_auth_ikme),
490        x25519_auth_rpub, sizeof(x25519_auth_rpub),
491        x25519_auth_rpriv, sizeof(x25519_auth_rpriv),
492        x25519_auth_expected_enc, sizeof(x25519_auth_expected_enc),
493        x25519_auth_expected_secret, sizeof(x25519_auth_expected_secret),
494        x25519_auth_spub, sizeof(x25519_auth_spub),
495        x25519_auth_spriv, sizeof(x25519_auth_spriv)
496    }
497#endif
498};
499
500/* Test vector from https://github.com/cfrg/draft-irtf-cfrg-hpke */
501#ifndef OPENSSL_NO_ECX
502static const unsigned char x448_ikmr[] = {
503    0xd4, 0x5d, 0x16, 0x52, 0xdf, 0x74, 0x92, 0x0a,
504    0xbf, 0x94, 0xa2, 0x88, 0x3c, 0x83, 0x05, 0x0f,
505    0x50, 0x2f, 0xf5, 0x12, 0xff, 0xb5, 0x6f, 0x07,
506    0xb6, 0xd8, 0x33, 0xec, 0x8d, 0xda, 0x74, 0xb6,
507    0xa1, 0xc1, 0xcc, 0x4d, 0x42, 0xa2, 0x26, 0x41,
508    0xc0, 0x96, 0x3d, 0x3c, 0x21, 0xed, 0x82, 0x61,
509    0xf3, 0x44, 0xdc, 0x9e, 0x05, 0x01, 0xa8, 0x1c
510};
511static const unsigned char x448_ikmr_priv[] = {
512    0x27, 0xa4, 0x35, 0x46, 0x08, 0xf3, 0xbd, 0xd3,
513    0x8f, 0x1f, 0x5a, 0xf3, 0x05, 0xf3, 0xe0, 0x68,
514    0x2e, 0xfe, 0x4e, 0x25, 0x80, 0x82, 0x49, 0xd8,
515    0xfc, 0xb5, 0x59, 0x27, 0xf6, 0xa9, 0xf4, 0x46,
516    0xb8, 0xdc, 0x1d, 0x0a, 0x2c, 0x3b, 0x8c, 0xb1,
517    0x33, 0xa5, 0x67, 0x3b, 0x59, 0xa6, 0xd5, 0x5c,
518    0xe7, 0x54, 0xec, 0x0c, 0x9a, 0x55, 0x54, 0x01
519};
520static const unsigned char x448_ikmr_pub[] = {
521    0x14, 0x5d, 0x08, 0x3e, 0xa7, 0xa6, 0x37, 0x9d,
522    0xbb, 0x32, 0xdc, 0xbd, 0x8a, 0xff, 0x4c, 0x20,
523    0x6e, 0xa5, 0xd0, 0x69, 0xb7, 0x5e, 0x96, 0xc6,
524    0xdd, 0x2a, 0x3e, 0x38, 0xf4, 0x41, 0x47, 0x1a,
525    0xc9, 0x7a, 0xdc, 0xa6, 0x41, 0xfd, 0xad, 0x66,
526    0x68, 0x5a, 0x96, 0xf3, 0x2b, 0x7c, 0x3e, 0x06,
527    0x46, 0x35, 0xfa, 0xb3, 0xcc, 0x89, 0x23, 0x4e
528};
529
530static const TEST_DERIVEKEY_DATA ecx_derivekey_data[] = {
531    {
532      "X25519",
533      x25519_ikme, sizeof(x25519_ikme),
534      x25519_ikme_pub, sizeof(x25519_ikme_pub),
535      x25519_ikme_priv, sizeof(x25519_ikme_priv)
536    },
537    {
538      "X448",
539      x448_ikmr, sizeof(x448_ikmr),
540      x448_ikmr_pub, sizeof(x448_ikmr_pub),
541      x448_ikmr_priv, sizeof(x448_ikmr_priv)
542    },
543};
544#endif
545
546/*
547 * Helper function to create a EC or ECX private key from bytes.
548 * The public key can optionally be NULL.
549 */
550static EVP_PKEY *new_raw_private_key(const char *curvename,
551                                     const unsigned char *priv, size_t privlen,
552                                     const unsigned char *pub, size_t publen)
553{
554    int ok = 0;
555    EVP_PKEY_CTX *ctx;
556    EVP_PKEY *key = NULL;
557    OSSL_PARAM *params = NULL;
558    BIGNUM *privbn = NULL;
559    OSSL_PARAM_BLD *bld = NULL;
560    int ecx = (curvename[0] == 'X');
561
562    if (ecx)
563        ctx = EVP_PKEY_CTX_new_from_name(libctx, curvename, NULL);
564    else
565        ctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL);
566    if (ctx == NULL)
567        return 0;
568
569    bld = OSSL_PARAM_BLD_new();
570    if (bld == NULL)
571        goto err;
572
573    if (ecx) {
574        if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PRIV_KEY,
575                                             (char *)priv, privlen))
576            goto err;
577    } else {
578        privbn = BN_bin2bn(priv, privlen, NULL);
579        if (privbn == NULL)
580            goto err;
581        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
582                                             curvename, 0))
583            goto err;
584        if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, privbn))
585            goto err;
586    }
587
588    if (pub != NULL) {
589        if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
590                                             (char *)pub, publen))
591            goto err;
592    }
593    params = OSSL_PARAM_BLD_to_param(bld);
594    if (params == NULL)
595        goto err;
596
597    if (EVP_PKEY_fromdata_init(ctx) <= 0)
598          goto err;
599    if (EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_KEYPAIR, params) <= 0)
600          goto err;
601    ok = 1;
602err:
603    if (!ok) {
604        EVP_PKEY_free(key);
605        key = NULL;
606    }
607    BN_free(privbn);
608    OSSL_PARAM_free(params);
609    OSSL_PARAM_BLD_free(bld);
610    EVP_PKEY_CTX_free(ctx);
611    return key;
612}
613
614static EVP_PKEY *new_raw_public_key(const char *curvename,
615                                    const unsigned char *pub, size_t publen)
616{
617    int ok = 0;
618    EVP_PKEY_CTX *ctx;
619    EVP_PKEY *key = NULL;
620    OSSL_PARAM params[3], *p = params;
621    int ecx = (curvename[0] == 'X');
622
623    if (ecx)
624        ctx = EVP_PKEY_CTX_new_from_name(libctx, curvename, NULL);
625    else
626        ctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL);
627    if (ctx == NULL)
628        return 0;
629
630    if (!ecx)
631        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
632                                                (char *)curvename, 0);
633    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
634                                             (char *)pub, publen);
635    *p = OSSL_PARAM_construct_end();
636    if (EVP_PKEY_fromdata_init(ctx) <= 0)
637          goto err;
638    if (EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_PUBLIC_KEY, params) <= 0)
639          goto err;
640    ok = 1;
641err:
642    if (!ok) {
643        EVP_PKEY_free(key);
644        key = NULL;
645    }
646    EVP_PKEY_CTX_free(ctx);
647    return key;
648}
649
650/* Helper function to perform encapsulation */
651static int do_encap(const TEST_ENCAPDATA *t, EVP_PKEY *rpub, EVP_PKEY *spriv)
652{
653    int ret = 0;
654    unsigned char secret[256] = { 0, };
655    unsigned char enc[256] = { 0, };
656    size_t secretlen = 0, enclen = 0;
657    EVP_PKEY_CTX *sctx = NULL;
658    OSSL_PARAM params[3], *p = params;
659
660    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION,
661                                            (char *)OSSL_KEM_PARAM_OPERATION_DHKEM,
662                                            0);
663    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME,
664                                             (char *)t->ikmE, t->ikmElen);
665    *p = OSSL_PARAM_construct_end();
666
667    if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(libctx, rpub, NULL)))
668        goto err;
669    if (t->spriv == NULL) {
670        if (!TEST_int_eq(EVP_PKEY_encapsulate_init(sctx, params), 1))
671            goto err;
672    } else {
673        if (!TEST_int_eq(EVP_PKEY_auth_encapsulate_init(sctx, spriv, params), 1))
674        goto err;
675    }
676    ret = TEST_int_eq(EVP_PKEY_encapsulate(sctx, NULL, &enclen, NULL,
677                                              &secretlen), 1)
678          && TEST_int_eq(EVP_PKEY_encapsulate(sctx, enc, &enclen, secret,
679                                              &secretlen), 1)
680          && TEST_mem_eq(enc, enclen, t->expected_enc, t->expected_enclen)
681          && TEST_mem_eq(secret, secretlen,
682                         t->expected_secret, t->expected_secretlen);
683err:
684    EVP_PKEY_CTX_free(sctx);
685    return ret;
686}
687
688/* Helper function to perform decapsulation */
689static int do_decap(const TEST_ENCAPDATA *t, EVP_PKEY *rpriv, EVP_PKEY *spub)
690{
691    int ret = 0;
692    EVP_PKEY_CTX *recipctx = NULL;
693    unsigned char secret[256] = { 0, };
694    size_t secretlen = 0;
695
696    if (!TEST_ptr(recipctx = EVP_PKEY_CTX_new_from_pkey(libctx, rpriv, NULL)))
697        goto err;
698    if (t->spub == NULL) {
699        if (!TEST_int_eq(EVP_PKEY_decapsulate_init(recipctx, opparam), 1))
700            goto err;
701    } else {
702        if (!TEST_int_eq(EVP_PKEY_auth_decapsulate_init(recipctx, spub,
703                                                        opparam), 1))
704            goto err;
705    }
706    ret = TEST_int_eq(EVP_PKEY_decapsulate(recipctx, NULL, &secretlen,
707                                              t->expected_enc,
708                                              t->expected_enclen), 1)
709          && TEST_int_eq(EVP_PKEY_decapsulate(recipctx, secret, &secretlen,
710                                              t->expected_enc,
711                                              t->expected_enclen), 1)
712          && TEST_mem_eq(secret, secretlen,
713                         t->expected_secret, t->expected_secretlen);
714err:
715    EVP_PKEY_CTX_free(recipctx);
716    return ret;
717}
718