1 /*
2 * Wrapper functions for OpenSSL libcrypto
3 * Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10 #include <openssl/opensslv.h>
11 #include <openssl/err.h>
12 #include <openssl/des.h>
13 #include <openssl/aes.h>
14 #include <openssl/bn.h>
15 #include <openssl/evp.h>
16 #include <openssl/dh.h>
17 #include <openssl/hmac.h>
18 #include <openssl/rand.h>
19 #include <openssl/rsa.h>
20 #include <openssl/pem.h>
21 #ifdef CONFIG_ECC
22 #include <openssl/ec.h>
23 #include <openssl/x509.h>
24 #endif /* CONFIG_ECC */
25 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
26 #include <openssl/provider.h>
27 #include <openssl/core_names.h>
28 #include <openssl/param_build.h>
29 #include <openssl/encoder.h>
30 #include <openssl/decoder.h>
31 #else /* OpenSSL version >= 3.0 */
32 #include <openssl/cmac.h>
33 #endif /* OpenSSL version >= 3.0 */
34 #ifdef CONFIG_DPP3
35 #if OPENSSL_VERSION_NUMBER >= 0x30200000L
36 #include <openssl/hpke.h>
37 #endif
38 #endif /* CONFIG_DPP3 */
39
40 #include "common.h"
41 #include "utils/const_time.h"
42 #include "wpabuf.h"
43 #include "dh_group5.h"
44 #include "sha1.h"
45 #include "sha256.h"
46 #include "sha384.h"
47 #include "sha512.h"
48 #include "md5.h"
49 #include "aes_wrap.h"
50 #include "crypto.h"
51
52 #if OPENSSL_VERSION_NUMBER < 0x10100000L
53 /* Compatibility wrappers for older versions. */
54
HMAC_CTX_new(void)55 static HMAC_CTX * HMAC_CTX_new(void)
56 {
57 HMAC_CTX *ctx;
58
59 ctx = os_zalloc(sizeof(*ctx));
60 if (ctx)
61 HMAC_CTX_init(ctx);
62 return ctx;
63 }
64
65
HMAC_CTX_free(HMAC_CTX * ctx)66 static void HMAC_CTX_free(HMAC_CTX *ctx)
67 {
68 if (!ctx)
69 return;
70 HMAC_CTX_cleanup(ctx);
71 bin_clear_free(ctx, sizeof(*ctx));
72 }
73
74
EVP_MD_CTX_new(void)75 static EVP_MD_CTX * EVP_MD_CTX_new(void)
76 {
77 EVP_MD_CTX *ctx;
78
79 ctx = os_zalloc(sizeof(*ctx));
80 if (ctx)
81 EVP_MD_CTX_init(ctx);
82 return ctx;
83 }
84
85
EVP_MD_CTX_free(EVP_MD_CTX * ctx)86 static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
87 {
88 if (!ctx)
89 return;
90 EVP_MD_CTX_cleanup(ctx);
91 bin_clear_free(ctx, sizeof(*ctx));
92 }
93
94
95 #ifdef CONFIG_ECC
96
EVP_PKEY_get0_EC_KEY(EVP_PKEY * pkey)97 static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
98 {
99 if (pkey->type != EVP_PKEY_EC)
100 return NULL;
101 return pkey->pkey.ec;
102 }
103
104
ECDSA_SIG_set0(ECDSA_SIG * sig,BIGNUM * r,BIGNUM * s)105 static int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
106 {
107 sig->r = r;
108 sig->s = s;
109 return 1;
110 }
111
112
ECDSA_SIG_get0(const ECDSA_SIG * sig,const BIGNUM ** pr,const BIGNUM ** ps)113 static void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr,
114 const BIGNUM **ps)
115 {
116 if (pr)
117 *pr = sig->r;
118 if (ps)
119 *ps = sig->s;
120 }
121
122 #endif /* CONFIG_ECC */
123
ASN1_STRING_get0_data(const ASN1_STRING * x)124 static const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
125 {
126 return ASN1_STRING_data((ASN1_STRING *) x);
127 }
128
129
X509_get0_notBefore(const X509 * x)130 static const ASN1_TIME * X509_get0_notBefore(const X509 *x)
131 {
132 return X509_get_notBefore(x);
133 }
134
135
X509_get0_notAfter(const X509 * x)136 static const ASN1_TIME * X509_get0_notAfter(const X509 *x)
137 {
138 return X509_get_notAfter(x);
139 }
140
141 #endif /* OpenSSL version < 1.1.0 */
142
143
144 #if OPENSSL_VERSION_NUMBER < 0x10101000L || \
145 (defined(LIBRESSL_VERSION_NUMBER) && \
146 LIBRESSL_VERSION_NUMBER < 0x30400000L)
147
EC_POINT_get_affine_coordinates(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BN_CTX * ctx)148 static int EC_POINT_get_affine_coordinates(const EC_GROUP *group,
149 const EC_POINT *point, BIGNUM *x,
150 BIGNUM *y, BN_CTX *ctx)
151 {
152 return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
153 }
154
155
EC_POINT_set_affine_coordinates(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,BN_CTX * ctx)156 static int EC_POINT_set_affine_coordinates(const EC_GROUP *group,
157 EC_POINT *point, const BIGNUM *x,
158 const BIGNUM *y, BN_CTX *ctx)
159 {
160 return EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx);
161 }
162
163 #endif /* OpenSSL version < 1.1.1 */
164
165
166 #if OPENSSL_VERSION_NUMBER < 0x10101000L || \
167 defined(OPENSSL_IS_BORINGSSL) || \
168 (defined(LIBRESSL_VERSION_NUMBER) && \
169 LIBRESSL_VERSION_NUMBER < 0x30400000L)
170
EC_POINT_set_compressed_coordinates(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,int y_bit,BN_CTX * ctx)171 static int EC_POINT_set_compressed_coordinates(const EC_GROUP *group,
172 EC_POINT *point, const BIGNUM *x,
173 int y_bit, BN_CTX *ctx)
174 {
175 return EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit,
176 ctx);
177 }
178
179
EC_GROUP_get_curve(const EC_GROUP * group,BIGNUM * p,BIGNUM * a,BIGNUM * b,BN_CTX * ctx)180 static int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
181 BIGNUM *b, BN_CTX *ctx)
182 {
183 return EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
184 }
185
186 #endif /* OpenSSL version < 1.1.1 */
187
188
openssl_disable_fips(void)189 static void openssl_disable_fips(void)
190 {
191 #ifndef CONFIG_FIPS
192 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
193 static bool done = false;
194
195 if (done)
196 return;
197 done = true;
198
199 if (!EVP_default_properties_is_fips_enabled(NULL))
200 return; /* FIPS mode is not enabled */
201
202 if (!EVP_default_properties_enable_fips(NULL, 0))
203 wpa_printf(MSG_INFO,
204 "OpenSSL: Failed to disable FIPS mode");
205 else
206 wpa_printf(MSG_DEBUG,
207 "OpenSSL: Disabled FIPS mode to enable non-FIPS-compliant algorithms and parameters");
208 #endif /* OpenSSL version >= 3.0 */
209 #endif /* !CONFIG_FIPS */
210 }
211
212 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
213 static OSSL_PROVIDER *openssl_legacy_provider = NULL;
214 static OSSL_PROVIDER *openssl_default_provider = NULL;
215 #endif /* OpenSSL version >= 3.0 */
216
openssl_load_legacy_provider(void)217 void openssl_load_legacy_provider(void)
218 {
219 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
220 if (openssl_legacy_provider)
221 return;
222
223 openssl_legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1);
224 #endif /* OpenSSL version >= 3.0 */
225 }
226
227
openssl_unload_legacy_provider(void)228 static void openssl_unload_legacy_provider(void)
229 {
230 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
231 if (openssl_legacy_provider) {
232 OSSL_PROVIDER_unload(openssl_legacy_provider);
233 openssl_legacy_provider = NULL;
234 }
235 #endif /* OpenSSL version >= 3.0 */
236 }
237
238
openssl_load_default_provider_if_fips(void)239 static void openssl_load_default_provider_if_fips(void)
240 {
241 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
242 if (openssl_default_provider)
243 return;
244
245 if (!OSSL_PROVIDER_available(NULL, "fips"))
246 return;
247
248 wpa_printf(MSG_DEBUG,
249 "OpenSSL: Load default provider to replace fips provider when needed");
250 openssl_default_provider = OSSL_PROVIDER_try_load(NULL, "default", 1);
251 if (!openssl_default_provider)
252 wpa_printf(MSG_DEBUG,
253 "OpenSSL: Failed to load default provider");
254 #endif /* OpenSSL version >= 3.0 */
255 }
256
257
openssl_unload_default_provider(void)258 static void openssl_unload_default_provider(void)
259 {
260 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
261 if (openssl_default_provider) {
262 OSSL_PROVIDER_unload(openssl_default_provider);
263 openssl_default_provider = NULL;
264 }
265 #endif /* OpenSSL version >= 3.0 */
266 }
267
268
269 #if OPENSSL_VERSION_NUMBER < 0x30000000L
270
get_group5_prime(void)271 static BIGNUM * get_group5_prime(void)
272 {
273 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
274 return BN_get_rfc3526_prime_1536(NULL);
275 #elif !defined(OPENSSL_IS_BORINGSSL)
276 return get_rfc3526_prime_1536(NULL);
277 #else
278 static const unsigned char RFC3526_PRIME_1536[] = {
279 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
280 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
281 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
282 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
283 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
284 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
285 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
286 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
287 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
288 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
289 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
290 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
291 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
292 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
293 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
294 0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
295 };
296 return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), NULL);
297 #endif
298 }
299
300
get_group5_order(void)301 static BIGNUM * get_group5_order(void)
302 {
303 static const unsigned char RFC3526_ORDER_1536[] = {
304 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0x87,0xED,0x51,
305 0x10,0xB4,0x61,0x1A,0x62,0x63,0x31,0x45,0xC0,0x6E,0x0E,0x68,
306 0x94,0x81,0x27,0x04,0x45,0x33,0xE6,0x3A,0x01,0x05,0xDF,0x53,
307 0x1D,0x89,0xCD,0x91,0x28,0xA5,0x04,0x3C,0xC7,0x1A,0x02,0x6E,
308 0xF7,0xCA,0x8C,0xD9,0xE6,0x9D,0x21,0x8D,0x98,0x15,0x85,0x36,
309 0xF9,0x2F,0x8A,0x1B,0xA7,0xF0,0x9A,0xB6,0xB6,0xA8,0xE1,0x22,
310 0xF2,0x42,0xDA,0xBB,0x31,0x2F,0x3F,0x63,0x7A,0x26,0x21,0x74,
311 0xD3,0x1B,0xF6,0xB5,0x85,0xFF,0xAE,0x5B,0x7A,0x03,0x5B,0xF6,
312 0xF7,0x1C,0x35,0xFD,0xAD,0x44,0xCF,0xD2,0xD7,0x4F,0x92,0x08,
313 0xBE,0x25,0x8F,0xF3,0x24,0x94,0x33,0x28,0xF6,0x72,0x2D,0x9E,
314 0xE1,0x00,0x3E,0x5C,0x50,0xB1,0xDF,0x82,0xCC,0x6D,0x24,0x1B,
315 0x0E,0x2A,0xE9,0xCD,0x34,0x8B,0x1F,0xD4,0x7E,0x92,0x67,0xAF,
316 0xC1,0xB2,0xAE,0x91,0xEE,0x51,0xD6,0xCB,0x0E,0x31,0x79,0xAB,
317 0x10,0x42,0xA9,0x5D,0xCF,0x6A,0x94,0x83,0xB8,0x4B,0x4B,0x36,
318 0xB3,0x86,0x1A,0xA7,0x25,0x5E,0x4C,0x02,0x78,0xBA,0x36,0x04,
319 0x65,0x11,0xB9,0x93,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
320 };
321 return BN_bin2bn(RFC3526_ORDER_1536, sizeof(RFC3526_ORDER_1536), NULL);
322 }
323
324 #endif /* OpenSSL version < 3.0 */
325
326
327 #ifdef OPENSSL_NO_SHA256
328 #define NO_SHA256_WRAPPER
329 #endif
330 #ifdef OPENSSL_NO_SHA512
331 #define NO_SHA384_WRAPPER
332 #endif
333
openssl_digest_vector(const EVP_MD * type,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)334 static int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
335 const u8 *addr[], const size_t *len, u8 *mac)
336 {
337 EVP_MD_CTX *ctx;
338 size_t i;
339 unsigned int mac_len;
340
341 if (TEST_FAIL())
342 return -1;
343
344 ctx = EVP_MD_CTX_new();
345 if (!ctx)
346 return -1;
347 if (!EVP_DigestInit_ex(ctx, type, NULL)) {
348 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
349 ERR_error_string(ERR_get_error(), NULL));
350 EVP_MD_CTX_free(ctx);
351 return -1;
352 }
353 for (i = 0; i < num_elem; i++) {
354 if (!EVP_DigestUpdate(ctx, addr[i], len[i])) {
355 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
356 "failed: %s",
357 ERR_error_string(ERR_get_error(), NULL));
358 EVP_MD_CTX_free(ctx);
359 return -1;
360 }
361 }
362 if (!EVP_DigestFinal(ctx, mac, &mac_len)) {
363 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
364 ERR_error_string(ERR_get_error(), NULL));
365 EVP_MD_CTX_free(ctx);
366 return -1;
367 }
368 EVP_MD_CTX_free(ctx);
369
370 return 0;
371 }
372
373
374 #ifndef CONFIG_FIPS
375
openssl_need_md5(void)376 static void openssl_need_md5(void)
377 {
378 openssl_disable_fips();
379 openssl_load_default_provider_if_fips();
380 }
381
382
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)383 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
384 {
385 openssl_disable_fips();
386 openssl_load_legacy_provider();
387 return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
388 }
389
390
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)391 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
392 {
393 u8 pkey[8], next, tmp;
394 int i, plen, ret = -1;
395 EVP_CIPHER_CTX *ctx;
396
397 openssl_load_legacy_provider();
398
399 /* Add parity bits to the key */
400 next = 0;
401 for (i = 0; i < 7; i++) {
402 tmp = key[i];
403 pkey[i] = (tmp >> i) | next | 1;
404 next = tmp << (7 - i);
405 }
406 pkey[i] = next | 1;
407
408 ctx = EVP_CIPHER_CTX_new();
409 if (ctx &&
410 EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, pkey, NULL) == 1 &&
411 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
412 EVP_EncryptUpdate(ctx, cypher, &plen, clear, 8) == 1 &&
413 EVP_EncryptFinal_ex(ctx, &cypher[plen], &plen) == 1)
414 ret = 0;
415 else
416 wpa_printf(MSG_ERROR, "OpenSSL: DES encrypt failed");
417
418 if (ctx)
419 EVP_CIPHER_CTX_free(ctx);
420 return ret;
421 }
422
423
424 #ifndef CONFIG_NO_RC4
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)425 int rc4_skip(const u8 *key, size_t keylen, size_t skip,
426 u8 *data, size_t data_len)
427 {
428 #ifdef OPENSSL_NO_RC4
429 return -1;
430 #else /* OPENSSL_NO_RC4 */
431 EVP_CIPHER_CTX *ctx;
432 int outl;
433 int res = -1;
434 unsigned char skip_buf[16];
435
436 openssl_load_legacy_provider();
437
438 ctx = EVP_CIPHER_CTX_new();
439 if (!ctx ||
440 !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
441 !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
442 !EVP_CIPHER_CTX_set_key_length(ctx, keylen) ||
443 !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1))
444 goto out;
445
446 while (skip >= sizeof(skip_buf)) {
447 size_t len = skip;
448 if (len > sizeof(skip_buf))
449 len = sizeof(skip_buf);
450 if (!EVP_CipherUpdate(ctx, skip_buf, &outl, skip_buf, len))
451 goto out;
452 skip -= len;
453 }
454
455 if (EVP_CipherUpdate(ctx, data, &outl, data, data_len))
456 res = 0;
457
458 out:
459 if (ctx)
460 EVP_CIPHER_CTX_free(ctx);
461 return res;
462 #endif /* OPENSSL_NO_RC4 */
463 }
464 #endif /* CONFIG_NO_RC4 */
465
466
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)467 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
468 {
469 openssl_need_md5();
470 return openssl_digest_vector(EVP_md5(), num_elem, addr, len, mac);
471 }
472
473 #endif /* CONFIG_FIPS */
474
475
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)476 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
477 {
478 return openssl_digest_vector(EVP_sha1(), num_elem, addr, len, mac);
479 }
480
481
482 #ifndef NO_SHA256_WRAPPER
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)483 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
484 u8 *mac)
485 {
486 return openssl_digest_vector(EVP_sha256(), num_elem, addr, len, mac);
487 }
488 #endif /* NO_SHA256_WRAPPER */
489
490
491 #ifndef NO_SHA384_WRAPPER
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)492 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
493 u8 *mac)
494 {
495 return openssl_digest_vector(EVP_sha384(), num_elem, addr, len, mac);
496 }
497 #endif /* NO_SHA384_WRAPPER */
498
499
500 #ifndef NO_SHA512_WRAPPER
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)501 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
502 u8 *mac)
503 {
504 return openssl_digest_vector(EVP_sha512(), num_elem, addr, len, mac);
505 }
506 #endif /* NO_SHA512_WRAPPER */
507
508
aes_get_evp_cipher(size_t keylen)509 static const EVP_CIPHER * aes_get_evp_cipher(size_t keylen)
510 {
511 switch (keylen) {
512 case 16:
513 return EVP_aes_128_ecb();
514 case 24:
515 return EVP_aes_192_ecb();
516 case 32:
517 return EVP_aes_256_ecb();
518 default:
519 return NULL;
520 }
521 }
522
523
aes_encrypt_init(const u8 * key,size_t len)524 void * aes_encrypt_init(const u8 *key, size_t len)
525 {
526 EVP_CIPHER_CTX *ctx;
527 const EVP_CIPHER *type;
528
529 if (TEST_FAIL())
530 return NULL;
531
532 type = aes_get_evp_cipher(len);
533 if (!type) {
534 wpa_printf(MSG_INFO, "%s: Unsupported len=%u",
535 __func__, (unsigned int) len);
536 return NULL;
537 }
538
539 ctx = EVP_CIPHER_CTX_new();
540 if (ctx == NULL)
541 return NULL;
542 if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1 ||
543 EVP_CIPHER_CTX_set_padding(ctx, 0) != 1) {
544 EVP_CIPHER_CTX_free(ctx);
545 return NULL;
546 }
547 return ctx;
548 }
549
550
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)551 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
552 {
553 EVP_CIPHER_CTX *c = ctx;
554 int clen = 16;
555 if (EVP_EncryptUpdate(c, crypt, &clen, plain, 16) != 1) {
556 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptUpdate failed: %s",
557 ERR_error_string(ERR_get_error(), NULL));
558 return -1;
559 }
560 return 0;
561 }
562
563
aes_encrypt_deinit(void * ctx)564 void aes_encrypt_deinit(void *ctx)
565 {
566 EVP_CIPHER_CTX *c = ctx;
567 u8 buf[16];
568 int len = sizeof(buf);
569 if (EVP_EncryptFinal_ex(c, buf, &len) != 1) {
570 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptFinal_ex failed: "
571 "%s", ERR_error_string(ERR_get_error(), NULL));
572 }
573 if (len != 0) {
574 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
575 "in AES encrypt", len);
576 }
577 EVP_CIPHER_CTX_free(c);
578 }
579
580
aes_decrypt_init(const u8 * key,size_t len)581 void * aes_decrypt_init(const u8 *key, size_t len)
582 {
583 EVP_CIPHER_CTX *ctx;
584 const EVP_CIPHER *type;
585
586 if (TEST_FAIL())
587 return NULL;
588
589 type = aes_get_evp_cipher(len);
590 if (!type) {
591 wpa_printf(MSG_INFO, "%s: Unsupported len=%u",
592 __func__, (unsigned int) len);
593 return NULL;
594 }
595
596 ctx = EVP_CIPHER_CTX_new();
597 if (ctx == NULL)
598 return NULL;
599 if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1 ||
600 EVP_CIPHER_CTX_set_padding(ctx, 0) != 1) {
601 EVP_CIPHER_CTX_free(ctx);
602 return NULL;
603 }
604 return ctx;
605 }
606
607
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)608 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
609 {
610 EVP_CIPHER_CTX *c = ctx;
611 int plen = 16;
612 if (EVP_DecryptUpdate(c, plain, &plen, crypt, 16) != 1) {
613 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptUpdate failed: %s",
614 ERR_error_string(ERR_get_error(), NULL));
615 return -1;
616 }
617 return 0;
618 }
619
620
aes_decrypt_deinit(void * ctx)621 void aes_decrypt_deinit(void *ctx)
622 {
623 EVP_CIPHER_CTX *c = ctx;
624 u8 buf[16];
625 int len = sizeof(buf);
626 if (EVP_DecryptFinal_ex(c, buf, &len) != 1) {
627 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptFinal_ex failed: "
628 "%s", ERR_error_string(ERR_get_error(), NULL));
629 }
630 if (len != 0) {
631 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
632 "in AES decrypt", len);
633 }
634 EVP_CIPHER_CTX_free(c);
635 }
636
637
638 #ifndef CONFIG_FIPS
639 #ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
640
641 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
aes_get_evp_wrap_cipher(size_t keylen)642 static const EVP_CIPHER * aes_get_evp_wrap_cipher(size_t keylen)
643 {
644 switch (keylen) {
645 case 16:
646 return EVP_aes_128_wrap();
647 case 24:
648 return EVP_aes_192_wrap();
649 case 32:
650 return EVP_aes_256_wrap();
651 default:
652 return NULL;
653 }
654 }
655 #endif /* OpenSSL version >= 3.0 */
656
657
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)658 int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
659 {
660 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
661 EVP_CIPHER_CTX *ctx;
662 const EVP_CIPHER *type;
663 int ret = -1, len;
664 u8 buf[16];
665
666 if (TEST_FAIL())
667 return -1;
668
669 type = aes_get_evp_wrap_cipher(kek_len);
670 if (!type)
671 return -1;
672
673 ctx = EVP_CIPHER_CTX_new();
674 if (!ctx)
675 return -1;
676
677 if (EVP_EncryptInit_ex(ctx, type, NULL, kek, NULL) == 1 &&
678 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
679 EVP_EncryptUpdate(ctx, cipher, &len, plain, n * 8) == 1 &&
680 len == (n + 1) * 8 &&
681 EVP_EncryptFinal_ex(ctx, buf, &len) == 1)
682 ret = 0;
683
684 EVP_CIPHER_CTX_free(ctx);
685 return ret;
686 #else /* OpenSSL version >= 3.0 */
687 AES_KEY actx;
688 int res;
689
690 if (TEST_FAIL())
691 return -1;
692 if (AES_set_encrypt_key(kek, kek_len << 3, &actx))
693 return -1;
694 res = AES_wrap_key(&actx, NULL, cipher, plain, n * 8);
695 OPENSSL_cleanse(&actx, sizeof(actx));
696 return res <= 0 ? -1 : 0;
697 #endif /* OpenSSL version >= 3.0 */
698 }
699
700
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)701 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
702 u8 *plain)
703 {
704 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
705 EVP_CIPHER_CTX *ctx;
706 const EVP_CIPHER *type;
707 int ret = -1, len;
708 u8 buf[16];
709
710 if (TEST_FAIL())
711 return -1;
712
713 type = aes_get_evp_wrap_cipher(kek_len);
714 if (!type)
715 return -1;
716
717 ctx = EVP_CIPHER_CTX_new();
718 if (!ctx)
719 return -1;
720
721 if (EVP_DecryptInit_ex(ctx, type, NULL, kek, NULL) == 1 &&
722 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
723 EVP_DecryptUpdate(ctx, plain, &len, cipher, (n + 1) * 8) == 1 &&
724 len == n * 8 &&
725 EVP_DecryptFinal_ex(ctx, buf, &len) == 1)
726 ret = 0;
727
728 EVP_CIPHER_CTX_free(ctx);
729 return ret;
730 #else /* OpenSSL version >= 3.0 */
731 AES_KEY actx;
732 int res;
733
734 if (TEST_FAIL())
735 return -1;
736 if (AES_set_decrypt_key(kek, kek_len << 3, &actx))
737 return -1;
738 res = AES_unwrap_key(&actx, NULL, plain, cipher, (n + 1) * 8);
739 OPENSSL_cleanse(&actx, sizeof(actx));
740 return res <= 0 ? -1 : 0;
741 #endif /* OpenSSL version >= 3.0 */
742 }
743
744 #endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
745 #endif /* CONFIG_FIPS */
746
747
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)748 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
749 {
750 EVP_CIPHER_CTX *ctx;
751 int clen, len;
752 u8 buf[16];
753 int res = -1;
754
755 if (TEST_FAIL())
756 return -1;
757
758 ctx = EVP_CIPHER_CTX_new();
759 if (!ctx)
760 return -1;
761 clen = data_len;
762 len = sizeof(buf);
763 if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
764 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
765 EVP_EncryptUpdate(ctx, data, &clen, data, data_len) == 1 &&
766 clen == (int) data_len &&
767 EVP_EncryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
768 res = 0;
769 EVP_CIPHER_CTX_free(ctx);
770
771 return res;
772 }
773
774
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)775 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
776 {
777 EVP_CIPHER_CTX *ctx;
778 int plen, len;
779 u8 buf[16];
780 int res = -1;
781
782 if (TEST_FAIL())
783 return -1;
784
785 ctx = EVP_CIPHER_CTX_new();
786 if (!ctx)
787 return -1;
788 plen = data_len;
789 len = sizeof(buf);
790 if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
791 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
792 EVP_DecryptUpdate(ctx, data, &plen, data, data_len) == 1 &&
793 plen == (int) data_len &&
794 EVP_DecryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
795 res = 0;
796 EVP_CIPHER_CTX_free(ctx);
797
798 return res;
799
800 }
801
802
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)803 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
804 u8 *pubkey)
805 {
806 size_t pubkey_len, pad;
807
808 if (os_get_random(privkey, prime_len) < 0)
809 return -1;
810 if (os_memcmp(privkey, prime, prime_len) > 0) {
811 /* Make sure private value is smaller than prime */
812 privkey[0] = 0;
813 }
814
815 pubkey_len = prime_len;
816 if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len,
817 pubkey, &pubkey_len) < 0)
818 return -1;
819 if (pubkey_len < prime_len) {
820 pad = prime_len - pubkey_len;
821 os_memmove(pubkey + pad, pubkey, pubkey_len);
822 os_memset(pubkey, 0, pad);
823 }
824
825 return 0;
826 }
827
828
crypto_dh_derive_secret(u8 generator,const u8 * prime,size_t prime_len,const u8 * order,size_t order_len,const u8 * privkey,size_t privkey_len,const u8 * pubkey,size_t pubkey_len,u8 * secret,size_t * len)829 int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
830 const u8 *order, size_t order_len,
831 const u8 *privkey, size_t privkey_len,
832 const u8 *pubkey, size_t pubkey_len,
833 u8 *secret, size_t *len)
834 {
835 BIGNUM *pub, *p;
836 int res = -1;
837
838 pub = BN_bin2bn(pubkey, pubkey_len, NULL);
839 p = BN_bin2bn(prime, prime_len, NULL);
840 if (!pub || !p || BN_is_zero(pub) || BN_is_one(pub) ||
841 BN_cmp(pub, p) >= 0)
842 goto fail;
843
844 if (order) {
845 BN_CTX *ctx;
846 BIGNUM *q, *tmp;
847 int failed;
848
849 /* verify: pubkey^q == 1 mod p */
850 q = BN_bin2bn(order, order_len, NULL);
851 ctx = BN_CTX_new();
852 tmp = BN_new();
853 failed = !q || !ctx || !tmp ||
854 !BN_mod_exp(tmp, pub, q, p, ctx) ||
855 !BN_is_one(tmp);
856 BN_clear_free(q);
857 BN_clear_free(tmp);
858 BN_CTX_free(ctx);
859 if (failed)
860 goto fail;
861 }
862
863 res = crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len,
864 prime, prime_len, secret, len);
865 fail:
866 BN_clear_free(pub);
867 BN_clear_free(p);
868 return res;
869 }
870
871
crypto_mod_exp(const u8 * base,size_t base_len,const u8 * power,size_t power_len,const u8 * modulus,size_t modulus_len,u8 * result,size_t * result_len)872 int crypto_mod_exp(const u8 *base, size_t base_len,
873 const u8 *power, size_t power_len,
874 const u8 *modulus, size_t modulus_len,
875 u8 *result, size_t *result_len)
876 {
877 BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result;
878 int ret = -1;
879 BN_CTX *ctx;
880
881 ctx = BN_CTX_new();
882 if (ctx == NULL)
883 return -1;
884
885 bn_base = BN_bin2bn(base, base_len, NULL);
886 bn_exp = BN_bin2bn(power, power_len, NULL);
887 bn_modulus = BN_bin2bn(modulus, modulus_len, NULL);
888 bn_result = BN_new();
889
890 if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
891 bn_result == NULL)
892 goto error;
893
894 if (BN_mod_exp_mont_consttime(bn_result, bn_base, bn_exp, bn_modulus,
895 ctx, NULL) != 1)
896 goto error;
897
898 *result_len = BN_bn2bin(bn_result, result);
899 ret = 0;
900
901 error:
902 BN_clear_free(bn_base);
903 BN_clear_free(bn_exp);
904 BN_clear_free(bn_modulus);
905 BN_clear_free(bn_result);
906 BN_CTX_free(ctx);
907 return ret;
908 }
909
910
911 struct crypto_cipher {
912 EVP_CIPHER_CTX *enc;
913 EVP_CIPHER_CTX *dec;
914 };
915
916
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)917 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
918 const u8 *iv, const u8 *key,
919 size_t key_len)
920 {
921 struct crypto_cipher *ctx;
922 const EVP_CIPHER *cipher;
923
924 ctx = os_zalloc(sizeof(*ctx));
925 if (ctx == NULL)
926 return NULL;
927
928 switch (alg) {
929 #ifndef CONFIG_NO_RC4
930 #ifndef OPENSSL_NO_RC4
931 case CRYPTO_CIPHER_ALG_RC4:
932 cipher = EVP_rc4();
933 break;
934 #endif /* OPENSSL_NO_RC4 */
935 #endif /* CONFIG_NO_RC4 */
936 #ifndef OPENSSL_NO_AES
937 case CRYPTO_CIPHER_ALG_AES:
938 switch (key_len) {
939 case 16:
940 cipher = EVP_aes_128_cbc();
941 break;
942 #ifndef OPENSSL_IS_BORINGSSL
943 case 24:
944 cipher = EVP_aes_192_cbc();
945 break;
946 #endif /* OPENSSL_IS_BORINGSSL */
947 case 32:
948 cipher = EVP_aes_256_cbc();
949 break;
950 default:
951 os_free(ctx);
952 return NULL;
953 }
954 break;
955 #endif /* OPENSSL_NO_AES */
956 #ifndef OPENSSL_NO_DES
957 case CRYPTO_CIPHER_ALG_3DES:
958 cipher = EVP_des_ede3_cbc();
959 break;
960 case CRYPTO_CIPHER_ALG_DES:
961 cipher = EVP_des_cbc();
962 break;
963 #endif /* OPENSSL_NO_DES */
964 #ifndef OPENSSL_NO_RC2
965 case CRYPTO_CIPHER_ALG_RC2:
966 cipher = EVP_rc2_ecb();
967 break;
968 #endif /* OPENSSL_NO_RC2 */
969 default:
970 os_free(ctx);
971 return NULL;
972 }
973
974 if (!(ctx->enc = EVP_CIPHER_CTX_new()) ||
975 !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) ||
976 !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
977 !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) ||
978 !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) {
979 if (ctx->enc)
980 EVP_CIPHER_CTX_free(ctx->enc);
981 os_free(ctx);
982 return NULL;
983 }
984
985 if (!(ctx->dec = EVP_CIPHER_CTX_new()) ||
986 !EVP_DecryptInit_ex(ctx->dec, cipher, NULL, NULL, NULL) ||
987 !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) ||
988 !EVP_CIPHER_CTX_set_key_length(ctx->dec, key_len) ||
989 !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) {
990 EVP_CIPHER_CTX_free(ctx->enc);
991 if (ctx->dec)
992 EVP_CIPHER_CTX_free(ctx->dec);
993 os_free(ctx);
994 return NULL;
995 }
996
997 return ctx;
998 }
999
1000
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)1001 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
1002 u8 *crypt, size_t len)
1003 {
1004 int outl;
1005 if (!EVP_EncryptUpdate(ctx->enc, crypt, &outl, plain, len))
1006 return -1;
1007 return 0;
1008 }
1009
1010
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)1011 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
1012 u8 *plain, size_t len)
1013 {
1014 int outl;
1015 outl = len;
1016 if (!EVP_DecryptUpdate(ctx->dec, plain, &outl, crypt, len))
1017 return -1;
1018 return 0;
1019 }
1020
1021
crypto_cipher_deinit(struct crypto_cipher * ctx)1022 void crypto_cipher_deinit(struct crypto_cipher *ctx)
1023 {
1024 EVP_CIPHER_CTX_free(ctx->enc);
1025 EVP_CIPHER_CTX_free(ctx->dec);
1026 os_free(ctx);
1027 }
1028
1029
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)1030 void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
1031 {
1032 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1033 DH *dh;
1034 struct wpabuf *pubkey = NULL, *privkey = NULL;
1035 size_t publen, privlen;
1036
1037 *priv = NULL;
1038 wpabuf_free(*publ);
1039 *publ = NULL;
1040
1041 dh = DH_new();
1042 if (dh == NULL)
1043 return NULL;
1044
1045 dh->g = BN_new();
1046 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
1047 goto err;
1048
1049 dh->p = get_group5_prime();
1050 if (dh->p == NULL)
1051 goto err;
1052
1053 dh->q = get_group5_order();
1054 if (!dh->q)
1055 goto err;
1056
1057 if (DH_generate_key(dh) != 1)
1058 goto err;
1059
1060 publen = BN_num_bytes(dh->pub_key);
1061 pubkey = wpabuf_alloc(publen);
1062 if (pubkey == NULL)
1063 goto err;
1064 privlen = BN_num_bytes(dh->priv_key);
1065 privkey = wpabuf_alloc(privlen);
1066 if (privkey == NULL)
1067 goto err;
1068
1069 BN_bn2bin(dh->pub_key, wpabuf_put(pubkey, publen));
1070 BN_bn2bin(dh->priv_key, wpabuf_put(privkey, privlen));
1071
1072 *priv = privkey;
1073 *publ = pubkey;
1074 return dh;
1075
1076 err:
1077 wpabuf_clear_free(pubkey);
1078 wpabuf_clear_free(privkey);
1079 DH_free(dh);
1080 return NULL;
1081 #elif OPENSSL_VERSION_NUMBER >= 0x30000000L
1082 EVP_PKEY *pkey = NULL;
1083 OSSL_PARAM params[2];
1084 size_t pub_len = OSSL_PARAM_UNMODIFIED;
1085 size_t priv_len;
1086 struct wpabuf *pubkey = NULL, *privkey = NULL;
1087 BIGNUM *priv_bn = NULL;
1088 EVP_PKEY_CTX *gctx;
1089 const char *propquery = NULL;
1090
1091 *priv = NULL;
1092 wpabuf_free(*publ);
1093 *publ = NULL;
1094
1095 if (OSSL_PROVIDER_available(NULL, "fips")) {
1096 openssl_disable_fips();
1097 openssl_load_default_provider_if_fips();
1098 propquery = "provider!=fips";
1099 }
1100
1101 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
1102 "modp_1536", 0);
1103 params[1] = OSSL_PARAM_construct_end();
1104
1105 gctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", propquery);
1106 if (!gctx ||
1107 EVP_PKEY_keygen_init(gctx) != 1 ||
1108 EVP_PKEY_CTX_set_params(gctx, params) != 1 ||
1109 EVP_PKEY_generate(gctx, &pkey) != 1 ||
1110 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
1111 &priv_bn) != 1 ||
1112 EVP_PKEY_get_octet_string_param(pkey,
1113 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
1114 NULL, 0, &pub_len) < 0 ||
1115 pub_len == OSSL_PARAM_UNMODIFIED ||
1116 (priv_len = BN_num_bytes(priv_bn)) == 0 ||
1117 !(pubkey = wpabuf_alloc(pub_len)) ||
1118 !(privkey = wpabuf_alloc(priv_len)) ||
1119 EVP_PKEY_get_octet_string_param(pkey,
1120 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
1121 wpabuf_put(pubkey, pub_len),
1122 pub_len, NULL) != 1) {
1123 wpa_printf(MSG_INFO, "OpenSSL: failed: %s",
1124 ERR_error_string(ERR_get_error(), NULL));
1125 wpabuf_free(pubkey);
1126 wpabuf_clear_free(privkey);
1127 EVP_PKEY_free(pkey);
1128 pkey = NULL;
1129 } else {
1130 BN_bn2bin(priv_bn, wpabuf_put(privkey, priv_len));
1131
1132 *priv = privkey;
1133 *publ = pubkey;
1134 }
1135
1136 BN_clear_free(priv_bn);
1137 EVP_PKEY_CTX_free(gctx);
1138 return pkey;
1139 #else
1140 DH *dh;
1141 struct wpabuf *pubkey = NULL, *privkey = NULL;
1142 size_t publen, privlen;
1143 BIGNUM *p, *g, *q;
1144 const BIGNUM *priv_key = NULL, *pub_key = NULL;
1145
1146 *priv = NULL;
1147 wpabuf_free(*publ);
1148 *publ = NULL;
1149
1150 dh = DH_new();
1151 if (dh == NULL)
1152 return NULL;
1153
1154 g = BN_new();
1155 p = get_group5_prime();
1156 q = get_group5_order();
1157 if (!g || BN_set_word(g, 2) != 1 || !p || !q ||
1158 DH_set0_pqg(dh, p, q, g) != 1)
1159 goto err;
1160 p = NULL;
1161 q = NULL;
1162 g = NULL;
1163
1164 if (DH_generate_key(dh) != 1)
1165 goto err;
1166
1167 DH_get0_key(dh, &pub_key, &priv_key);
1168 publen = BN_num_bytes(pub_key);
1169 pubkey = wpabuf_alloc(publen);
1170 if (!pubkey)
1171 goto err;
1172 privlen = BN_num_bytes(priv_key);
1173 privkey = wpabuf_alloc(privlen);
1174 if (!privkey)
1175 goto err;
1176
1177 BN_bn2bin(pub_key, wpabuf_put(pubkey, publen));
1178 BN_bn2bin(priv_key, wpabuf_put(privkey, privlen));
1179
1180 *priv = privkey;
1181 *publ = pubkey;
1182 return dh;
1183
1184 err:
1185 BN_free(p);
1186 BN_free(q);
1187 BN_free(g);
1188 wpabuf_clear_free(pubkey);
1189 wpabuf_clear_free(privkey);
1190 DH_free(dh);
1191 return NULL;
1192 #endif
1193 }
1194
1195
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)1196 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
1197 {
1198 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1199 DH *dh;
1200
1201 dh = DH_new();
1202 if (dh == NULL)
1203 return NULL;
1204
1205 dh->g = BN_new();
1206 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
1207 goto err;
1208
1209 dh->p = get_group5_prime();
1210 if (dh->p == NULL)
1211 goto err;
1212
1213 dh->priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
1214 if (dh->priv_key == NULL)
1215 goto err;
1216
1217 dh->pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
1218 if (dh->pub_key == NULL)
1219 goto err;
1220
1221 if (DH_generate_key(dh) != 1)
1222 goto err;
1223
1224 return dh;
1225
1226 err:
1227 DH_free(dh);
1228 return NULL;
1229 #elif OPENSSL_VERSION_NUMBER >= 0x30000000L
1230 EVP_PKEY *pkey = NULL;
1231 OSSL_PARAM_BLD *bld;
1232 OSSL_PARAM *params = NULL;
1233 BIGNUM *priv_key, *pub_key;
1234 EVP_PKEY_CTX *fctx;
1235
1236 fctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);
1237 priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
1238 pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
1239 bld = OSSL_PARAM_BLD_new();
1240 if (!fctx || !priv_key || !pub_key || !bld ||
1241 OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1242 "modp_1536", 0) != 1 ||
1243 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY,
1244 priv_key) != 1 ||
1245 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY,
1246 pub_key) != 1 ||
1247 !(params = OSSL_PARAM_BLD_to_param(bld)) ||
1248 EVP_PKEY_fromdata_init(fctx) != 1 ||
1249 EVP_PKEY_fromdata(fctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) {
1250 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_fromdata failed: %s",
1251 ERR_error_string(ERR_get_error(), NULL));
1252 EVP_PKEY_free(pkey);
1253 pkey = NULL;
1254 }
1255
1256 BN_clear_free(priv_key);
1257 BN_free(pub_key);
1258 EVP_PKEY_CTX_free(fctx);
1259 OSSL_PARAM_BLD_free(bld);
1260 OSSL_PARAM_free(params);
1261 return pkey;
1262 #else
1263 DH *dh;
1264 BIGNUM *p = NULL, *g, *priv_key = NULL, *pub_key = NULL;
1265
1266 dh = DH_new();
1267 if (dh == NULL)
1268 return NULL;
1269
1270 g = BN_new();
1271 p = get_group5_prime();
1272 if (!g || BN_set_word(g, 2) != 1 || !p ||
1273 DH_set0_pqg(dh, p, NULL, g) != 1)
1274 goto err;
1275 p = NULL;
1276 g = NULL;
1277
1278 priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
1279 pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
1280 if (!priv_key || !pub_key || DH_set0_key(dh, pub_key, priv_key) != 1)
1281 goto err;
1282 pub_key = NULL;
1283 priv_key = NULL;
1284
1285 if (DH_generate_key(dh) != 1)
1286 goto err;
1287
1288 return dh;
1289
1290 err:
1291 BN_free(p);
1292 BN_free(g);
1293 BN_free(pub_key);
1294 BN_clear_free(priv_key);
1295 DH_free(dh);
1296 return NULL;
1297 #endif
1298 }
1299
1300
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)1301 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
1302 const struct wpabuf *own_private)
1303 {
1304 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1305 EVP_PKEY *pkey = ctx;
1306 EVP_PKEY *peer_pub;
1307 size_t len;
1308 struct wpabuf *res = NULL;
1309 EVP_PKEY_CTX *dctx = NULL;
1310
1311 peer_pub = EVP_PKEY_new();
1312 if (!pkey || !peer_pub ||
1313 EVP_PKEY_copy_parameters(peer_pub, pkey) != 1 ||
1314 EVP_PKEY_set1_encoded_public_key(peer_pub, wpabuf_head(peer_public),
1315 wpabuf_len(peer_public)) != 1 ||
1316 !(dctx = EVP_PKEY_CTX_new(pkey, NULL)) ||
1317 EVP_PKEY_derive_init(dctx) != 1 ||
1318 EVP_PKEY_derive_set_peer(dctx, peer_pub) != 1 ||
1319 EVP_PKEY_derive(dctx, NULL, &len) != 1 ||
1320 !(res = wpabuf_alloc(len)) ||
1321 EVP_PKEY_derive(dctx, wpabuf_mhead(res), &len) != 1) {
1322 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_derive failed: %s",
1323 ERR_error_string(ERR_get_error(), NULL));
1324 wpabuf_free(res);
1325 res = NULL;
1326 } else {
1327 wpabuf_put(res, len);
1328 }
1329
1330 EVP_PKEY_free(peer_pub);
1331 EVP_PKEY_CTX_free(dctx);
1332 return res;
1333 #else /* OpenSSL version >= 3.0 */
1334 BIGNUM *pub_key;
1335 struct wpabuf *res = NULL;
1336 size_t rlen;
1337 DH *dh = ctx;
1338 int keylen;
1339
1340 if (ctx == NULL)
1341 return NULL;
1342
1343 pub_key = BN_bin2bn(wpabuf_head(peer_public), wpabuf_len(peer_public),
1344 NULL);
1345 if (pub_key == NULL)
1346 return NULL;
1347
1348 rlen = DH_size(dh);
1349 res = wpabuf_alloc(rlen);
1350 if (res == NULL)
1351 goto err;
1352
1353 keylen = DH_compute_key(wpabuf_mhead(res), pub_key, dh);
1354 if (keylen < 0)
1355 goto err;
1356 wpabuf_put(res, keylen);
1357 BN_clear_free(pub_key);
1358
1359 return res;
1360
1361 err:
1362 BN_clear_free(pub_key);
1363 wpabuf_clear_free(res);
1364 return NULL;
1365 #endif /* OpenSSL version >= 3.0 */
1366 }
1367
1368
dh5_free(void * ctx)1369 void dh5_free(void *ctx)
1370 {
1371 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1372 EVP_PKEY *pkey = ctx;
1373
1374 EVP_PKEY_free(pkey);
1375 #else /* OpenSSL version >= 3.0 */
1376 DH *dh;
1377 if (ctx == NULL)
1378 return;
1379 dh = ctx;
1380 DH_free(dh);
1381 #endif /* OpenSSL version >= 3.0 */
1382 }
1383
1384
1385 struct crypto_hash {
1386 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1387 EVP_MAC_CTX *ctx;
1388 #else /* OpenSSL version >= 3.0 */
1389 HMAC_CTX *ctx;
1390 #endif /* OpenSSL version >= 3.0 */
1391 bool failed;
1392 };
1393
1394
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)1395 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
1396 size_t key_len)
1397 {
1398 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1399 struct crypto_hash *ctx;
1400 EVP_MAC *mac;
1401 OSSL_PARAM params[2];
1402 char *a = NULL;
1403
1404 switch (alg) {
1405 #ifndef OPENSSL_NO_MD5
1406 case CRYPTO_HASH_ALG_HMAC_MD5:
1407 a = "MD5";
1408 break;
1409 #endif /* OPENSSL_NO_MD5 */
1410 #ifndef OPENSSL_NO_SHA
1411 case CRYPTO_HASH_ALG_HMAC_SHA1:
1412 a = "SHA1";
1413 break;
1414 #endif /* OPENSSL_NO_SHA */
1415 #ifndef OPENSSL_NO_SHA256
1416 #ifdef CONFIG_SHA256
1417 case CRYPTO_HASH_ALG_HMAC_SHA256:
1418 a = "SHA256";
1419 break;
1420 #endif /* CONFIG_SHA256 */
1421 #endif /* OPENSSL_NO_SHA256 */
1422 default:
1423 return NULL;
1424 }
1425
1426 mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
1427 if (!mac)
1428 return NULL;
1429
1430 params[0] = OSSL_PARAM_construct_utf8_string("digest", a, 0);
1431 params[1] = OSSL_PARAM_construct_end();
1432
1433 ctx = os_zalloc(sizeof(*ctx));
1434 if (!ctx)
1435 goto fail;
1436 ctx->ctx = EVP_MAC_CTX_new(mac);
1437 if (!ctx->ctx) {
1438 os_free(ctx);
1439 ctx = NULL;
1440 goto fail;
1441 }
1442
1443 if (EVP_MAC_init(ctx->ctx, key, key_len, params) != 1) {
1444 wpa_printf(MSG_INFO,
1445 "OpenSSL: EVP_MAC_init(hmac,digest=%s) failed: %s",
1446 a, ERR_error_string(ERR_get_error(), NULL));
1447 EVP_MAC_CTX_free(ctx->ctx);
1448 bin_clear_free(ctx, sizeof(*ctx));
1449 ctx = NULL;
1450 goto fail;
1451 }
1452
1453 fail:
1454 EVP_MAC_free(mac);
1455 return ctx;
1456 #else /* OpenSSL version >= 3.0 */
1457 struct crypto_hash *ctx;
1458 const EVP_MD *md;
1459
1460 switch (alg) {
1461 #ifndef OPENSSL_NO_MD5
1462 case CRYPTO_HASH_ALG_HMAC_MD5:
1463 md = EVP_md5();
1464 break;
1465 #endif /* OPENSSL_NO_MD5 */
1466 #ifndef OPENSSL_NO_SHA
1467 case CRYPTO_HASH_ALG_HMAC_SHA1:
1468 md = EVP_sha1();
1469 break;
1470 #endif /* OPENSSL_NO_SHA */
1471 #ifndef OPENSSL_NO_SHA256
1472 #ifdef CONFIG_SHA256
1473 case CRYPTO_HASH_ALG_HMAC_SHA256:
1474 md = EVP_sha256();
1475 break;
1476 #endif /* CONFIG_SHA256 */
1477 #endif /* OPENSSL_NO_SHA256 */
1478 default:
1479 return NULL;
1480 }
1481
1482 ctx = os_zalloc(sizeof(*ctx));
1483 if (ctx == NULL)
1484 return NULL;
1485 ctx->ctx = HMAC_CTX_new();
1486 if (!ctx->ctx) {
1487 os_free(ctx);
1488 return NULL;
1489 }
1490
1491 if (HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL) != 1) {
1492 HMAC_CTX_free(ctx->ctx);
1493 bin_clear_free(ctx, sizeof(*ctx));
1494 return NULL;
1495 }
1496
1497 return ctx;
1498 #endif /* OpenSSL version >= 3.0 */
1499 }
1500
1501
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)1502 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
1503 {
1504 if (ctx == NULL)
1505 return;
1506 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1507 if (!EVP_MAC_update(ctx->ctx, data, len))
1508 ctx->failed = true;
1509 #else /* OpenSSL version >= 3.0 */
1510 if (!HMAC_Update(ctx->ctx, data, len))
1511 ctx->failed = true;
1512 #endif /* OpenSSL version >= 3.0 */
1513 }
1514
1515
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)1516 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
1517 {
1518 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1519 size_t mdlen;
1520 int res;
1521 bool failed;
1522
1523 if (!ctx)
1524 return -2;
1525
1526 if (!mac || !len) {
1527 EVP_MAC_CTX_free(ctx->ctx);
1528 bin_clear_free(ctx, sizeof(*ctx));
1529 return 0;
1530 }
1531
1532 res = EVP_MAC_final(ctx->ctx, NULL, &mdlen, 0);
1533 if (res != 1) {
1534 EVP_MAC_CTX_free(ctx->ctx);
1535 bin_clear_free(ctx, sizeof(*ctx));
1536 return -1;
1537 }
1538 res = EVP_MAC_final(ctx->ctx, mac, &mdlen, mdlen);
1539 EVP_MAC_CTX_free(ctx->ctx);
1540 failed = ctx->failed;
1541 bin_clear_free(ctx, sizeof(*ctx));
1542
1543 if (TEST_FAIL())
1544 return -1;
1545
1546 if (failed)
1547 return -2;
1548
1549 if (res == 1) {
1550 *len = mdlen;
1551 return 0;
1552 }
1553
1554 return -1;
1555 #else /* OpenSSL version >= 3.0 */
1556 unsigned int mdlen;
1557 int res;
1558 bool failed;
1559
1560 if (ctx == NULL)
1561 return -2;
1562
1563 if (mac == NULL || len == NULL) {
1564 HMAC_CTX_free(ctx->ctx);
1565 bin_clear_free(ctx, sizeof(*ctx));
1566 return 0;
1567 }
1568
1569 mdlen = *len;
1570 res = HMAC_Final(ctx->ctx, mac, &mdlen);
1571 HMAC_CTX_free(ctx->ctx);
1572 failed = ctx->failed;
1573 bin_clear_free(ctx, sizeof(*ctx));
1574
1575 if (TEST_FAIL())
1576 return -1;
1577
1578 if (failed)
1579 return -2;
1580
1581 if (res == 1) {
1582 *len = mdlen;
1583 return 0;
1584 }
1585
1586 return -1;
1587 #endif /* OpenSSL version >= 3.0 */
1588 }
1589
1590
1591 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1592
openssl_hmac_vector(char * digest,const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,unsigned int mdlen)1593 static int openssl_hmac_vector(char *digest, const u8 *key,
1594 size_t key_len, size_t num_elem,
1595 const u8 *addr[], const size_t *len, u8 *mac,
1596 unsigned int mdlen)
1597 {
1598 EVP_MAC *hmac;
1599 OSSL_PARAM params[2];
1600 EVP_MAC_CTX *ctx;
1601 size_t i, mlen;
1602 int res;
1603 const char *property_query = NULL;
1604
1605 if (TEST_FAIL())
1606 return -1;
1607
1608 #ifndef CONFIG_FIPS
1609 if (os_strcmp(digest, "MD5") == 0) {
1610 openssl_need_md5();
1611 property_query = "provider!=fips";
1612 } else if (key_len < 14 && OSSL_PROVIDER_available(NULL, "fips")) {
1613 /* Need to use non-FIPS provider in OpenSSL to handle cases
1614 * where HMAC is used with salt that is less than 112 bits
1615 * instead of the HMAC uses with an actual key. */
1616 openssl_disable_fips();
1617 openssl_load_default_provider_if_fips();
1618 property_query = "provider!=fips";
1619 }
1620 #endif /* CONFIG_FIPS */
1621 hmac = EVP_MAC_fetch(NULL, "HMAC", property_query);
1622 if (!hmac) {
1623 wpa_printf(MSG_INFO, "OpenSSL: EVP_MAC_fetch(HMAC) failed: %s",
1624 ERR_error_string(ERR_get_error(), NULL));
1625 return -1;
1626 }
1627
1628 params[0] = OSSL_PARAM_construct_utf8_string("digest", digest, 0);
1629 params[1] = OSSL_PARAM_construct_end();
1630
1631 ctx = EVP_MAC_CTX_new(hmac);
1632 EVP_MAC_free(hmac);
1633 if (!ctx)
1634 return -1;
1635
1636 if (EVP_MAC_init(ctx, key, key_len, params) != 1) {
1637 wpa_printf(MSG_INFO,
1638 "OpenSSL: EVP_MAC_init(hmac,digest=%s,key_len=%zu) failed: %s",
1639 digest, key_len,
1640 ERR_error_string(ERR_get_error(), NULL));
1641 goto fail;
1642 }
1643
1644 for (i = 0; i < num_elem; i++) {
1645 if (EVP_MAC_update(ctx, addr[i], len[i]) != 1)
1646 goto fail;
1647 }
1648
1649 res = EVP_MAC_final(ctx, mac, &mlen, mdlen);
1650 EVP_MAC_CTX_free(ctx);
1651
1652 return res == 1 ? 0 : -1;
1653 fail:
1654 EVP_MAC_CTX_free(ctx);
1655 return -1;
1656 }
1657
1658
1659 #ifndef CONFIG_FIPS
1660
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1661 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
1662 const u8 *addr[], const size_t *len, u8 *mac)
1663 {
1664 return openssl_hmac_vector("MD5", key ,key_len, num_elem, addr, len,
1665 mac, 16);
1666 }
1667
1668
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1669 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1670 u8 *mac)
1671 {
1672 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
1673 }
1674
1675 #endif /* CONFIG_FIPS */
1676
1677
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1678 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
1679 const u8 *addr[], const size_t *len, u8 *mac)
1680 {
1681 return openssl_hmac_vector("SHA1", key, key_len, num_elem, addr,
1682 len, mac, 20);
1683 }
1684
1685
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1686 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1687 u8 *mac)
1688 {
1689 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
1690 }
1691
1692
1693 #ifdef CONFIG_SHA256
1694
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1695 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
1696 const u8 *addr[], const size_t *len, u8 *mac)
1697 {
1698 return openssl_hmac_vector("SHA256", key, key_len, num_elem, addr,
1699 len, mac, 32);
1700 }
1701
1702
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1703 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
1704 size_t data_len, u8 *mac)
1705 {
1706 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
1707 }
1708
1709 #endif /* CONFIG_SHA256 */
1710
1711
1712 #ifdef CONFIG_SHA384
1713
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1714 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
1715 const u8 *addr[], const size_t *len, u8 *mac)
1716 {
1717 return openssl_hmac_vector("SHA384", key, key_len, num_elem, addr,
1718 len, mac, 48);
1719 }
1720
1721
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1722 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
1723 size_t data_len, u8 *mac)
1724 {
1725 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
1726 }
1727
1728 #endif /* CONFIG_SHA384 */
1729
1730
1731 #ifdef CONFIG_SHA512
1732
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1733 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
1734 const u8 *addr[], const size_t *len, u8 *mac)
1735 {
1736 return openssl_hmac_vector("SHA512", key, key_len, num_elem, addr,
1737 len, mac, 64);
1738 }
1739
1740
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1741 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
1742 size_t data_len, u8 *mac)
1743 {
1744 return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
1745 }
1746
1747 #endif /* CONFIG_SHA512 */
1748
1749 #else /* OpenSSL version >= 3.0 */
1750
openssl_hmac_vector(const EVP_MD * type,const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,unsigned int mdlen)1751 static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
1752 size_t key_len, size_t num_elem,
1753 const u8 *addr[], const size_t *len, u8 *mac,
1754 unsigned int mdlen)
1755 {
1756 HMAC_CTX *ctx;
1757 size_t i;
1758 int res;
1759
1760 if (TEST_FAIL())
1761 return -1;
1762
1763 ctx = HMAC_CTX_new();
1764 if (!ctx)
1765 return -1;
1766 res = HMAC_Init_ex(ctx, key, key_len, type, NULL);
1767 if (res != 1)
1768 goto done;
1769
1770 for (i = 0; i < num_elem; i++)
1771 HMAC_Update(ctx, addr[i], len[i]);
1772
1773 res = HMAC_Final(ctx, mac, &mdlen);
1774 done:
1775 HMAC_CTX_free(ctx);
1776
1777 return res == 1 ? 0 : -1;
1778 }
1779
1780
1781 #ifndef CONFIG_FIPS
1782
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1783 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
1784 const u8 *addr[], const size_t *len, u8 *mac)
1785 {
1786 return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
1787 mac, 16);
1788 }
1789
1790
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1791 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1792 u8 *mac)
1793 {
1794 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
1795 }
1796
1797 #endif /* CONFIG_FIPS */
1798
1799
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1800 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
1801 const u8 *addr[], const size_t *len, u8 *mac)
1802 {
1803 return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
1804 len, mac, 20);
1805 }
1806
1807
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1808 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1809 u8 *mac)
1810 {
1811 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
1812 }
1813
1814
1815 #ifdef CONFIG_SHA256
1816
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1817 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
1818 const u8 *addr[], const size_t *len, u8 *mac)
1819 {
1820 return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
1821 len, mac, 32);
1822 }
1823
1824
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1825 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
1826 size_t data_len, u8 *mac)
1827 {
1828 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
1829 }
1830
1831 #endif /* CONFIG_SHA256 */
1832
1833
1834 #ifdef CONFIG_SHA384
1835
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1836 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
1837 const u8 *addr[], const size_t *len, u8 *mac)
1838 {
1839 return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
1840 len, mac, 48);
1841 }
1842
1843
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1844 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
1845 size_t data_len, u8 *mac)
1846 {
1847 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
1848 }
1849
1850 #endif /* CONFIG_SHA384 */
1851
1852
1853 #ifdef CONFIG_SHA512
1854
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1855 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
1856 const u8 *addr[], const size_t *len, u8 *mac)
1857 {
1858 return openssl_hmac_vector(EVP_sha512(), key, key_len, num_elem, addr,
1859 len, mac, 64);
1860 }
1861
1862
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)1863 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
1864 size_t data_len, u8 *mac)
1865 {
1866 return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
1867 }
1868
1869 #endif /* CONFIG_SHA512 */
1870
1871 #endif /* OpenSSL version >= 3.0 */
1872
1873
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)1874 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
1875 int iterations, u8 *buf, size_t buflen)
1876 {
1877 if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
1878 ssid_len, iterations, buflen, buf) != 1)
1879 return -1;
1880 return 0;
1881 }
1882
1883
crypto_get_random(void * buf,size_t len)1884 int crypto_get_random(void *buf, size_t len)
1885 {
1886 if (RAND_bytes(buf, len) != 1)
1887 return -1;
1888 return 0;
1889 }
1890
1891
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1892 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1893 const u8 *addr[], const size_t *len, u8 *mac)
1894 {
1895 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1896 EVP_MAC_CTX *ctx = NULL;
1897 EVP_MAC *emac;
1898 int ret = -1;
1899 size_t outlen, i;
1900 OSSL_PARAM params[2];
1901 char *cipher = NULL;
1902
1903 if (TEST_FAIL())
1904 return -1;
1905
1906 emac = EVP_MAC_fetch(NULL, "CMAC", NULL);
1907
1908 if (key_len == 32)
1909 cipher = "aes-256-cbc";
1910 else if (key_len == 24)
1911 cipher = "aes-192-cbc";
1912 else if (key_len == 16)
1913 cipher = "aes-128-cbc";
1914
1915 params[0] = OSSL_PARAM_construct_utf8_string("cipher", cipher, 0);
1916 params[1] = OSSL_PARAM_construct_end();
1917
1918 if (!emac || !cipher ||
1919 !(ctx = EVP_MAC_CTX_new(emac)) ||
1920 EVP_MAC_init(ctx, key, key_len, params) != 1) {
1921 wpa_printf(MSG_INFO,
1922 "OpenSSL: EVP_MAC_init(cmac,cipher=%s) failed: %s",
1923 cipher, ERR_error_string(ERR_get_error(), NULL));
1924 goto fail;
1925 }
1926
1927 for (i = 0; i < num_elem; i++) {
1928 if (!EVP_MAC_update(ctx, addr[i], len[i]))
1929 goto fail;
1930 }
1931 if (EVP_MAC_final(ctx, mac, &outlen, 16) != 1 || outlen != 16)
1932 goto fail;
1933
1934 ret = 0;
1935 fail:
1936 EVP_MAC_CTX_free(ctx);
1937 EVP_MAC_free(emac);
1938 return ret;
1939 #else /* OpenSSL version >= 3.0 */
1940 CMAC_CTX *ctx;
1941 int ret = -1;
1942 size_t outlen, i;
1943
1944 if (TEST_FAIL())
1945 return -1;
1946
1947 ctx = CMAC_CTX_new();
1948 if (ctx == NULL)
1949 return -1;
1950
1951 if (key_len == 32) {
1952 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
1953 goto fail;
1954 } else if (key_len == 24) {
1955 if (!CMAC_Init(ctx, key, 24, EVP_aes_192_cbc(), NULL))
1956 goto fail;
1957 } else if (key_len == 16) {
1958 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
1959 goto fail;
1960 } else {
1961 goto fail;
1962 }
1963 for (i = 0; i < num_elem; i++) {
1964 if (!CMAC_Update(ctx, addr[i], len[i]))
1965 goto fail;
1966 }
1967 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
1968 goto fail;
1969
1970 ret = 0;
1971 fail:
1972 CMAC_CTX_free(ctx);
1973 return ret;
1974 #endif /* OpenSSL version >= 3.0 */
1975 }
1976
1977
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1978 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1979 const u8 *addr[], const size_t *len, u8 *mac)
1980 {
1981 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1982 }
1983
1984
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1985 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1986 {
1987 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1988 }
1989
1990
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1991 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1992 {
1993 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1994 }
1995
1996
crypto_bignum_init(void)1997 struct crypto_bignum * crypto_bignum_init(void)
1998 {
1999 if (TEST_FAIL())
2000 return NULL;
2001 return (struct crypto_bignum *) BN_new();
2002 }
2003
2004
crypto_bignum_init_set(const u8 * buf,size_t len)2005 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
2006 {
2007 BIGNUM *bn;
2008
2009 if (TEST_FAIL())
2010 return NULL;
2011
2012 bn = BN_bin2bn(buf, len, NULL);
2013 return (struct crypto_bignum *) bn;
2014 }
2015
2016
crypto_bignum_init_uint(unsigned int val)2017 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
2018 {
2019 BIGNUM *bn;
2020
2021 if (TEST_FAIL())
2022 return NULL;
2023
2024 bn = BN_new();
2025 if (!bn)
2026 return NULL;
2027 if (BN_set_word(bn, val) != 1) {
2028 BN_free(bn);
2029 return NULL;
2030 }
2031 return (struct crypto_bignum *) bn;
2032 }
2033
2034
crypto_bignum_deinit(struct crypto_bignum * n,int clear)2035 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
2036 {
2037 if (clear)
2038 BN_clear_free((BIGNUM *) n);
2039 else
2040 BN_free((BIGNUM *) n);
2041 }
2042
2043
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)2044 int crypto_bignum_to_bin(const struct crypto_bignum *a,
2045 u8 *buf, size_t buflen, size_t padlen)
2046 {
2047 int num_bytes, offset;
2048
2049 if (TEST_FAIL())
2050 return -1;
2051
2052 if (padlen > buflen)
2053 return -1;
2054
2055 if (padlen) {
2056 #ifdef OPENSSL_IS_BORINGSSL
2057 if (BN_bn2bin_padded(buf, padlen, (const BIGNUM *) a) == 0)
2058 return -1;
2059 return padlen;
2060 #else /* OPENSSL_IS_BORINGSSL */
2061 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
2062 return BN_bn2binpad((const BIGNUM *) a, buf, padlen);
2063 #endif
2064 #endif
2065 }
2066
2067 num_bytes = BN_num_bytes((const BIGNUM *) a);
2068 if ((size_t) num_bytes > buflen)
2069 return -1;
2070 if (padlen > (size_t) num_bytes)
2071 offset = padlen - num_bytes;
2072 else
2073 offset = 0;
2074
2075 os_memset(buf, 0, offset);
2076 BN_bn2bin((const BIGNUM *) a, buf + offset);
2077
2078 return num_bytes + offset;
2079 }
2080
2081
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)2082 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
2083 {
2084 if (TEST_FAIL())
2085 return -1;
2086 return BN_rand_range((BIGNUM *) r, (const BIGNUM *) m) == 1 ? 0 : -1;
2087 }
2088
2089
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2090 int crypto_bignum_add(const struct crypto_bignum *a,
2091 const struct crypto_bignum *b,
2092 struct crypto_bignum *c)
2093 {
2094 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
2095 0 : -1;
2096 }
2097
2098
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2099 int crypto_bignum_mod(const struct crypto_bignum *a,
2100 const struct crypto_bignum *b,
2101 struct crypto_bignum *c)
2102 {
2103 int res;
2104 BN_CTX *bnctx;
2105
2106 bnctx = BN_CTX_new();
2107 if (bnctx == NULL)
2108 return -1;
2109 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
2110 bnctx);
2111 BN_CTX_free(bnctx);
2112
2113 return res ? 0 : -1;
2114 }
2115
2116
crypto_bignum_exptmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2117 int crypto_bignum_exptmod(const struct crypto_bignum *a,
2118 const struct crypto_bignum *b,
2119 const struct crypto_bignum *c,
2120 struct crypto_bignum *d)
2121 {
2122 int res;
2123 BN_CTX *bnctx;
2124
2125 if (TEST_FAIL())
2126 return -1;
2127
2128 bnctx = BN_CTX_new();
2129 if (bnctx == NULL)
2130 return -1;
2131 res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
2132 (const BIGNUM *) b, (const BIGNUM *) c,
2133 bnctx, NULL);
2134 BN_CTX_free(bnctx);
2135
2136 return res ? 0 : -1;
2137 }
2138
2139
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2140 int crypto_bignum_inverse(const struct crypto_bignum *a,
2141 const struct crypto_bignum *b,
2142 struct crypto_bignum *c)
2143 {
2144 BIGNUM *res;
2145 BN_CTX *bnctx;
2146
2147 if (TEST_FAIL())
2148 return -1;
2149 bnctx = BN_CTX_new();
2150 if (bnctx == NULL)
2151 return -1;
2152 #ifdef OPENSSL_IS_BORINGSSL
2153 /* TODO: use BN_mod_inverse_blinded() ? */
2154 #else /* OPENSSL_IS_BORINGSSL */
2155 BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
2156 #endif /* OPENSSL_IS_BORINGSSL */
2157 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
2158 (const BIGNUM *) b, bnctx);
2159 BN_CTX_free(bnctx);
2160
2161 return res ? 0 : -1;
2162 }
2163
2164
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2165 int crypto_bignum_sub(const struct crypto_bignum *a,
2166 const struct crypto_bignum *b,
2167 struct crypto_bignum *c)
2168 {
2169 if (TEST_FAIL())
2170 return -1;
2171 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
2172 0 : -1;
2173 }
2174
2175
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2176 int crypto_bignum_div(const struct crypto_bignum *a,
2177 const struct crypto_bignum *b,
2178 struct crypto_bignum *c)
2179 {
2180 int res;
2181
2182 BN_CTX *bnctx;
2183
2184 if (TEST_FAIL())
2185 return -1;
2186
2187 bnctx = BN_CTX_new();
2188 if (bnctx == NULL)
2189 return -1;
2190 #ifndef OPENSSL_IS_BORINGSSL
2191 BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
2192 #endif /* OPENSSL_IS_BORINGSSL */
2193 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
2194 (const BIGNUM *) b, bnctx);
2195 BN_CTX_free(bnctx);
2196
2197 return res ? 0 : -1;
2198 }
2199
2200
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2201 int crypto_bignum_addmod(const struct crypto_bignum *a,
2202 const struct crypto_bignum *b,
2203 const struct crypto_bignum *c,
2204 struct crypto_bignum *d)
2205 {
2206 int res;
2207 BN_CTX *bnctx;
2208
2209 if (TEST_FAIL())
2210 return -1;
2211
2212 bnctx = BN_CTX_new();
2213 if (!bnctx)
2214 return -1;
2215 res = BN_mod_add((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
2216 (const BIGNUM *) c, bnctx);
2217 BN_CTX_free(bnctx);
2218
2219 return res ? 0 : -1;
2220 }
2221
2222
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2223 int crypto_bignum_mulmod(const struct crypto_bignum *a,
2224 const struct crypto_bignum *b,
2225 const struct crypto_bignum *c,
2226 struct crypto_bignum *d)
2227 {
2228 int res;
2229
2230 BN_CTX *bnctx;
2231
2232 if (TEST_FAIL())
2233 return -1;
2234
2235 bnctx = BN_CTX_new();
2236 if (bnctx == NULL)
2237 return -1;
2238 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
2239 (const BIGNUM *) c, bnctx);
2240 BN_CTX_free(bnctx);
2241
2242 return res ? 0 : -1;
2243 }
2244
2245
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2246 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
2247 const struct crypto_bignum *b,
2248 struct crypto_bignum *c)
2249 {
2250 int res;
2251 BN_CTX *bnctx;
2252
2253 if (TEST_FAIL())
2254 return -1;
2255
2256 bnctx = BN_CTX_new();
2257 if (!bnctx)
2258 return -1;
2259 res = BN_mod_sqr((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
2260 bnctx);
2261 BN_CTX_free(bnctx);
2262
2263 return res ? 0 : -1;
2264 }
2265
2266
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)2267 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
2268 struct crypto_bignum *r)
2269 {
2270 return BN_rshift((BIGNUM *) r, (const BIGNUM *) a, n) == 1 ? 0 : -1;
2271 }
2272
2273
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)2274 int crypto_bignum_cmp(const struct crypto_bignum *a,
2275 const struct crypto_bignum *b)
2276 {
2277 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
2278 }
2279
2280
crypto_bignum_is_zero(const struct crypto_bignum * a)2281 int crypto_bignum_is_zero(const struct crypto_bignum *a)
2282 {
2283 return BN_is_zero((const BIGNUM *) a);
2284 }
2285
2286
crypto_bignum_is_one(const struct crypto_bignum * a)2287 int crypto_bignum_is_one(const struct crypto_bignum *a)
2288 {
2289 return BN_is_one((const BIGNUM *) a);
2290 }
2291
2292
crypto_bignum_is_odd(const struct crypto_bignum * a)2293 int crypto_bignum_is_odd(const struct crypto_bignum *a)
2294 {
2295 return BN_is_odd((const BIGNUM *) a);
2296 }
2297
2298
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)2299 int crypto_bignum_legendre(const struct crypto_bignum *a,
2300 const struct crypto_bignum *p)
2301 {
2302 BN_CTX *bnctx;
2303 BIGNUM *exp = NULL, *tmp = NULL;
2304 int res = -2;
2305 unsigned int mask;
2306
2307 if (TEST_FAIL())
2308 return -2;
2309
2310 bnctx = BN_CTX_new();
2311 if (bnctx == NULL)
2312 return -2;
2313
2314 exp = BN_new();
2315 tmp = BN_new();
2316 if (!exp || !tmp ||
2317 /* exp = (p-1) / 2 */
2318 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
2319 !BN_rshift1(exp, exp) ||
2320 !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
2321 (const BIGNUM *) p, bnctx, NULL))
2322 goto fail;
2323
2324 /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
2325 * constant time selection to avoid branches here. */
2326 res = -1;
2327 mask = const_time_eq(BN_is_word(tmp, 1), 1);
2328 res = const_time_select_int(mask, 1, res);
2329 mask = const_time_eq(BN_is_zero(tmp), 1);
2330 res = const_time_select_int(mask, 0, res);
2331
2332 fail:
2333 BN_clear_free(tmp);
2334 BN_clear_free(exp);
2335 BN_CTX_free(bnctx);
2336 return res;
2337 }
2338
2339
2340 #ifdef CONFIG_ECC
2341
2342 struct crypto_ec {
2343 EC_GROUP *group;
2344 int nid;
2345 int iana_group;
2346 BN_CTX *bnctx;
2347 BIGNUM *prime;
2348 BIGNUM *order;
2349 BIGNUM *a;
2350 BIGNUM *b;
2351 };
2352
2353
crypto_ec_group_2_nid(int group)2354 static int crypto_ec_group_2_nid(int group)
2355 {
2356 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
2357 switch (group) {
2358 case 19:
2359 return NID_X9_62_prime256v1;
2360 case 20:
2361 return NID_secp384r1;
2362 case 21:
2363 return NID_secp521r1;
2364 case 25:
2365 return NID_X9_62_prime192v1;
2366 case 26:
2367 return NID_secp224r1;
2368 #ifdef NID_brainpoolP224r1
2369 case 27:
2370 return NID_brainpoolP224r1;
2371 #endif /* NID_brainpoolP224r1 */
2372 #ifdef NID_brainpoolP256r1
2373 case 28:
2374 return NID_brainpoolP256r1;
2375 #endif /* NID_brainpoolP256r1 */
2376 #ifdef NID_brainpoolP384r1
2377 case 29:
2378 return NID_brainpoolP384r1;
2379 #endif /* NID_brainpoolP384r1 */
2380 #ifdef NID_brainpoolP512r1
2381 case 30:
2382 return NID_brainpoolP512r1;
2383 #endif /* NID_brainpoolP512r1 */
2384 default:
2385 return -1;
2386 }
2387 }
2388
2389
2390 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
crypto_ec_group_2_name(int group)2391 static const char * crypto_ec_group_2_name(int group)
2392 {
2393 /* Map from IANA registry for IKE D-H groups to OpenSSL group name */
2394 switch (group) {
2395 case 19:
2396 return "prime256v1";
2397 case 20:
2398 return "secp384r1";
2399 case 21:
2400 return "secp521r1";
2401 case 25:
2402 return "prime192v1";
2403 case 26:
2404 return "secp224r1";
2405 #ifdef NID_brainpoolP224r1
2406 case 27:
2407 return "brainpoolP224r1";
2408 #endif /* NID_brainpoolP224r1 */
2409 #ifdef NID_brainpoolP256r1
2410 case 28:
2411 return "brainpoolP256r1";
2412 #endif /* NID_brainpoolP256r1 */
2413 #ifdef NID_brainpoolP384r1
2414 case 29:
2415 return "brainpoolP384r1";
2416 #endif /* NID_brainpoolP384r1 */
2417 #ifdef NID_brainpoolP512r1
2418 case 30:
2419 return "brainpoolP512r1";
2420 #endif /* NID_brainpoolP512r1 */
2421 default:
2422 return NULL;
2423 }
2424 }
2425 #endif /* OpenSSL version >= 3.0 */
2426
2427
crypto_ec_init(int group)2428 struct crypto_ec * crypto_ec_init(int group)
2429 {
2430 struct crypto_ec *e;
2431 int nid;
2432
2433 nid = crypto_ec_group_2_nid(group);
2434 if (nid < 0)
2435 return NULL;
2436
2437 e = os_zalloc(sizeof(*e));
2438 if (e == NULL)
2439 return NULL;
2440
2441 e->nid = nid;
2442 e->iana_group = group;
2443 e->bnctx = BN_CTX_new();
2444 e->group = EC_GROUP_new_by_curve_name(nid);
2445 e->prime = BN_new();
2446 e->order = BN_new();
2447 e->a = BN_new();
2448 e->b = BN_new();
2449 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
2450 e->order == NULL || e->a == NULL || e->b == NULL ||
2451 !EC_GROUP_get_curve(e->group, e->prime, e->a, e->b, e->bnctx) ||
2452 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
2453 crypto_ec_deinit(e);
2454 e = NULL;
2455 }
2456
2457 return e;
2458 }
2459
2460
crypto_ec_deinit(struct crypto_ec * e)2461 void crypto_ec_deinit(struct crypto_ec *e)
2462 {
2463 if (e == NULL)
2464 return;
2465 BN_clear_free(e->b);
2466 BN_clear_free(e->a);
2467 BN_clear_free(e->order);
2468 BN_clear_free(e->prime);
2469 EC_GROUP_free(e->group);
2470 BN_CTX_free(e->bnctx);
2471 os_free(e);
2472 }
2473
2474
crypto_ec_point_init(struct crypto_ec * e)2475 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
2476 {
2477 if (TEST_FAIL())
2478 return NULL;
2479 if (e == NULL)
2480 return NULL;
2481 return (struct crypto_ec_point *) EC_POINT_new(e->group);
2482 }
2483
2484
crypto_ec_prime_len(struct crypto_ec * e)2485 size_t crypto_ec_prime_len(struct crypto_ec *e)
2486 {
2487 return BN_num_bytes(e->prime);
2488 }
2489
2490
crypto_ec_prime_len_bits(struct crypto_ec * e)2491 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
2492 {
2493 return BN_num_bits(e->prime);
2494 }
2495
2496
crypto_ec_order_len(struct crypto_ec * e)2497 size_t crypto_ec_order_len(struct crypto_ec *e)
2498 {
2499 return BN_num_bytes(e->order);
2500 }
2501
2502
crypto_ec_get_prime(struct crypto_ec * e)2503 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
2504 {
2505 return (const struct crypto_bignum *) e->prime;
2506 }
2507
2508
crypto_ec_get_order(struct crypto_ec * e)2509 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
2510 {
2511 return (const struct crypto_bignum *) e->order;
2512 }
2513
2514
crypto_ec_get_a(struct crypto_ec * e)2515 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
2516 {
2517 return (const struct crypto_bignum *) e->a;
2518 }
2519
2520
crypto_ec_get_b(struct crypto_ec * e)2521 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
2522 {
2523 return (const struct crypto_bignum *) e->b;
2524 }
2525
2526
crypto_ec_get_generator(struct crypto_ec * e)2527 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
2528 {
2529 return (const struct crypto_ec_point *)
2530 EC_GROUP_get0_generator(e->group);
2531 }
2532
2533
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)2534 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
2535 {
2536 if (clear)
2537 EC_POINT_clear_free((EC_POINT *) p);
2538 else
2539 EC_POINT_free((EC_POINT *) p);
2540 }
2541
2542
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)2543 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
2544 struct crypto_bignum *x)
2545 {
2546 return EC_POINT_get_affine_coordinates(e->group,
2547 (const EC_POINT *) p,
2548 (BIGNUM *) x, NULL,
2549 e->bnctx) == 1 ? 0 : -1;
2550 }
2551
2552
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)2553 int crypto_ec_point_to_bin(struct crypto_ec *e,
2554 const struct crypto_ec_point *point, u8 *x, u8 *y)
2555 {
2556 BIGNUM *x_bn, *y_bn;
2557 int ret = -1;
2558 int len = BN_num_bytes(e->prime);
2559
2560 if (TEST_FAIL())
2561 return -1;
2562
2563 x_bn = BN_new();
2564 y_bn = BN_new();
2565
2566 if (x_bn && y_bn &&
2567 EC_POINT_get_affine_coordinates(e->group, (EC_POINT *) point,
2568 x_bn, y_bn, e->bnctx)) {
2569 if (x) {
2570 ret = crypto_bignum_to_bin(
2571 (struct crypto_bignum *) x_bn, x, len, len);
2572 }
2573 if (ret >= 0 && y) {
2574 ret = crypto_bignum_to_bin(
2575 (struct crypto_bignum *) y_bn, y, len, len);
2576 }
2577
2578 if (ret > 0)
2579 ret = 0;
2580 }
2581
2582 BN_clear_free(x_bn);
2583 BN_clear_free(y_bn);
2584 return ret;
2585 }
2586
2587
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)2588 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
2589 const u8 *val)
2590 {
2591 BIGNUM *x, *y;
2592 EC_POINT *elem;
2593 int len = BN_num_bytes(e->prime);
2594
2595 if (TEST_FAIL())
2596 return NULL;
2597
2598 x = BN_bin2bn(val, len, NULL);
2599 y = BN_bin2bn(val + len, len, NULL);
2600 elem = EC_POINT_new(e->group);
2601 if (x == NULL || y == NULL || elem == NULL) {
2602 BN_clear_free(x);
2603 BN_clear_free(y);
2604 EC_POINT_clear_free(elem);
2605 return NULL;
2606 }
2607
2608 if (!EC_POINT_set_affine_coordinates(e->group, elem, x, y, e->bnctx)) {
2609 EC_POINT_clear_free(elem);
2610 elem = NULL;
2611 }
2612
2613 BN_clear_free(x);
2614 BN_clear_free(y);
2615
2616 return (struct crypto_ec_point *) elem;
2617 }
2618
2619
crypto_ec_point_add(struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b,struct crypto_ec_point * c)2620 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
2621 const struct crypto_ec_point *b,
2622 struct crypto_ec_point *c)
2623 {
2624 if (TEST_FAIL())
2625 return -1;
2626 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
2627 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
2628 }
2629
2630
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2631 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2632 const struct crypto_bignum *b,
2633 struct crypto_ec_point *res)
2634 {
2635 if (TEST_FAIL())
2636 return -1;
2637 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
2638 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
2639 ? 0 : -1;
2640 }
2641
2642
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2643 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2644 {
2645 if (TEST_FAIL())
2646 return -1;
2647 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
2648 }
2649
2650
2651 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2652 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2653 const struct crypto_bignum *x)
2654 {
2655 BIGNUM *tmp;
2656
2657 if (TEST_FAIL())
2658 return NULL;
2659
2660 tmp = BN_new();
2661
2662 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2663 if (tmp &&
2664 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
2665 BN_mod_add_quick(tmp, e->a, tmp, e->prime) &&
2666 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
2667 BN_mod_add_quick(tmp, tmp, e->b, e->prime))
2668 return (struct crypto_bignum *) tmp;
2669
2670 BN_clear_free(tmp);
2671 return NULL;
2672 }
2673
2674
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2675 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2676 const struct crypto_ec_point *p)
2677 {
2678 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
2679 }
2680
2681
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2682 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2683 const struct crypto_ec_point *p)
2684 {
2685 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
2686 e->bnctx) == 1;
2687 }
2688
2689
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2690 int crypto_ec_point_cmp(const struct crypto_ec *e,
2691 const struct crypto_ec_point *a,
2692 const struct crypto_ec_point *b)
2693 {
2694 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
2695 (const EC_POINT *) b, e->bnctx);
2696 }
2697
2698
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2699 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2700 const struct crypto_ec_point *p,
2701 const char *title)
2702 {
2703 BIGNUM *x, *y;
2704 char *x_str = NULL, *y_str = NULL;
2705
2706 x = BN_new();
2707 y = BN_new();
2708 if (!x || !y ||
2709 EC_POINT_get_affine_coordinates(e->group, (const EC_POINT *) p,
2710 x, y, e->bnctx) != 1)
2711 goto fail;
2712
2713 x_str = BN_bn2hex(x);
2714 y_str = BN_bn2hex(y);
2715 if (!x_str || !y_str)
2716 goto fail;
2717
2718 wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
2719
2720 fail:
2721 OPENSSL_free(x_str);
2722 OPENSSL_free(y_str);
2723 BN_free(x);
2724 BN_free(y);
2725 }
2726
2727
2728 struct crypto_ecdh {
2729 struct crypto_ec *ec;
2730 EVP_PKEY *pkey;
2731 };
2732
crypto_ecdh_init(int group)2733 struct crypto_ecdh * crypto_ecdh_init(int group)
2734 {
2735 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2736 struct crypto_ecdh *ecdh;
2737 const char *name;
2738
2739 ecdh = os_zalloc(sizeof(*ecdh));
2740 if (!ecdh)
2741 goto fail;
2742
2743 ecdh->ec = crypto_ec_init(group);
2744 if (!ecdh->ec)
2745 goto fail;
2746
2747 name = OSSL_EC_curve_nid2name(ecdh->ec->nid);
2748 if (!name)
2749 goto fail;
2750
2751 ecdh->pkey = EVP_EC_gen(name);
2752 if (!ecdh->pkey) {
2753 wpa_printf(MSG_INFO,
2754 "OpenSSL: EVP_EC_gen(group=%d) failed: %s",
2755 group, ERR_error_string(ERR_get_error(), NULL));
2756 goto fail;
2757 }
2758
2759 done:
2760 return ecdh;
2761 fail:
2762 crypto_ecdh_deinit(ecdh);
2763 ecdh = NULL;
2764 goto done;
2765 #else /* OpenSSL version >= 3.0 */
2766 struct crypto_ecdh *ecdh;
2767 EVP_PKEY *params = NULL;
2768 EC_KEY *ec_params = NULL;
2769 EVP_PKEY_CTX *kctx = NULL;
2770
2771 ecdh = os_zalloc(sizeof(*ecdh));
2772 if (!ecdh)
2773 goto fail;
2774
2775 ecdh->ec = crypto_ec_init(group);
2776 if (!ecdh->ec)
2777 goto fail;
2778
2779 ec_params = EC_KEY_new_by_curve_name(ecdh->ec->nid);
2780 if (!ec_params) {
2781 wpa_printf(MSG_ERROR,
2782 "OpenSSL: Failed to generate EC_KEY parameters");
2783 goto fail;
2784 }
2785 EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
2786 params = EVP_PKEY_new();
2787 if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
2788 wpa_printf(MSG_ERROR,
2789 "OpenSSL: Failed to generate EVP_PKEY parameters");
2790 goto fail;
2791 }
2792
2793 kctx = EVP_PKEY_CTX_new(params, NULL);
2794 if (!kctx)
2795 goto fail;
2796
2797 if (EVP_PKEY_keygen_init(kctx) != 1) {
2798 wpa_printf(MSG_ERROR,
2799 "OpenSSL: EVP_PKEY_keygen_init failed: %s",
2800 ERR_error_string(ERR_get_error(), NULL));
2801 goto fail;
2802 }
2803
2804 if (EVP_PKEY_keygen(kctx, &ecdh->pkey) != 1) {
2805 wpa_printf(MSG_ERROR, "OpenSSL: EVP_PKEY_keygen failed: %s",
2806 ERR_error_string(ERR_get_error(), NULL));
2807 goto fail;
2808 }
2809
2810 done:
2811 EC_KEY_free(ec_params);
2812 EVP_PKEY_free(params);
2813 EVP_PKEY_CTX_free(kctx);
2814
2815 return ecdh;
2816 fail:
2817 crypto_ecdh_deinit(ecdh);
2818 ecdh = NULL;
2819 goto done;
2820 #endif /* OpenSSL version >= 3.0 */
2821 }
2822
2823
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2824 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2825 {
2826 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2827 struct crypto_ecdh *ecdh;
2828
2829 ecdh = os_zalloc(sizeof(*ecdh));
2830 if (!ecdh)
2831 goto fail;
2832
2833 ecdh->ec = crypto_ec_init(group);
2834 if (!ecdh->ec)
2835 goto fail;
2836
2837 ecdh->pkey = EVP_PKEY_dup((EVP_PKEY *) own_key);
2838 if (!ecdh->pkey)
2839 goto fail;
2840
2841 return ecdh;
2842 fail:
2843 crypto_ecdh_deinit(ecdh);
2844 return NULL;
2845 #else /* OpenSSL version >= 3.0 */
2846 struct crypto_ecdh *ecdh;
2847
2848 ecdh = os_zalloc(sizeof(*ecdh));
2849 if (!ecdh)
2850 goto fail;
2851
2852 ecdh->ec = crypto_ec_init(group);
2853 if (!ecdh->ec)
2854 goto fail;
2855
2856 ecdh->pkey = EVP_PKEY_new();
2857 if (!ecdh->pkey ||
2858 EVP_PKEY_assign_EC_KEY(ecdh->pkey,
2859 EVP_PKEY_get1_EC_KEY((EVP_PKEY *) own_key))
2860 != 1)
2861 goto fail;
2862
2863 return ecdh;
2864 fail:
2865 crypto_ecdh_deinit(ecdh);
2866 return NULL;
2867 #endif /* OpenSSL version >= 3.0 */
2868 }
2869
2870
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2871 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2872 {
2873 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2874 struct wpabuf *buf = NULL;
2875 unsigned char *pub;
2876 size_t len, exp_len;
2877
2878 len = EVP_PKEY_get1_encoded_public_key(ecdh->pkey, &pub);
2879 if (len == 0)
2880 return NULL;
2881
2882 /* Encoded using SECG SEC 1, Sec. 2.3.4 format */
2883 exp_len = 1 + 2 * crypto_ec_prime_len(ecdh->ec);
2884 if (len != exp_len) {
2885 wpa_printf(MSG_ERROR,
2886 "OpenSSL:%s: Unexpected encoded public key length %zu (expected %zu)",
2887 __func__, len, exp_len);
2888 goto fail;
2889 }
2890 buf = wpabuf_alloc_copy(pub + 1, inc_y ? len - 1 : len / 2);
2891 fail:
2892 OPENSSL_free(pub);
2893 return buf;
2894 #else /* OpenSSL version >= 3.0 */
2895 struct wpabuf *buf = NULL;
2896 EC_KEY *eckey;
2897 const EC_POINT *pubkey;
2898 BIGNUM *x, *y = NULL;
2899 int len = BN_num_bytes(ecdh->ec->prime);
2900 int res;
2901
2902 eckey = EVP_PKEY_get1_EC_KEY(ecdh->pkey);
2903 if (!eckey)
2904 return NULL;
2905
2906 pubkey = EC_KEY_get0_public_key(eckey);
2907 if (!pubkey)
2908 return NULL;
2909
2910 x = BN_new();
2911 if (inc_y) {
2912 y = BN_new();
2913 if (!y)
2914 goto fail;
2915 }
2916 buf = wpabuf_alloc(inc_y ? 2 * len : len);
2917 if (!x || !buf)
2918 goto fail;
2919
2920 if (EC_POINT_get_affine_coordinates(ecdh->ec->group, pubkey,
2921 x, y, ecdh->ec->bnctx) != 1) {
2922 wpa_printf(MSG_ERROR,
2923 "OpenSSL: EC_POINT_get_affine_coordinates failed: %s",
2924 ERR_error_string(ERR_get_error(), NULL));
2925 goto fail;
2926 }
2927
2928 res = crypto_bignum_to_bin((struct crypto_bignum *) x,
2929 wpabuf_put(buf, len), len, len);
2930 if (res < 0)
2931 goto fail;
2932
2933 if (inc_y) {
2934 res = crypto_bignum_to_bin((struct crypto_bignum *) y,
2935 wpabuf_put(buf, len), len, len);
2936 if (res < 0)
2937 goto fail;
2938 }
2939
2940 done:
2941 BN_clear_free(x);
2942 BN_clear_free(y);
2943 EC_KEY_free(eckey);
2944
2945 return buf;
2946 fail:
2947 wpabuf_free(buf);
2948 buf = NULL;
2949 goto done;
2950 #endif /* OpenSSL version >= 3.0 */
2951 }
2952
2953
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2954 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2955 const u8 *key, size_t len)
2956 {
2957 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2958 EVP_PKEY *peerkey = EVP_PKEY_new();
2959 EVP_PKEY_CTX *ctx;
2960 size_t res_len;
2961 struct wpabuf *res = NULL;
2962 u8 *peer;
2963
2964 /* Encode using SECG SEC 1, Sec. 2.3.4 format */
2965 peer = os_malloc(1 + len);
2966 if (!peer) {
2967 EVP_PKEY_free(peerkey);
2968 return NULL;
2969 }
2970 peer[0] = inc_y ? 0x04 : 0x02;
2971 os_memcpy(peer + 1, key, len);
2972
2973 if (!peerkey ||
2974 EVP_PKEY_copy_parameters(peerkey, ecdh->pkey) != 1 ||
2975 EVP_PKEY_set1_encoded_public_key(peerkey, peer, 1 + len) != 1) {
2976 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_set1_encoded_public_key failed: %s",
2977 ERR_error_string(ERR_get_error(), NULL));
2978 EVP_PKEY_free(peerkey);
2979 os_free(peer);
2980 return NULL;
2981 }
2982 os_free(peer);
2983
2984 ctx = EVP_PKEY_CTX_new(ecdh->pkey, NULL);
2985 if (!ctx ||
2986 EVP_PKEY_derive_init(ctx) != 1 ||
2987 EVP_PKEY_derive_set_peer(ctx, peerkey) != 1 ||
2988 EVP_PKEY_derive(ctx, NULL, &res_len) != 1 ||
2989 !(res = wpabuf_alloc(res_len)) ||
2990 EVP_PKEY_derive(ctx, wpabuf_mhead(res), &res_len) != 1) {
2991 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_derive failed: %s",
2992 ERR_error_string(ERR_get_error(), NULL));
2993 wpabuf_free(res);
2994 res = NULL;
2995 } else {
2996 wpabuf_put(res, res_len);
2997 }
2998
2999 EVP_PKEY_free(peerkey);
3000 EVP_PKEY_CTX_free(ctx);
3001 return res;
3002 #else /* OpenSSL version >= 3.0 */
3003 BIGNUM *x, *y = NULL;
3004 EVP_PKEY_CTX *ctx = NULL;
3005 EVP_PKEY *peerkey = NULL;
3006 struct wpabuf *secret = NULL;
3007 size_t secret_len;
3008 EC_POINT *pub;
3009 EC_KEY *eckey = NULL;
3010
3011 x = BN_bin2bn(key, inc_y ? len / 2 : len, NULL);
3012 pub = EC_POINT_new(ecdh->ec->group);
3013 if (!x || !pub)
3014 goto fail;
3015
3016 if (inc_y) {
3017 y = BN_bin2bn(key + len / 2, len / 2, NULL);
3018 if (!y)
3019 goto fail;
3020 if (!EC_POINT_set_affine_coordinates(ecdh->ec->group, pub,
3021 x, y, ecdh->ec->bnctx)) {
3022 wpa_printf(MSG_ERROR,
3023 "OpenSSL: EC_POINT_set_affine_coordinates failed: %s",
3024 ERR_error_string(ERR_get_error(), NULL));
3025 goto fail;
3026 }
3027 } else if (!EC_POINT_set_compressed_coordinates(ecdh->ec->group,
3028 pub, x, 0,
3029 ecdh->ec->bnctx)) {
3030 wpa_printf(MSG_ERROR,
3031 "OpenSSL: EC_POINT_set_compressed_coordinates failed: %s",
3032 ERR_error_string(ERR_get_error(), NULL));
3033 goto fail;
3034 }
3035
3036 if (!EC_POINT_is_on_curve(ecdh->ec->group, pub, ecdh->ec->bnctx)) {
3037 wpa_printf(MSG_ERROR,
3038 "OpenSSL: ECDH peer public key is not on curve");
3039 goto fail;
3040 }
3041
3042 eckey = EC_KEY_new_by_curve_name(ecdh->ec->nid);
3043 if (!eckey || EC_KEY_set_public_key(eckey, pub) != 1) {
3044 wpa_printf(MSG_ERROR,
3045 "OpenSSL: EC_KEY_set_public_key failed: %s",
3046 ERR_error_string(ERR_get_error(), NULL));
3047 goto fail;
3048 }
3049
3050 peerkey = EVP_PKEY_new();
3051 if (!peerkey || EVP_PKEY_set1_EC_KEY(peerkey, eckey) != 1)
3052 goto fail;
3053
3054 ctx = EVP_PKEY_CTX_new(ecdh->pkey, NULL);
3055 if (!ctx || EVP_PKEY_derive_init(ctx) != 1 ||
3056 EVP_PKEY_derive_set_peer(ctx, peerkey) != 1 ||
3057 EVP_PKEY_derive(ctx, NULL, &secret_len) != 1) {
3058 wpa_printf(MSG_ERROR,
3059 "OpenSSL: EVP_PKEY_derive(1) failed: %s",
3060 ERR_error_string(ERR_get_error(), NULL));
3061 goto fail;
3062 }
3063
3064 secret = wpabuf_alloc(secret_len);
3065 if (!secret)
3066 goto fail;
3067 if (EVP_PKEY_derive(ctx, wpabuf_put(secret, 0), &secret_len) != 1) {
3068 wpa_printf(MSG_ERROR,
3069 "OpenSSL: EVP_PKEY_derive(2) failed: %s",
3070 ERR_error_string(ERR_get_error(), NULL));
3071 goto fail;
3072 }
3073 if (secret->size != secret_len)
3074 wpa_printf(MSG_DEBUG,
3075 "OpenSSL: EVP_PKEY_derive(2) changed secret_len %d -> %d",
3076 (int) secret->size, (int) secret_len);
3077 wpabuf_put(secret, secret_len);
3078
3079 done:
3080 BN_free(x);
3081 BN_free(y);
3082 EC_KEY_free(eckey);
3083 EC_POINT_free(pub);
3084 EVP_PKEY_CTX_free(ctx);
3085 EVP_PKEY_free(peerkey);
3086 return secret;
3087 fail:
3088 wpabuf_free(secret);
3089 secret = NULL;
3090 goto done;
3091 #endif /* OpenSSL version >= 3.0 */
3092 }
3093
3094
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)3095 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
3096 {
3097 if (ecdh) {
3098 crypto_ec_deinit(ecdh->ec);
3099 EVP_PKEY_free(ecdh->pkey);
3100 os_free(ecdh);
3101 }
3102 }
3103
3104
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)3105 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
3106 {
3107 return crypto_ec_prime_len(ecdh->ec);
3108 }
3109
3110
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)3111 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
3112 {
3113 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3114 EVP_PKEY *pkey = NULL;
3115 OSSL_DECODER_CTX *ctx;
3116
3117 ctx = OSSL_DECODER_CTX_new_for_pkey(
3118 &pkey, "DER", NULL, "EC",
3119 OSSL_KEYMGMT_SELECT_KEYPAIR |
3120 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
3121 NULL, NULL);
3122 if (!ctx ||
3123 OSSL_DECODER_from_data(ctx, &der, &der_len) != 1) {
3124 wpa_printf(MSG_INFO,
3125 "OpenSSL: Decoding EC private key (DER) failed: %s",
3126 ERR_error_string(ERR_get_error(), NULL));
3127 if (ctx)
3128 OSSL_DECODER_CTX_free(ctx);
3129 goto fail;
3130 }
3131
3132 OSSL_DECODER_CTX_free(ctx);
3133 return (struct crypto_ec_key *) pkey;
3134 fail:
3135 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3136 return NULL;
3137 #else /* OpenSSL version >= 3.0 */
3138 EVP_PKEY *pkey = NULL;
3139 EC_KEY *eckey;
3140
3141 eckey = d2i_ECPrivateKey(NULL, &der, der_len);
3142 if (!eckey) {
3143 wpa_printf(MSG_INFO, "OpenSSL: d2i_ECPrivateKey() failed: %s",
3144 ERR_error_string(ERR_get_error(), NULL));
3145 goto fail;
3146 }
3147 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3148
3149 pkey = EVP_PKEY_new();
3150 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3151 EC_KEY_free(eckey);
3152 goto fail;
3153 }
3154
3155 return (struct crypto_ec_key *) pkey;
3156 fail:
3157 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3158 return NULL;
3159 #endif /* OpenSSL version >= 3.0 */
3160 }
3161
3162
crypto_ec_key_set_priv(int group,const u8 * raw,size_t raw_len)3163 struct crypto_ec_key * crypto_ec_key_set_priv(int group,
3164 const u8 *raw, size_t raw_len)
3165 {
3166 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3167 const char *group_name;
3168 OSSL_PARAM params[4];
3169 EVP_PKEY_CTX *ctx = NULL;
3170 EVP_PKEY *pkey = NULL;
3171 BIGNUM *priv;
3172 EC_POINT *pub = NULL;
3173 EC_GROUP *ec_group = NULL;
3174 size_t len;
3175 u8 *pub_bin = NULL;
3176 u8 *priv_bin = NULL;
3177 int priv_bin_len;
3178
3179 group_name = crypto_ec_group_2_name(group);
3180 if (!group_name)
3181 return NULL;
3182
3183 priv = BN_bin2bn(raw, raw_len, NULL);
3184 if (!priv)
3185 return NULL;
3186 priv_bin = os_malloc(raw_len);
3187 if (!priv_bin)
3188 goto fail;
3189 priv_bin_len = BN_bn2lebinpad(priv, priv_bin, raw_len);
3190 if (priv_bin_len < 0)
3191 goto fail;
3192
3193 ec_group = EC_GROUP_new_by_curve_name(crypto_ec_group_2_nid(group));
3194 if (!ec_group)
3195 goto fail;
3196 pub = EC_POINT_new(ec_group);
3197 if (!pub ||
3198 EC_POINT_mul(ec_group, pub, priv, NULL, NULL, NULL) != 1)
3199 goto fail;
3200 len = EC_POINT_point2oct(ec_group, pub, POINT_CONVERSION_UNCOMPRESSED,
3201 NULL, 0, NULL);
3202 if (len == 0)
3203 goto fail;
3204 pub_bin = os_malloc(len);
3205 if (!pub_bin)
3206 goto fail;
3207 len = EC_POINT_point2oct(ec_group, pub, POINT_CONVERSION_UNCOMPRESSED,
3208 pub_bin, len, NULL);
3209 if (len == 0)
3210 goto fail;
3211
3212 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3213 (char *) group_name, 0);
3214 params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY,
3215 priv_bin, priv_bin_len);
3216 params[2] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
3217 pub_bin, len);
3218 params[3] = OSSL_PARAM_construct_end();
3219
3220 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3221 if (!ctx ||
3222 EVP_PKEY_fromdata_init(ctx) <= 0 ||
3223 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
3224 goto fail;
3225
3226 out:
3227 bin_clear_free(priv_bin, raw_len);
3228 os_free(pub_bin);
3229 BN_clear_free(priv);
3230 EVP_PKEY_CTX_free(ctx);
3231 EC_POINT_free(pub);
3232 EC_GROUP_free(ec_group);
3233 return (struct crypto_ec_key *) pkey;
3234
3235 fail:
3236 EVP_PKEY_free(pkey);
3237 pkey = NULL;
3238 goto out;
3239 #else /* OpenSSL version >= 3.0 */
3240 EC_KEY *eckey = NULL;
3241 EVP_PKEY *pkey = NULL;
3242 BIGNUM *priv = NULL;
3243 int nid;
3244 const EC_GROUP *ec_group;
3245 EC_POINT *pub = NULL;
3246
3247 nid = crypto_ec_group_2_nid(group);
3248 if (nid < 0) {
3249 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3250 return NULL;
3251 }
3252
3253 eckey = EC_KEY_new_by_curve_name(nid);
3254 priv = BN_bin2bn(raw, raw_len, NULL);
3255 if (!eckey || !priv ||
3256 EC_KEY_set_private_key(eckey, priv) != 1) {
3257 wpa_printf(MSG_ERROR,
3258 "OpenSSL: Failed to set EC_KEY: %s",
3259 ERR_error_string(ERR_get_error(), NULL));
3260 goto fail;
3261 }
3262
3263 ec_group = EC_KEY_get0_group(eckey);
3264 if (!ec_group)
3265 goto fail;
3266 pub = EC_POINT_new(ec_group);
3267 if (!pub ||
3268 EC_POINT_mul(ec_group, pub, priv, NULL, NULL, NULL) != 1 ||
3269 EC_KEY_set_public_key(eckey, pub) != 1) {
3270 wpa_printf(MSG_ERROR,
3271 "OpenSSL: Failed to set EC_KEY(pub): %s",
3272 ERR_error_string(ERR_get_error(), NULL));
3273 goto fail;
3274 }
3275
3276 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3277
3278 pkey = EVP_PKEY_new();
3279 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3280 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3281 goto fail;
3282 }
3283
3284 out:
3285 BN_clear_free(priv);
3286 EC_POINT_free(pub);
3287 return (struct crypto_ec_key *) pkey;
3288
3289 fail:
3290 EC_KEY_free(eckey);
3291 EVP_PKEY_free(pkey);
3292 pkey = NULL;
3293 goto out;
3294 #endif /* OpenSSL version >= 3.0 */
3295 }
3296
3297
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)3298 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
3299 {
3300 EVP_PKEY *pkey;
3301
3302 pkey = d2i_PUBKEY(NULL, &der, der_len);
3303 if (!pkey) {
3304 wpa_printf(MSG_INFO, "OpenSSL: d2i_PUBKEY() failed: %s",
3305 ERR_error_string(ERR_get_error(), NULL));
3306 goto fail;
3307 }
3308
3309 /* Ensure this is an EC key */
3310 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3311 if (!EVP_PKEY_is_a(pkey, "EC"))
3312 goto fail;
3313 #else /* OpenSSL version >= 3.0 */
3314 if (!EVP_PKEY_get0_EC_KEY(pkey))
3315 goto fail;
3316 #endif /* OpenSSL version >= 3.0 */
3317 return (struct crypto_ec_key *) pkey;
3318 fail:
3319 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3320 return NULL;
3321 }
3322
3323
crypto_ec_key_set_pub(int group,const u8 * buf_x,const u8 * buf_y,size_t len)3324 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *buf_x,
3325 const u8 *buf_y, size_t len)
3326 {
3327 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3328 const char *group_name;
3329 OSSL_PARAM params[3];
3330 u8 *pub;
3331 EVP_PKEY_CTX *ctx;
3332 EVP_PKEY *pkey = NULL;
3333
3334 group_name = crypto_ec_group_2_name(group);
3335 if (!group_name)
3336 return NULL;
3337
3338 pub = os_malloc(1 + len * 2);
3339 if (!pub)
3340 return NULL;
3341 pub[0] = 0x04; /* uncompressed */
3342 os_memcpy(pub + 1, buf_x, len);
3343 os_memcpy(pub + 1 + len, buf_y, len);
3344
3345 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3346 (char *) group_name, 0);
3347 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
3348 pub, 1 + len * 2);
3349 params[2] = OSSL_PARAM_construct_end();
3350
3351 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3352 if (!ctx) {
3353 os_free(pub);
3354 return NULL;
3355 }
3356 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
3357 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
3358 os_free(pub);
3359 EVP_PKEY_CTX_free(ctx);
3360 return NULL;
3361 }
3362
3363 os_free(pub);
3364 EVP_PKEY_CTX_free(ctx);
3365
3366 return (struct crypto_ec_key *) pkey;
3367 #else /* OpenSSL version >= 3.0 */
3368 EC_KEY *eckey = NULL;
3369 EVP_PKEY *pkey = NULL;
3370 EC_GROUP *ec_group = NULL;
3371 BN_CTX *ctx;
3372 EC_POINT *point = NULL;
3373 BIGNUM *x = NULL, *y = NULL;
3374 int nid;
3375
3376 if (!buf_x || !buf_y)
3377 return NULL;
3378
3379 nid = crypto_ec_group_2_nid(group);
3380 if (nid < 0) {
3381 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3382 return NULL;
3383 }
3384
3385 ctx = BN_CTX_new();
3386 if (!ctx)
3387 goto fail;
3388
3389 ec_group = EC_GROUP_new_by_curve_name(nid);
3390 if (!ec_group)
3391 goto fail;
3392
3393 x = BN_bin2bn(buf_x, len, NULL);
3394 y = BN_bin2bn(buf_y, len, NULL);
3395 point = EC_POINT_new(ec_group);
3396 if (!x || !y || !point)
3397 goto fail;
3398
3399 if (!EC_POINT_set_affine_coordinates(ec_group, point, x, y, ctx)) {
3400 wpa_printf(MSG_ERROR,
3401 "OpenSSL: EC_POINT_set_affine_coordinates failed: %s",
3402 ERR_error_string(ERR_get_error(), NULL));
3403 goto fail;
3404 }
3405
3406 if (!EC_POINT_is_on_curve(ec_group, point, ctx) ||
3407 EC_POINT_is_at_infinity(ec_group, point)) {
3408 wpa_printf(MSG_ERROR, "OpenSSL: Invalid point");
3409 goto fail;
3410 }
3411
3412 eckey = EC_KEY_new();
3413 if (!eckey ||
3414 EC_KEY_set_group(eckey, ec_group) != 1 ||
3415 EC_KEY_set_public_key(eckey, point) != 1) {
3416 wpa_printf(MSG_ERROR,
3417 "OpenSSL: Failed to set EC_KEY: %s",
3418 ERR_error_string(ERR_get_error(), NULL));
3419 goto fail;
3420 }
3421 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3422
3423 pkey = EVP_PKEY_new();
3424 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3425 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3426 goto fail;
3427 }
3428
3429 out:
3430 EC_GROUP_free(ec_group);
3431 BN_free(x);
3432 BN_free(y);
3433 EC_POINT_free(point);
3434 BN_CTX_free(ctx);
3435 return (struct crypto_ec_key *) pkey;
3436
3437 fail:
3438 EC_KEY_free(eckey);
3439 EVP_PKEY_free(pkey);
3440 pkey = NULL;
3441 goto out;
3442 #endif /* OpenSSL version >= 3.0 */
3443 }
3444
3445
3446 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * ec,const struct crypto_ec_point * pub)3447 crypto_ec_key_set_pub_point(struct crypto_ec *ec,
3448 const struct crypto_ec_point *pub)
3449 {
3450 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3451 int len = BN_num_bytes(ec->prime);
3452 struct crypto_ec_key *key;
3453 u8 *buf;
3454
3455 buf = os_malloc(2 * len);
3456 if (!buf)
3457 return NULL;
3458 if (crypto_ec_point_to_bin(ec, pub, buf, buf + len) < 0) {
3459 os_free(buf);
3460 return NULL;
3461 }
3462
3463 key = crypto_ec_key_set_pub(ec->iana_group, buf, buf + len, len);
3464 os_free(buf);
3465
3466 return key;
3467 #else /* OpenSSL version >= 3.0 */
3468 EC_KEY *eckey;
3469 EVP_PKEY *pkey = NULL;
3470
3471 eckey = EC_KEY_new();
3472 if (!eckey ||
3473 EC_KEY_set_group(eckey, ec->group) != 1 ||
3474 EC_KEY_set_public_key(eckey, (const EC_POINT *) pub) != 1) {
3475 wpa_printf(MSG_ERROR,
3476 "OpenSSL: Failed to set EC_KEY: %s",
3477 ERR_error_string(ERR_get_error(), NULL));
3478 goto fail;
3479 }
3480 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3481
3482 pkey = EVP_PKEY_new();
3483 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3484 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3485 goto fail;
3486 }
3487
3488 out:
3489 return (struct crypto_ec_key *) pkey;
3490
3491 fail:
3492 EVP_PKEY_free(pkey);
3493 EC_KEY_free(eckey);
3494 pkey = NULL;
3495 goto out;
3496 #endif /* OpenSSL version >= 3.0 */
3497 }
3498
3499
crypto_ec_key_gen(int group)3500 struct crypto_ec_key * crypto_ec_key_gen(int group)
3501 {
3502 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3503 EVP_PKEY_CTX *ctx;
3504 OSSL_PARAM params[2];
3505 const char *group_name;
3506 EVP_PKEY *pkey = NULL;
3507
3508 group_name = crypto_ec_group_2_name(group);
3509 if (!group_name)
3510 return NULL;
3511
3512 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3513 (char *) group_name, 0);
3514 params[1] = OSSL_PARAM_construct_end();
3515
3516 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3517 if (!ctx ||
3518 EVP_PKEY_keygen_init(ctx) != 1 ||
3519 EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
3520 EVP_PKEY_generate(ctx, &pkey) != 1) {
3521 wpa_printf(MSG_INFO,
3522 "OpenSSL: Failed to generate EC keypair (group=%d): %s",
3523 group, ERR_error_string(ERR_get_error(), NULL));
3524 pkey = NULL;
3525 }
3526
3527 EVP_PKEY_CTX_free(ctx);
3528
3529 return (struct crypto_ec_key *) pkey;
3530 #else /* OpenSSL version >= 3.0 */
3531 EVP_PKEY_CTX *kctx = NULL;
3532 EC_KEY *ec_params = NULL, *eckey;
3533 EVP_PKEY *params = NULL, *key = NULL;
3534 int nid;
3535
3536 nid = crypto_ec_group_2_nid(group);
3537 if (nid < 0) {
3538 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3539 return NULL;
3540 }
3541
3542 ec_params = EC_KEY_new_by_curve_name(nid);
3543 if (!ec_params) {
3544 wpa_printf(MSG_ERROR,
3545 "OpenSSL: Failed to generate EC_KEY parameters");
3546 goto fail;
3547 }
3548 EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
3549 params = EVP_PKEY_new();
3550 if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
3551 wpa_printf(MSG_ERROR,
3552 "OpenSSL: Failed to generate EVP_PKEY parameters");
3553 goto fail;
3554 }
3555
3556 kctx = EVP_PKEY_CTX_new(params, NULL);
3557 if (!kctx ||
3558 EVP_PKEY_keygen_init(kctx) != 1 ||
3559 EVP_PKEY_keygen(kctx, &key) != 1) {
3560 wpa_printf(MSG_ERROR, "OpenSSL: Failed to generate EC key");
3561 key = NULL;
3562 goto fail;
3563 }
3564
3565 eckey = EVP_PKEY_get1_EC_KEY(key);
3566 if (!eckey) {
3567 key = NULL;
3568 goto fail;
3569 }
3570 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3571 EC_KEY_free(eckey);
3572
3573 fail:
3574 EC_KEY_free(ec_params);
3575 EVP_PKEY_free(params);
3576 EVP_PKEY_CTX_free(kctx);
3577 return (struct crypto_ec_key *) key;
3578 #endif /* OpenSSL version >= 3.0 */
3579 }
3580
3581
crypto_ec_key_deinit(struct crypto_ec_key * key)3582 void crypto_ec_key_deinit(struct crypto_ec_key *key)
3583 {
3584 EVP_PKEY_free((EVP_PKEY *) key);
3585 }
3586
3587
3588 #ifdef OPENSSL_IS_BORINGSSL
3589
3590 /* BoringSSL version of i2d_PUBKEY() always outputs public EC key using
3591 * uncompressed form so define a custom function to export EC pubkey using
3592 * the compressed format that is explicitly required for some protocols. */
3593
3594 #include <openssl/asn1.h>
3595 #include <openssl/asn1t.h>
3596
3597 typedef struct {
3598 /* AlgorithmIdentifier ecPublicKey with optional parameters present
3599 * as an OID identifying the curve */
3600 X509_ALGOR *alg;
3601 /* Compressed format public key per ANSI X9.63 */
3602 ASN1_BIT_STRING *pub_key;
3603 } EC_COMP_PUBKEY;
3604
3605 ASN1_SEQUENCE(EC_COMP_PUBKEY) = {
3606 ASN1_SIMPLE(EC_COMP_PUBKEY, alg, X509_ALGOR),
3607 ASN1_SIMPLE(EC_COMP_PUBKEY, pub_key, ASN1_BIT_STRING)
3608 } ASN1_SEQUENCE_END(EC_COMP_PUBKEY);
3609
3610 IMPLEMENT_ASN1_FUNCTIONS(EC_COMP_PUBKEY);
3611
3612 #endif /* OPENSSL_IS_BORINGSSL */
3613
3614
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)3615 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
3616 {
3617 EVP_PKEY *pkey = (EVP_PKEY *) key;
3618 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3619 OSSL_ENCODER_CTX *ctx;
3620 int selection;
3621 unsigned char *pdata = NULL;
3622 size_t pdata_len = 0;
3623 EVP_PKEY *copy = NULL;
3624 struct wpabuf *buf = NULL;
3625
3626 if (EVP_PKEY_get_ec_point_conv_form(pkey) !=
3627 POINT_CONVERSION_COMPRESSED) {
3628 copy = EVP_PKEY_dup(pkey);
3629 if (!copy)
3630 return NULL;
3631 if (EVP_PKEY_set_utf8_string_param(
3632 copy, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
3633 OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED) !=
3634 1) {
3635 wpa_printf(MSG_INFO,
3636 "OpenSSL: Failed to set compressed format");
3637 EVP_PKEY_free(copy);
3638 return NULL;
3639 }
3640 pkey = copy;
3641 }
3642
3643 selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS |
3644 OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
3645
3646 ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "DER",
3647 "SubjectPublicKeyInfo",
3648 NULL);
3649 if (!ctx || OSSL_ENCODER_to_data(ctx, &pdata, &pdata_len) != 1) {
3650 wpa_printf(MSG_INFO,
3651 "OpenSSL: Failed to encode SubjectPublicKeyInfo: %s",
3652 ERR_error_string(ERR_get_error(), NULL));
3653 pdata = NULL;
3654 }
3655 OSSL_ENCODER_CTX_free(ctx);
3656 if (pdata) {
3657 buf = wpabuf_alloc_copy(pdata, pdata_len);
3658 OPENSSL_free(pdata);
3659 }
3660
3661 EVP_PKEY_free(copy);
3662
3663 return buf;
3664 #else /* OpenSSL version >= 3.0 */
3665 #ifdef OPENSSL_IS_BORINGSSL
3666 unsigned char *der = NULL;
3667 int der_len;
3668 const EC_KEY *eckey;
3669 struct wpabuf *ret = NULL;
3670 size_t len;
3671 const EC_GROUP *group;
3672 const EC_POINT *point;
3673 BN_CTX *ctx;
3674 EC_COMP_PUBKEY *pubkey = NULL;
3675 int nid;
3676
3677 ctx = BN_CTX_new();
3678 eckey = EVP_PKEY_get0_EC_KEY(pkey);
3679 if (!ctx || !eckey)
3680 goto fail;
3681
3682 group = EC_KEY_get0_group(eckey);
3683 point = EC_KEY_get0_public_key(eckey);
3684 if (!group || !point)
3685 goto fail;
3686 nid = EC_GROUP_get_curve_name(group);
3687
3688 pubkey = EC_COMP_PUBKEY_new();
3689 if (!pubkey ||
3690 X509_ALGOR_set0(pubkey->alg, OBJ_nid2obj(EVP_PKEY_EC),
3691 V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1)
3692 goto fail;
3693
3694 len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
3695 NULL, 0, ctx);
3696 if (len == 0)
3697 goto fail;
3698
3699 der = OPENSSL_malloc(len);
3700 if (!der)
3701 goto fail;
3702 len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
3703 der, len, ctx);
3704
3705 OPENSSL_free(pubkey->pub_key->data);
3706 pubkey->pub_key->data = der;
3707 der = NULL;
3708 pubkey->pub_key->length = len;
3709 /* No unused bits */
3710 pubkey->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
3711 pubkey->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
3712
3713 der_len = i2d_EC_COMP_PUBKEY(pubkey, &der);
3714 if (der_len <= 0) {
3715 wpa_printf(MSG_ERROR,
3716 "BoringSSL: Failed to build DER encoded public key");
3717 goto fail;
3718 }
3719
3720 ret = wpabuf_alloc_copy(der, der_len);
3721 fail:
3722 EC_COMP_PUBKEY_free(pubkey);
3723 OPENSSL_free(der);
3724 BN_CTX_free(ctx);
3725 return ret;
3726 #else /* OPENSSL_IS_BORINGSSL */
3727 unsigned char *der = NULL;
3728 int der_len;
3729 struct wpabuf *buf;
3730 EC_KEY *eckey;
3731
3732 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3733 if (!eckey)
3734 return NULL;
3735
3736 /* For now, all users expect COMPRESSED form */
3737 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3738
3739 der_len = i2d_PUBKEY((EVP_PKEY *) key, &der);
3740 EC_KEY_free(eckey);
3741 if (der_len <= 0) {
3742 wpa_printf(MSG_INFO, "OpenSSL: i2d_PUBKEY() failed: %s",
3743 ERR_error_string(ERR_get_error(), NULL));
3744 return NULL;
3745 }
3746
3747 buf = wpabuf_alloc_copy(der, der_len);
3748 OPENSSL_free(der);
3749 return buf;
3750 #endif /* OPENSSL_IS_BORINGSSL */
3751 #endif /* OpenSSL version >= 3.0 */
3752 }
3753
3754
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)3755 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
3756 bool include_pub)
3757 {
3758 EVP_PKEY *pkey = (EVP_PKEY *) key;
3759 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3760 OSSL_ENCODER_CTX *ctx;
3761 int selection;
3762 unsigned char *pdata = NULL;
3763 size_t pdata_len = 0;
3764 struct wpabuf *buf;
3765 EVP_PKEY *copy = NULL;
3766
3767 selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS |
3768 OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
3769 if (include_pub) {
3770 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
3771 } else {
3772 /* Not including OSSL_KEYMGMT_SELECT_PUBLIC_KEY does not seem
3773 * to really be sufficient, so clone the key and explicitly
3774 * mark it not to include the public key. */
3775 copy = EVP_PKEY_dup(pkey);
3776 if (!copy)
3777 return NULL;
3778 EVP_PKEY_set_int_param(copy, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC,
3779 0);
3780 pkey = copy;
3781 }
3782
3783 ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "DER",
3784 "type-specific", NULL);
3785 if (!ctx || OSSL_ENCODER_to_data(ctx, &pdata, &pdata_len) != 1) {
3786 wpa_printf(MSG_INFO, "OpenSSL: OSSL_ENCODER failed: %s",
3787 ERR_error_string(ERR_get_error(), NULL));
3788 OSSL_ENCODER_CTX_free(ctx);
3789 EVP_PKEY_free(copy);
3790 return NULL;
3791 }
3792 OSSL_ENCODER_CTX_free(ctx);
3793 buf = wpabuf_alloc_copy(pdata, pdata_len);
3794 OPENSSL_free(pdata);
3795 EVP_PKEY_free(copy);
3796 return buf;
3797 #else /* OpenSSL version >= 3.0 */
3798 EC_KEY *eckey;
3799 unsigned char *der = NULL;
3800 int der_len;
3801 struct wpabuf *buf;
3802 unsigned int key_flags;
3803
3804 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3805 if (!eckey)
3806 return NULL;
3807
3808 key_flags = EC_KEY_get_enc_flags(eckey);
3809 if (include_pub)
3810 key_flags &= ~EC_PKEY_NO_PUBKEY;
3811 else
3812 key_flags |= EC_PKEY_NO_PUBKEY;
3813 EC_KEY_set_enc_flags(eckey, key_flags);
3814
3815 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
3816
3817 der_len = i2d_ECPrivateKey(eckey, &der);
3818 EC_KEY_free(eckey);
3819 if (der_len <= 0)
3820 return NULL;
3821 buf = wpabuf_alloc_copy(der, der_len);
3822 OPENSSL_free(der);
3823
3824 return buf;
3825 #endif /* OpenSSL version >= 3.0 */
3826 }
3827
3828
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)3829 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
3830 int prefix)
3831 {
3832 EVP_PKEY *pkey = (EVP_PKEY *) key;
3833 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3834 struct wpabuf *buf;
3835 unsigned char *pos;
3836 size_t pub_len = OSSL_PARAM_UNMODIFIED;
3837
3838 buf = NULL;
3839 if (!EVP_PKEY_is_a(pkey, "EC") ||
3840 EVP_PKEY_get_octet_string_param(pkey,
3841 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
3842 NULL, 0, &pub_len) < 0 ||
3843 pub_len == OSSL_PARAM_UNMODIFIED ||
3844 !(buf = wpabuf_alloc(pub_len)) ||
3845 EVP_PKEY_get_octet_string_param(pkey,
3846 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
3847 wpabuf_put(buf, pub_len),
3848 pub_len, NULL) != 1 ||
3849 wpabuf_head_u8(buf)[0] != 0x04) {
3850 wpa_printf(MSG_INFO,
3851 "OpenSSL: Failed to get encoded public key: %s",
3852 ERR_error_string(ERR_get_error(), NULL));
3853 wpabuf_free(buf);
3854 return NULL;
3855 }
3856
3857 if (!prefix) {
3858 /* Remove 0x04 prefix if requested */
3859 pos = wpabuf_mhead(buf);
3860 os_memmove(pos, pos + 1, pub_len - 1);
3861 buf->used--;
3862 }
3863
3864 return buf;
3865 #else /* OpenSSL version >= 3.0 */
3866 int len, res;
3867 EC_KEY *eckey;
3868 struct wpabuf *buf;
3869 unsigned char *pos;
3870
3871 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3872 if (!eckey)
3873 return NULL;
3874 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
3875 len = i2o_ECPublicKey(eckey, NULL);
3876 if (len <= 0) {
3877 wpa_printf(MSG_ERROR,
3878 "OpenSSL: Failed to determine public key encoding length");
3879 EC_KEY_free(eckey);
3880 return NULL;
3881 }
3882
3883 buf = wpabuf_alloc(len);
3884 if (!buf) {
3885 EC_KEY_free(eckey);
3886 return NULL;
3887 }
3888
3889 pos = wpabuf_put(buf, len);
3890 res = i2o_ECPublicKey(eckey, &pos);
3891 EC_KEY_free(eckey);
3892 if (res != len) {
3893 wpa_printf(MSG_ERROR,
3894 "OpenSSL: Failed to encode public key (res=%d/%d)",
3895 res, len);
3896 wpabuf_free(buf);
3897 return NULL;
3898 }
3899
3900 if (!prefix) {
3901 /* Remove 0x04 prefix if requested */
3902 pos = wpabuf_mhead(buf);
3903 os_memmove(pos, pos + 1, len - 1);
3904 buf->used--;
3905 }
3906
3907 return buf;
3908 #endif /* OpenSSL version >= 3.0 */
3909 }
3910
3911
3912 struct crypto_ec_point *
crypto_ec_key_get_public_key(struct crypto_ec_key * key)3913 crypto_ec_key_get_public_key(struct crypto_ec_key *key)
3914 {
3915 EVP_PKEY *pkey = (EVP_PKEY *) key;
3916 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3917 char group[64];
3918 unsigned char pub[256];
3919 size_t len;
3920 EC_POINT *point = NULL;
3921 EC_GROUP *grp;
3922 int res = 0;
3923 OSSL_PARAM params[2];
3924
3925 if (!EVP_PKEY_is_a(pkey, "EC") ||
3926 EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
3927 group, sizeof(group), &len) != 1 ||
3928 EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
3929 pub, sizeof(pub), &len) != 1)
3930 return NULL;
3931
3932 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3933 group, 0);
3934 params[1] = OSSL_PARAM_construct_end();
3935 grp = EC_GROUP_new_from_params(params, NULL, NULL);
3936 if (!grp)
3937 goto fail;
3938 point = EC_POINT_new(grp);
3939 if (!point)
3940 goto fail;
3941 res = EC_POINT_oct2point(grp, point, pub, len, NULL);
3942
3943 fail:
3944 if (res != 1) {
3945 EC_POINT_free(point);
3946 point = NULL;
3947 }
3948
3949 EC_GROUP_free(grp);
3950
3951 return (struct crypto_ec_point *) point;
3952 #else /* OpenSSL version >= 3.0 */
3953 const EC_KEY *eckey;
3954 const EC_POINT *point;
3955 const EC_GROUP *group;
3956
3957 eckey = EVP_PKEY_get0_EC_KEY(pkey);
3958 if (!eckey)
3959 return NULL;
3960 group = EC_KEY_get0_group(eckey);
3961 if (!group)
3962 return NULL;
3963 point = EC_KEY_get0_public_key(eckey);
3964 if (!point)
3965 return NULL;
3966 return (struct crypto_ec_point *) EC_POINT_dup(point, group);
3967 #endif /* OpenSSL version >= 3.0 */
3968 }
3969
3970
3971 struct crypto_bignum *
crypto_ec_key_get_private_key(struct crypto_ec_key * key)3972 crypto_ec_key_get_private_key(struct crypto_ec_key *key)
3973 {
3974 EVP_PKEY *pkey = (EVP_PKEY *) key;
3975 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3976 BIGNUM *bn = NULL;
3977
3978 if (!EVP_PKEY_is_a(pkey, "EC") ||
3979 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn) != 1)
3980 return NULL;
3981 return (struct crypto_bignum *) bn;
3982 #else /* OpenSSL version >= 3.0 */
3983 const EC_KEY *eckey;
3984 const BIGNUM *bn;
3985
3986 eckey = EVP_PKEY_get0_EC_KEY(pkey);
3987 if (!eckey)
3988 return NULL;
3989 bn = EC_KEY_get0_private_key(eckey);
3990 if (!bn)
3991 return NULL;
3992 return (struct crypto_bignum *) BN_dup(bn);
3993 #endif /* OpenSSL version >= 3.0 */
3994 }
3995
3996
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)3997 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
3998 size_t len)
3999 {
4000 EVP_PKEY_CTX *pkctx;
4001 struct wpabuf *sig_der;
4002 size_t sig_len;
4003
4004 sig_len = EVP_PKEY_size((EVP_PKEY *) key);
4005 sig_der = wpabuf_alloc(sig_len);
4006 if (!sig_der)
4007 return NULL;
4008
4009 pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
4010 if (!pkctx ||
4011 EVP_PKEY_sign_init(pkctx) <= 0 ||
4012 EVP_PKEY_sign(pkctx, wpabuf_put(sig_der, 0), &sig_len,
4013 data, len) <= 0) {
4014 wpabuf_free(sig_der);
4015 sig_der = NULL;
4016 } else {
4017 wpabuf_put(sig_der, sig_len);
4018 }
4019
4020 EVP_PKEY_CTX_free(pkctx);
4021 return sig_der;
4022 }
4023
4024
openssl_evp_pkey_ec_prime_len(struct crypto_ec_key * key)4025 static int openssl_evp_pkey_ec_prime_len(struct crypto_ec_key *key)
4026 {
4027 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4028 char gname[50];
4029 int nid;
4030 EC_GROUP *group;
4031 BIGNUM *prime = NULL;
4032 int prime_len = -1;
4033
4034 if (EVP_PKEY_get_group_name((EVP_PKEY *) key, gname, sizeof(gname),
4035 NULL) != 1)
4036 return -1;
4037 nid = OBJ_txt2nid(gname);
4038 group = EC_GROUP_new_by_curve_name(nid);
4039 prime = BN_new();
4040 if (!group || !prime)
4041 goto fail;
4042 if (EC_GROUP_get_curve(group, prime, NULL, NULL, NULL) == 1)
4043 prime_len = BN_num_bytes(prime);
4044 fail:
4045 EC_GROUP_free(group);
4046 BN_free(prime);
4047 return prime_len;
4048 #else
4049 const EC_GROUP *group;
4050 const EC_KEY *eckey;
4051 BIGNUM *prime = NULL;
4052 int prime_len = -1;
4053
4054 eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
4055 if (!eckey)
4056 goto fail;
4057 group = EC_KEY_get0_group(eckey);
4058 prime = BN_new();
4059 if (!prime || !group ||
4060 !EC_GROUP_get_curve(group, prime, NULL, NULL, NULL))
4061 goto fail;
4062 prime_len = BN_num_bytes(prime);
4063 fail:
4064 BN_free(prime);
4065 return prime_len;
4066 #endif
4067 }
4068
4069
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)4070 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
4071 const u8 *data, size_t len)
4072 {
4073 ECDSA_SIG *sig = NULL;
4074 const BIGNUM *r, *s;
4075 u8 *r_buf, *s_buf;
4076 struct wpabuf *buf;
4077 const unsigned char *p;
4078 int prime_len;
4079
4080 prime_len = openssl_evp_pkey_ec_prime_len(key);
4081 if (prime_len < 0)
4082 return NULL;
4083
4084 buf = crypto_ec_key_sign(key, data, len);
4085 if (!buf)
4086 return NULL;
4087
4088 /* Extract (r,s) from Ecdsa-Sig-Value */
4089
4090 p = wpabuf_head(buf);
4091 sig = d2i_ECDSA_SIG(NULL, &p, wpabuf_len(buf));
4092 if (!sig)
4093 goto fail;
4094 ECDSA_SIG_get0(sig, &r, &s);
4095
4096 /* Re-use wpabuf returned by crypto_ec_key_sign() */
4097 buf->used = 0;
4098 r_buf = wpabuf_put(buf, prime_len);
4099 s_buf = wpabuf_put(buf, prime_len);
4100 if (crypto_bignum_to_bin((const struct crypto_bignum *) r, r_buf,
4101 prime_len, prime_len) < 0 ||
4102 crypto_bignum_to_bin((const struct crypto_bignum *) s, s_buf,
4103 prime_len, prime_len) < 0)
4104 goto fail;
4105
4106 out:
4107 ECDSA_SIG_free(sig);
4108 return buf;
4109 fail:
4110 wpabuf_clear_free(buf);
4111 buf = NULL;
4112 goto out;
4113 }
4114
4115
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)4116 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
4117 size_t len, const u8 *sig, size_t sig_len)
4118 {
4119 EVP_PKEY_CTX *pkctx;
4120 int ret;
4121
4122 pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
4123 if (!pkctx || EVP_PKEY_verify_init(pkctx) <= 0) {
4124 EVP_PKEY_CTX_free(pkctx);
4125 return -1;
4126 }
4127
4128 ret = EVP_PKEY_verify(pkctx, sig, sig_len, data, len);
4129 EVP_PKEY_CTX_free(pkctx);
4130 if (ret == 1)
4131 return 1; /* signature ok */
4132 if (ret == 0)
4133 return 0; /* incorrect signature */
4134 return -1;
4135 }
4136
4137
crypto_ec_key_verify_signature_r_s(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * r,size_t r_len,const u8 * s,size_t s_len)4138 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
4139 const u8 *data, size_t len,
4140 const u8 *r, size_t r_len,
4141 const u8 *s, size_t s_len)
4142 {
4143 ECDSA_SIG *sig;
4144 BIGNUM *r_bn, *s_bn;
4145 unsigned char *der = NULL;
4146 int der_len;
4147 int ret = -1;
4148
4149 r_bn = BN_bin2bn(r, r_len, NULL);
4150 s_bn = BN_bin2bn(s, s_len, NULL);
4151 sig = ECDSA_SIG_new();
4152 if (!r_bn || !s_bn || !sig || ECDSA_SIG_set0(sig, r_bn, s_bn) != 1)
4153 goto fail;
4154 r_bn = NULL;
4155 s_bn = NULL;
4156
4157 der_len = i2d_ECDSA_SIG(sig, &der);
4158 if (der_len <= 0) {
4159 wpa_printf(MSG_DEBUG,
4160 "OpenSSL: Could not DER encode signature");
4161 goto fail;
4162 }
4163
4164 ret = crypto_ec_key_verify_signature(key, data, len, der, der_len);
4165
4166 fail:
4167 OPENSSL_free(der);
4168 BN_free(r_bn);
4169 BN_free(s_bn);
4170 ECDSA_SIG_free(sig);
4171 return ret;
4172 }
4173
4174
crypto_ec_key_group(struct crypto_ec_key * key)4175 int crypto_ec_key_group(struct crypto_ec_key *key)
4176 {
4177 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4178 char gname[50];
4179 int nid;
4180
4181 if (EVP_PKEY_get_group_name((EVP_PKEY *) key, gname, sizeof(gname),
4182 NULL) != 1)
4183 return -1;
4184 nid = OBJ_txt2nid(gname);
4185 #else
4186 const EC_KEY *eckey;
4187 const EC_GROUP *group;
4188 int nid;
4189
4190 eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
4191 if (!eckey)
4192 return -1;
4193 group = EC_KEY_get0_group(eckey);
4194 if (!group)
4195 return -1;
4196 nid = EC_GROUP_get_curve_name(group);
4197 #endif
4198 switch (nid) {
4199 case NID_X9_62_prime256v1:
4200 return 19;
4201 case NID_secp384r1:
4202 return 20;
4203 case NID_secp521r1:
4204 return 21;
4205 #ifdef NID_brainpoolP256r1
4206 case NID_brainpoolP256r1:
4207 return 28;
4208 #endif /* NID_brainpoolP256r1 */
4209 #ifdef NID_brainpoolP384r1
4210 case NID_brainpoolP384r1:
4211 return 29;
4212 #endif /* NID_brainpoolP384r1 */
4213 #ifdef NID_brainpoolP512r1
4214 case NID_brainpoolP512r1:
4215 return 30;
4216 #endif /* NID_brainpoolP512r1 */
4217 default:
4218 wpa_printf(MSG_ERROR,
4219 "OpenSSL: Unsupported curve (nid=%d) in EC key",
4220 nid);
4221 return -1;
4222 }
4223 }
4224
4225
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)4226 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
4227 {
4228 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4229 if (EVP_PKEY_eq((EVP_PKEY *) key1, (EVP_PKEY *) key2) != 1)
4230 return -1;
4231 #else
4232 if (EVP_PKEY_cmp((EVP_PKEY *) key1, (EVP_PKEY *) key2) != 1)
4233 return -1;
4234 #endif
4235 return 0;
4236 }
4237
4238
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)4239 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
4240 const char *title)
4241 {
4242 BIO *out;
4243 size_t rlen;
4244 char *txt;
4245 int res;
4246
4247 out = BIO_new(BIO_s_mem());
4248 if (!out)
4249 return;
4250
4251 EVP_PKEY_print_private(out, (EVP_PKEY *) key, 0, NULL);
4252 rlen = BIO_ctrl_pending(out);
4253 txt = os_malloc(rlen + 1);
4254 if (txt) {
4255 res = BIO_read(out, txt, rlen);
4256 if (res > 0) {
4257 txt[res] = '\0';
4258 wpa_printf(MSG_DEBUG, "%s: %s", title, txt);
4259 }
4260 os_free(txt);
4261 }
4262 BIO_free(out);
4263 }
4264
4265
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)4266 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
4267 {
4268 #ifdef OPENSSL_IS_BORINGSSL
4269 CBS pkcs7_cbs;
4270 #else /* OPENSSL_IS_BORINGSSL */
4271 PKCS7 *p7 = NULL;
4272 const unsigned char *p = wpabuf_head(pkcs7);
4273 #endif /* OPENSSL_IS_BORINGSSL */
4274 STACK_OF(X509) *certs;
4275 int i, num;
4276 BIO *out = NULL;
4277 size_t rlen;
4278 struct wpabuf *pem = NULL;
4279 int res;
4280
4281 #ifdef OPENSSL_IS_BORINGSSL
4282 certs = sk_X509_new_null();
4283 if (!certs)
4284 goto fail;
4285 CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7));
4286 if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
4287 wpa_printf(MSG_INFO,
4288 "OpenSSL: Could not parse PKCS#7 object: %s",
4289 ERR_error_string(ERR_get_error(), NULL));
4290 goto fail;
4291 }
4292 #else /* OPENSSL_IS_BORINGSSL */
4293 p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7));
4294 if (!p7) {
4295 wpa_printf(MSG_INFO,
4296 "OpenSSL: Could not parse PKCS#7 object: %s",
4297 ERR_error_string(ERR_get_error(), NULL));
4298 goto fail;
4299 }
4300
4301 switch (OBJ_obj2nid(p7->type)) {
4302 case NID_pkcs7_signed:
4303 certs = p7->d.sign->cert;
4304 break;
4305 case NID_pkcs7_signedAndEnveloped:
4306 certs = p7->d.signed_and_enveloped->cert;
4307 break;
4308 default:
4309 certs = NULL;
4310 break;
4311 }
4312 #endif /* OPENSSL_IS_BORINGSSL */
4313
4314 if (!certs || ((num = sk_X509_num(certs)) == 0)) {
4315 wpa_printf(MSG_INFO,
4316 "OpenSSL: No certificates found in PKCS#7 object");
4317 goto fail;
4318 }
4319
4320 out = BIO_new(BIO_s_mem());
4321 if (!out)
4322 goto fail;
4323
4324 for (i = 0; i < num; i++) {
4325 X509 *cert = sk_X509_value(certs, i);
4326
4327 PEM_write_bio_X509(out, cert);
4328 }
4329
4330 rlen = BIO_ctrl_pending(out);
4331 pem = wpabuf_alloc(rlen);
4332 if (!pem)
4333 goto fail;
4334 res = BIO_read(out, wpabuf_put(pem, 0), rlen);
4335 if (res <= 0) {
4336 wpabuf_free(pem);
4337 pem = NULL;
4338 goto fail;
4339 }
4340 wpabuf_put(pem, res);
4341
4342 fail:
4343 #ifdef OPENSSL_IS_BORINGSSL
4344 if (certs)
4345 sk_X509_pop_free(certs, X509_free);
4346 #else /* OPENSSL_IS_BORINGSSL */
4347 PKCS7_free(p7);
4348 #endif /* OPENSSL_IS_BORINGSSL */
4349 if (out)
4350 BIO_free_all(out);
4351
4352 return pem;
4353 }
4354
4355
crypto_csr_init(void)4356 struct crypto_csr * crypto_csr_init(void)
4357 {
4358 return (struct crypto_csr *)X509_REQ_new();
4359 }
4360
4361
crypto_csr_verify(const struct wpabuf * req)4362 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
4363 {
4364 X509_REQ *csr;
4365 EVP_PKEY *pkey = NULL;
4366 const u8 *der = wpabuf_head(req);
4367
4368 csr = d2i_X509_REQ(NULL, &der, wpabuf_len(req));
4369 if (!csr)
4370 return NULL;
4371
4372 pkey = X509_REQ_get_pubkey((X509_REQ *)csr);
4373 if (!pkey)
4374 goto fail;
4375
4376 if (X509_REQ_verify((X509_REQ *)csr, pkey) != 1)
4377 goto fail;
4378
4379 return (struct crypto_csr *)csr;
4380 fail:
4381 X509_REQ_free(csr);
4382 return NULL;
4383 }
4384
4385
crypto_csr_deinit(struct crypto_csr * csr)4386 void crypto_csr_deinit(struct crypto_csr *csr)
4387 {
4388 X509_REQ_free((X509_REQ *)csr);
4389 }
4390
4391
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)4392 int crypto_csr_set_ec_public_key(struct crypto_csr *csr, struct crypto_ec_key *key)
4393 {
4394 if (!X509_REQ_set_pubkey((X509_REQ *)csr, (EVP_PKEY *)key))
4395 return -1;
4396
4397 return 0;
4398 }
4399
4400
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)4401 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
4402 const char *name)
4403 {
4404 X509_NAME *n;
4405 int nid;
4406
4407 switch (type) {
4408 case CSR_NAME_CN:
4409 nid = NID_commonName;
4410 break;
4411 case CSR_NAME_SN:
4412 nid = NID_surname;
4413 break;
4414 case CSR_NAME_C:
4415 nid = NID_countryName;
4416 break;
4417 case CSR_NAME_O:
4418 nid = NID_organizationName;
4419 break;
4420 case CSR_NAME_OU:
4421 nid = NID_organizationalUnitName;
4422 break;
4423 default:
4424 return -1;
4425 }
4426
4427 n = X509_REQ_get_subject_name((X509_REQ *) csr);
4428 if (!n)
4429 return -1;
4430
4431 #if OPENSSL_VERSION_NUMBER < 0x10100000L
4432 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
4433 (unsigned char *) name,
4434 os_strlen(name), -1, 0))
4435 return -1;
4436 #else
4437 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
4438 (const unsigned char *) name,
4439 os_strlen(name), -1, 0))
4440 return -1;
4441 #endif
4442
4443 return 0;
4444 }
4445
4446
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)4447 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
4448 int attr_type, const u8 *value, size_t len)
4449 {
4450 int nid;
4451
4452 switch (attr) {
4453 case CSR_ATTR_CHALLENGE_PASSWORD:
4454 nid = NID_pkcs9_challengePassword;
4455 break;
4456 default:
4457 return -1;
4458 }
4459
4460 if (!X509_REQ_add1_attr_by_NID((X509_REQ *) csr, nid, attr_type, value,
4461 len))
4462 return -1;
4463
4464 return 0;
4465 }
4466
4467
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)4468 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
4469 enum crypto_csr_attr attr,
4470 size_t *len, int *type)
4471 {
4472 X509_ATTRIBUTE *attrib;
4473 ASN1_TYPE *attrib_type;
4474 ASN1_STRING *data;
4475 int loc;
4476 int nid;
4477
4478 switch (attr) {
4479 case CSR_ATTR_CHALLENGE_PASSWORD:
4480 nid = NID_pkcs9_challengePassword;
4481 break;
4482 default:
4483 return NULL;
4484 }
4485
4486 loc = X509_REQ_get_attr_by_NID((X509_REQ *) csr, nid, -1);
4487 if (loc < 0)
4488 return NULL;
4489
4490 attrib = X509_REQ_get_attr((X509_REQ *) csr, loc);
4491 if (!attrib)
4492 return NULL;
4493
4494 attrib_type = X509_ATTRIBUTE_get0_type(attrib, 0);
4495 if (!attrib_type)
4496 return NULL;
4497 *type = ASN1_TYPE_get(attrib_type);
4498 data = X509_ATTRIBUTE_get0_data(attrib, 0, *type, NULL);
4499 if (!data)
4500 return NULL;
4501 *len = ASN1_STRING_length(data);
4502 return ASN1_STRING_get0_data(data);
4503 }
4504
4505
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)4506 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
4507 struct crypto_ec_key *key,
4508 enum crypto_hash_alg algo)
4509 {
4510 const EVP_MD *sign_md;
4511 struct wpabuf *buf;
4512 unsigned char *der = NULL;
4513 int der_len;
4514
4515 switch (algo) {
4516 case CRYPTO_HASH_ALG_SHA256:
4517 sign_md = EVP_sha256();
4518 break;
4519 case CRYPTO_HASH_ALG_SHA384:
4520 sign_md = EVP_sha384();
4521 break;
4522 case CRYPTO_HASH_ALG_SHA512:
4523 sign_md = EVP_sha512();
4524 break;
4525 default:
4526 return NULL;
4527 }
4528
4529 if (!X509_REQ_sign((X509_REQ *) csr, (EVP_PKEY *) key, sign_md))
4530 return NULL;
4531
4532 der_len = i2d_X509_REQ((X509_REQ *) csr, &der);
4533 if (der_len < 0)
4534 return NULL;
4535
4536 buf = wpabuf_alloc_copy(der, der_len);
4537 OPENSSL_free(der);
4538
4539 return buf;
4540 }
4541
4542 #endif /* CONFIG_ECC */
4543
4544
crypto_rsa_key_read_public(FILE * f)4545 static EVP_PKEY * crypto_rsa_key_read_public(FILE *f)
4546 {
4547 EVP_PKEY *pkey;
4548 X509 *x509;
4549 const ASN1_TIME *not_before, *not_after;
4550 int res_before, res_after;
4551
4552 pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
4553 if (pkey)
4554 return pkey;
4555
4556 rewind(f);
4557 x509 = PEM_read_X509(f, NULL, NULL, NULL);
4558 if (!x509)
4559 return NULL;
4560
4561 not_before = X509_get0_notBefore(x509);
4562 not_after = X509_get0_notAfter(x509);
4563 if (!not_before || !not_after)
4564 goto fail;
4565 res_before = X509_cmp_current_time(not_before);
4566 res_after = X509_cmp_current_time(not_after);
4567 if (!res_before || !res_after)
4568 goto fail;
4569 if (res_before > 0 || res_after < 0) {
4570 wpa_printf(MSG_INFO,
4571 "OpenSSL: Certificate for RSA public key is not valid at this time (%d %d)",
4572 res_before, res_after);
4573 goto fail;
4574 }
4575
4576 pkey = X509_get_pubkey(x509);
4577 X509_free(x509);
4578
4579 if (!pkey)
4580 return NULL;
4581 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
4582 wpa_printf(MSG_INFO, "OpenSSL: No RSA public key found");
4583 EVP_PKEY_free(pkey);
4584 return NULL;
4585 }
4586
4587 return pkey;
4588 fail:
4589 X509_free(x509);
4590 return NULL;
4591 }
4592
4593
crypto_rsa_key_read(const char * file,bool private_key)4594 struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key)
4595 {
4596 FILE *f;
4597 EVP_PKEY *pkey;
4598
4599 f = fopen(file, "r");
4600 if (!f)
4601 return NULL;
4602 if (private_key)
4603 pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
4604 else
4605 pkey = crypto_rsa_key_read_public(f);
4606 fclose(f);
4607 return (struct crypto_rsa_key *) pkey;
4608 }
4609
4610
4611 #ifndef OPENSSL_NO_SHA256
4612
crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key * key,const struct wpabuf * in)4613 struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
4614 const struct wpabuf *in)
4615 {
4616 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x30400000L
4617 EVP_PKEY *pkey = (EVP_PKEY *) key;
4618 EVP_PKEY_CTX *pkctx;
4619 struct wpabuf *res = NULL;
4620 size_t outlen;
4621
4622 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
4623 if (!pkctx)
4624 goto fail;
4625
4626 if (EVP_PKEY_encrypt_init(pkctx) != 1 ||
4627 EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
4628 EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
4629 EVP_PKEY_encrypt(pkctx, NULL, &outlen, wpabuf_head(in),
4630 wpabuf_len(in)) != 1 ||
4631 !(res = wpabuf_alloc(outlen)) ||
4632 EVP_PKEY_encrypt(pkctx, wpabuf_put(res, 0), &outlen,
4633 wpabuf_head(in), wpabuf_len(in)) != 1) {
4634 wpabuf_free(res);
4635 res = NULL;
4636 goto fail;
4637 }
4638 wpabuf_put(res, outlen);
4639
4640 fail:
4641 EVP_PKEY_CTX_free(pkctx);
4642 return res;
4643 #else
4644 wpa_printf(MSG_ERROR, "%s() not supported", __func__);
4645 return NULL;
4646 #endif
4647 }
4648
4649
crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key * key,const struct wpabuf * in)4650 struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
4651 const struct wpabuf *in)
4652 {
4653 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x30400000L
4654 EVP_PKEY *pkey = (EVP_PKEY *) key;
4655 EVP_PKEY_CTX *pkctx;
4656 struct wpabuf *res = NULL;
4657 size_t outlen;
4658
4659 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
4660 if (!pkctx)
4661 goto fail;
4662
4663 if (EVP_PKEY_decrypt_init(pkctx) != 1 ||
4664 EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
4665 EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
4666 EVP_PKEY_decrypt(pkctx, NULL, &outlen, wpabuf_head(in),
4667 wpabuf_len(in)) != 1 ||
4668 !(res = wpabuf_alloc(outlen)) ||
4669 EVP_PKEY_decrypt(pkctx, wpabuf_put(res, 0), &outlen,
4670 wpabuf_head(in), wpabuf_len(in)) != 1) {
4671 wpabuf_free(res);
4672 res = NULL;
4673 goto fail;
4674 }
4675 wpabuf_put(res, outlen);
4676
4677 fail:
4678 EVP_PKEY_CTX_free(pkctx);
4679 return res;
4680 #else
4681 wpa_printf(MSG_ERROR, "%s() not supported", __func__);
4682 return NULL;
4683 #endif
4684 }
4685
4686 #endif /* OPENSSL_NO_SHA256 */
4687
4688
crypto_rsa_key_free(struct crypto_rsa_key * key)4689 void crypto_rsa_key_free(struct crypto_rsa_key *key)
4690 {
4691 EVP_PKEY_free((EVP_PKEY *) key);
4692 }
4693
4694
4695 #ifdef CONFIG_DPP3
4696
4697 #define HPKE_MAX_SHARED_SECRET_LEN 66
4698 #define HPKE_MAX_HASH_LEN 64
4699 #define HPKE_MAX_KEY_LEN 32
4700 #define HPKE_MAX_NONCE_LEN 12
4701 #define HPKE_MAX_PUB_LEN (1 + 2 * 66)
4702
4703 struct hpke_context {
4704 /* KEM */
4705 enum hpke_kem_id kem_id;
4706 int kem_nid;
4707 int iana_group;
4708 size_t n_pk;
4709 size_t n_secret;
4710 const EVP_MD *kem_h;
4711 size_t kem_n_h;
4712
4713 /* KDF */
4714 enum hpke_kdf_id kdf_id;
4715 const EVP_MD *kdf_h;
4716 size_t n_h;
4717
4718 /* AEAD */
4719 enum hpke_aead_id aead_id;
4720 const EVP_CIPHER *cipher;
4721 size_t n_k;
4722 size_t n_n;
4723 size_t n_t;
4724 u8 key[HPKE_MAX_KEY_LEN];
4725 u8 base_nonce[HPKE_MAX_NONCE_LEN];
4726 };
4727
4728
hpke_free_context(struct hpke_context * ctx)4729 static void hpke_free_context(struct hpke_context *ctx)
4730 {
4731 bin_clear_free(ctx, sizeof(*ctx));
4732 }
4733
4734
hpke_get_context(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * key)4735 static struct hpke_context * hpke_get_context(enum hpke_kem_id kem_id,
4736 enum hpke_kdf_id kdf_id,
4737 enum hpke_aead_id aead_id,
4738 struct crypto_ec_key *key)
4739 {
4740 struct hpke_context *ctx;
4741 int group;
4742
4743 ctx = os_zalloc(sizeof(*ctx));
4744 if (!ctx)
4745 return NULL;
4746
4747 ctx->kem_id = kem_id;
4748 switch (kem_id) {
4749 case HPKE_DHKEM_P256_HKDF_SHA256:
4750 ctx->kem_nid = NID_X9_62_prime256v1;
4751 ctx->iana_group = 19;
4752 ctx->n_pk = 65;
4753 ctx->n_secret = 32;
4754 ctx->kem_h = EVP_sha256();
4755 ctx->kem_n_h = 32;
4756 break;
4757 case HPKE_DHKEM_P384_HKDF_SHA384:
4758 ctx->kem_nid = NID_secp384r1;
4759 ctx->iana_group = 20;
4760 ctx->n_pk = 97;
4761 ctx->n_secret = 48;
4762 ctx->kem_h = EVP_sha384();
4763 ctx->kem_n_h = 48;
4764 break;
4765 case HPKE_DHKEM_P521_HKDF_SHA512:
4766 ctx->kem_nid = NID_secp521r1;
4767 ctx->iana_group = 21;
4768 ctx->n_pk = 133;
4769 ctx->n_secret = 64;
4770 ctx->kem_h = EVP_sha512();
4771 ctx->kem_n_h = 64;
4772 break;
4773 default:
4774 goto fail;
4775 }
4776
4777 ctx->kdf_id = kdf_id;
4778 switch (kdf_id) {
4779 case HPKE_KDF_HKDF_SHA256:
4780 ctx->kdf_h = EVP_sha256();
4781 ctx->n_h = 32;
4782 break;
4783 case HPKE_KDF_HKDF_SHA384:
4784 ctx->kdf_h = EVP_sha384();
4785 ctx->n_h = 48;
4786 break;
4787 case HPKE_KDF_HKDF_SHA512:
4788 ctx->kdf_h = EVP_sha512();
4789 ctx->n_h = 64;
4790 break;
4791 default:
4792 goto fail;
4793 }
4794
4795 ctx->aead_id = aead_id;
4796 switch (aead_id) {
4797 case HPKE_AEAD_AES_128_GCM:
4798 ctx->cipher = EVP_aes_128_gcm();
4799 ctx->n_k = 16;
4800 ctx->n_n = 12;
4801 ctx->n_t = 16;
4802 break;
4803 case HPKE_AEAD_AES_256_GCM:
4804 ctx->cipher = EVP_aes_256_gcm();
4805 ctx->n_k = 32;
4806 ctx->n_n = 12;
4807 ctx->n_t = 16;
4808 break;
4809 default:
4810 goto fail;
4811 }
4812
4813 /* Convert BP-256/384/512 to P-256/384/521 for DPP */
4814 group = crypto_ec_key_group(key);
4815 if (group == 28 && ctx->iana_group == 19) {
4816 ctx->iana_group = 28;
4817 } else if (group == 29 && ctx->iana_group == 20) {
4818 ctx->iana_group = 29;
4819 } else if (group == 30 && ctx->iana_group == 21) {
4820 ctx->iana_group = 30;
4821 ctx->n_pk = 129;
4822 }
4823 if (group != ctx->iana_group) {
4824 wpa_printf(MSG_INFO, "OpenSSL:%s:group mismatch (%d != %d)",
4825 __func__, group, ctx->iana_group);
4826 goto fail;
4827 }
4828
4829 return ctx;
4830 fail:
4831 hpke_free_context(ctx);
4832 return NULL;
4833 }
4834
4835
hpke_suite_id(struct hpke_context * ctx,bool kem,u8 * suite_id)4836 static size_t hpke_suite_id(struct hpke_context *ctx, bool kem, u8 *suite_id)
4837 {
4838 size_t suite_id_len;
4839
4840 if (kem) {
4841 os_memcpy(suite_id, "KEM", 3);
4842 WPA_PUT_BE16(&suite_id[3], ctx->kem_id);
4843 suite_id_len = 5;
4844 } else {
4845 os_memcpy(suite_id, "HPKE", 4);
4846 WPA_PUT_BE16(&suite_id[4], ctx->kem_id);
4847 WPA_PUT_BE16(&suite_id[6], ctx->kdf_id);
4848 WPA_PUT_BE16(&suite_id[8], ctx->aead_id);
4849 suite_id_len = 10;
4850 }
4851 return suite_id_len;
4852 }
4853
4854
hpke_labeled_extract(struct hpke_context * ctx,bool kem,const u8 * salt,size_t salt_len,const char * label,const u8 * ikm,size_t ikm_len,u8 * prk)4855 static int hpke_labeled_extract(struct hpke_context *ctx, bool kem,
4856 const u8 *salt, size_t salt_len,
4857 const char *label,
4858 const u8 *ikm, size_t ikm_len, u8 *prk)
4859 {
4860 u8 zero[HPKE_MAX_HASH_LEN];
4861 u8 suite_id[10];
4862 size_t suite_id_len;
4863 unsigned int mdlen = kem ? ctx->kem_n_h : ctx->n_h;
4864 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4865 EVP_MAC *hmac;
4866 OSSL_PARAM params[2];
4867 EVP_MAC_CTX *hctx;
4868 size_t mlen;
4869 int res;
4870 #else /* OpenSSL version >= 3.0 */
4871 HMAC_CTX *hctx;
4872 int res;
4873 #endif /* OpenSSL version >= 3.0 */
4874
4875 if (!salt || !salt_len) {
4876 salt_len = mdlen;
4877 os_memset(zero, 0, salt_len);
4878 salt = zero;
4879 }
4880
4881 suite_id_len = hpke_suite_id(ctx, kem, suite_id);
4882
4883 /* labeled_ikm = concat("HPKE-v1", suite_id, label, ikm)
4884 * return Extract(salt, labeled_ikm) */
4885
4886 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4887 hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
4888 if (!hmac)
4889 return -1;
4890
4891 params[0] = OSSL_PARAM_construct_utf8_string(
4892 "digest",
4893 (char *) EVP_MD_get0_name(kem ? ctx->kem_h : ctx->kdf_h), 0);
4894 params[1] = OSSL_PARAM_construct_end();
4895
4896 hctx = EVP_MAC_CTX_new(hmac);
4897 EVP_MAC_free(hmac);
4898 if (!hctx)
4899 return -1;
4900
4901 if (EVP_MAC_init(hctx, salt, salt_len, params) != 1) {
4902 wpa_printf(MSG_INFO,
4903 "OpenSSL: EVP_MAC_init(hmac,digest/HPKE) failed: %s",
4904 ERR_error_string(ERR_get_error(), NULL));
4905 goto fail;
4906 }
4907
4908 if (EVP_MAC_update(hctx, (const unsigned char *) "HPKE-v1", 7) != 1 ||
4909 EVP_MAC_update(hctx, suite_id, suite_id_len) != 1 ||
4910 EVP_MAC_update(hctx, (const unsigned char *) label,
4911 os_strlen(label)) != 1 ||
4912 EVP_MAC_update(hctx, ikm, ikm_len) != 1)
4913 goto fail;
4914
4915 res = EVP_MAC_final(hctx, prk, &mlen, mdlen);
4916 EVP_MAC_CTX_free(hctx);
4917
4918 return res == 1 ? 0 : -1;
4919 fail:
4920 EVP_MAC_CTX_free(hctx);
4921 return -1;
4922 #else /* OpenSSL version >= 3.0 */
4923 hctx = HMAC_CTX_new();
4924 if (!hctx)
4925 return -1;
4926 res = HMAC_Init_ex(hctx, salt, salt_len, kem ? ctx->kem_h : ctx->kdf_h,
4927 NULL);
4928 if (res != 1)
4929 goto done;
4930
4931 HMAC_Update(hctx, (const unsigned char *) "HPKE-v1", 7);
4932 HMAC_Update(hctx, suite_id, suite_id_len);
4933 HMAC_Update(hctx, (const unsigned char *) label, os_strlen(label));
4934 HMAC_Update(hctx, ikm, ikm_len);
4935
4936 res = HMAC_Final(hctx, prk, &mdlen);
4937 done:
4938 HMAC_CTX_free(hctx);
4939
4940 return res == 1 ? 0 : -1;
4941 #endif /* OpenSSL version >= 3.0 */
4942 }
4943
4944
4945 static int
hpke_labeled_expand(struct hpke_context * ctx,bool kem,const u8 * prk,const char * label,const u8 * info,size_t info_len,u8 * out,size_t out_len)4946 hpke_labeled_expand(struct hpke_context *ctx, bool kem, const u8 *prk,
4947 const char *label, const u8 *info, size_t info_len,
4948 u8 *out, size_t out_len)
4949 {
4950 u8 suite_id[10];
4951 size_t suite_id_len;
4952 u8 hash[HPKE_MAX_HASH_LEN];
4953 u8 iter = 0;
4954 size_t label_len = os_strlen(label);
4955 u8 *pos;
4956 size_t left = out_len, clen;
4957 int res = -1;
4958 u8 *labeled_info;
4959 size_t labeled_info_len;
4960 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4961 EVP_MAC *hmac;
4962 OSSL_PARAM params[2];
4963 EVP_MAC_CTX *hctx = NULL;
4964 size_t mdlen;
4965 #else /* OpenSSL version >= 3.0 */
4966 HMAC_CTX *hctx;
4967 unsigned int mdlen;
4968 #endif /* OpenSSL version >= 3.0 */
4969
4970 /* labeled_info = concat(I2OSP(L, 2), "HPKE-v1", suite_id,
4971 * label, info)
4972 * return Expand(prk, labeled_info, L) */
4973 suite_id_len = hpke_suite_id(ctx, kem, suite_id);
4974 labeled_info_len = 2 + 7 + suite_id_len + label_len + info_len;
4975 labeled_info = os_malloc(labeled_info_len);
4976 if (!labeled_info)
4977 return -1;
4978 pos = labeled_info;
4979 WPA_PUT_BE16(pos, out_len);
4980 pos += 2;
4981 os_memcpy(pos, "HPKE-v1", 7);
4982 pos += 7;
4983 os_memcpy(pos, suite_id, suite_id_len);
4984 pos += suite_id_len;
4985 os_memcpy(pos, label, label_len);
4986 pos += label_len;
4987 if (info && info_len)
4988 os_memcpy(pos, info, info_len);
4989
4990 pos = out;
4991 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4992 hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
4993 if (!hmac)
4994 goto fail;
4995
4996 params[0] = OSSL_PARAM_construct_utf8_string(
4997 "digest",
4998 (char *) EVP_MD_get0_name(kem ? ctx->kem_h : ctx->kdf_h), 0);
4999 params[1] = OSSL_PARAM_construct_end();
5000 #else /* OpenSSL version >= 3.0 */
5001 hctx = HMAC_CTX_new();
5002 if (!hctx)
5003 goto fail;
5004 #endif /* OpenSSL version >= 3.0 */
5005
5006 while (left > 0) {
5007 mdlen = kem ? ctx->kem_n_h : ctx->n_h;
5008 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
5009 EVP_MAC_CTX_free(hctx);
5010 hctx = EVP_MAC_CTX_new(hmac);
5011 if (!hctx)
5012 goto fail;
5013
5014 if (EVP_MAC_init(hctx, prk, mdlen, params) != 1) {
5015 wpa_printf(MSG_INFO,
5016 "OpenSSL: EVP_MAC_init(hmac,digest/HPKE) failed: %s",
5017 ERR_error_string(ERR_get_error(), NULL));
5018 goto fail;
5019 }
5020
5021 if (iter > 0 && EVP_MAC_update(hctx, hash, mdlen) != 1)
5022 goto fail;
5023 if (iter == 255)
5024 goto fail;
5025 iter++;
5026
5027 if (EVP_MAC_update(hctx, labeled_info, labeled_info_len) != 1 ||
5028 EVP_MAC_update(hctx, &iter, sizeof(iter)) != 1)
5029 goto fail;
5030
5031 if (EVP_MAC_final(hctx, hash, &mdlen, mdlen) != 1)
5032 goto fail;
5033 #else /* OpenSSL version >= 3.0 */
5034 if (HMAC_Init_ex(hctx, prk, mdlen,
5035 kem ? ctx->kem_h : ctx->kdf_h,
5036 NULL) != 1)
5037 goto fail;
5038
5039 if (iter > 0)
5040 HMAC_Update(hctx, hash, mdlen);
5041 if (iter == 255)
5042 goto fail;
5043 iter++;
5044 HMAC_Update(hctx, labeled_info, labeled_info_len);
5045 HMAC_Update(hctx, &iter, sizeof(iter));
5046
5047 if (HMAC_Final(hctx, hash, &mdlen) != 1)
5048 goto fail;
5049 HMAC_CTX_reset(hctx);
5050 #endif /* OpenSSL version >= 3.0 */
5051
5052 clen = left > mdlen ? mdlen : left;
5053 os_memcpy(pos, hash, clen);
5054 pos += clen;
5055 left -= clen;
5056 }
5057 res = 0;
5058 fail:
5059 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
5060 EVP_MAC_free(hmac);
5061 EVP_MAC_CTX_free(hctx);
5062 #else /* OpenSSL version >= 3.0 */
5063 HMAC_CTX_free(hctx);
5064 #endif /* OpenSSL version >= 3.0 */
5065 os_free(labeled_info);
5066
5067 return res;
5068 }
5069
5070
hpke_extract_and_expand(struct hpke_context * ctx,const u8 * dhss,size_t dhss_len,const u8 * enc,size_t enc_len,const u8 * pk_rm,size_t pk_rm_len,u8 * shared_secret)5071 static int hpke_extract_and_expand(struct hpke_context *ctx,
5072 const u8 *dhss, size_t dhss_len,
5073 const u8 *enc, size_t enc_len,
5074 const u8 *pk_rm, size_t pk_rm_len,
5075 u8 *shared_secret)
5076 {
5077 u8 kem_context[2 * HPKE_MAX_PUB_LEN];
5078 u8 eae_prk[HPKE_MAX_HASH_LEN];
5079
5080 /* eae_prk = LabeledExtract("", "eae_prk", dh) */
5081 if (hpke_labeled_extract(ctx, true, NULL, 0, "eae_prk", dhss, dhss_len,
5082 eae_prk) < 0)
5083 return -1;
5084
5085 if (enc_len > HPKE_MAX_PUB_LEN || pk_rm_len > HPKE_MAX_PUB_LEN)
5086 return -1;
5087 /* kem_context = concat(enc, pkRm) */
5088 os_memcpy(kem_context, enc, enc_len);
5089 os_memcpy(&kem_context[enc_len], pk_rm, pk_rm_len);
5090
5091 /* shared_secret = LabeledExpand(eae_prk, "shared_secret",
5092 * kem_context, Nsecret) */
5093 if (hpke_labeled_expand(ctx, true, eae_prk, "shared_secret",
5094 kem_context, enc_len + pk_rm_len,
5095 shared_secret, ctx->n_secret) < 0)
5096 return -1;
5097
5098 forced_memzero(eae_prk, sizeof(eae_prk));
5099 return 0;
5100 }
5101
5102
hpke_key_schedule(struct hpke_context * ctx,const u8 * shared_secret,const u8 * info,size_t info_len)5103 static int hpke_key_schedule(struct hpke_context *ctx, const u8 *shared_secret,
5104 const u8 *info, size_t info_len)
5105 {
5106 u8 key_schedule_context[1 + 2 * HPKE_MAX_HASH_LEN];
5107 u8 secret[HPKE_MAX_HASH_LEN];
5108 int res = -1;
5109
5110 /* key_schedule_context = concat(mode, psk_id_hash, info_hash) */
5111 key_schedule_context[0] = HPKE_MODE_BASE;
5112
5113 /* psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id) */
5114 if (hpke_labeled_extract(ctx, false, NULL, 0, "psk_id_hash",
5115 NULL, 0, &key_schedule_context[1]) < 0)
5116 goto fail;
5117
5118 /* info_hash = LabeledExtract("", "info_hash", info) */
5119 if (hpke_labeled_extract(ctx, false, NULL, 0, "info_hash",
5120 info, info_len,
5121 &key_schedule_context[1 + ctx->n_h]) < 0)
5122 goto fail;
5123
5124 /* secret = LabeledExtract(shared_secret, "secret", psk) */
5125 if (hpke_labeled_extract(ctx, false, shared_secret, ctx->n_secret,
5126 "secret", NULL, 0, secret) < 0)
5127 goto fail;
5128
5129 /* key = LabeledExpand(secret, "key", key_schedule_context, Nk) */
5130 if (hpke_labeled_expand(ctx, false, secret, "key",
5131 key_schedule_context, 1 + 2 * ctx->n_h,
5132 ctx->key, ctx->n_k) < 0)
5133 goto fail;
5134
5135 /* base_nonce = LabeledExpand(secret, "base_nonce",
5136 * key_schedule_context, Nn) */
5137 if (hpke_labeled_expand(ctx, false, secret, "base_nonce",
5138 key_schedule_context, 1 + 2 * ctx->n_h,
5139 ctx->base_nonce, ctx->n_n) < 0)
5140 goto fail;
5141 res = 0;
5142 fail:
5143 forced_memzero(key_schedule_context, sizeof(key_schedule_context));
5144 forced_memzero(secret, sizeof(secret));
5145 return res;
5146 }
5147
5148
hpke_encap(struct hpke_context * ctx,struct crypto_ec_key * pk_r,u8 * shared_secret,u8 * enc)5149 static int hpke_encap(struct hpke_context *ctx, struct crypto_ec_key *pk_r,
5150 u8 *shared_secret, u8 *enc)
5151 {
5152 EVP_PKEY_CTX *pctx = NULL;
5153 struct crypto_ec_key *sk_e;
5154 int res = -1;
5155 u8 *dhss = NULL;
5156 size_t dhss_len = 0;
5157 struct wpabuf *enc_buf = NULL, *pk_rm = NULL;
5158
5159 /* skE, pkE = GenerateKeyPair() */
5160 sk_e = crypto_ec_key_gen(ctx->iana_group);
5161 if (!sk_e) {
5162 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not generate key pair",
5163 __func__);
5164 goto fail;
5165 }
5166
5167 /* dh = DH(skE, pkR) */
5168 dhss_len = sizeof(dhss);
5169 pctx = EVP_PKEY_CTX_new((EVP_PKEY *) sk_e, NULL);
5170 if (!pctx ||
5171 EVP_PKEY_derive_init(pctx) != 1 ||
5172 EVP_PKEY_derive_set_peer(pctx, (EVP_PKEY *) pk_r) != 1 ||
5173 EVP_PKEY_derive(pctx, NULL, &dhss_len) != 1 ||
5174 !(dhss = os_malloc(dhss_len)) ||
5175 EVP_PKEY_derive(pctx, dhss, &dhss_len) != 1 ||
5176 dhss_len > HPKE_MAX_SHARED_SECRET_LEN) {
5177 wpa_printf(MSG_INFO,
5178 "OpenSSL: hpke_encap: EVP_PKEY_derive failed (dhss_len=%zu): %s",
5179 dhss_len, ERR_error_string(ERR_get_error(), NULL));
5180 goto fail;
5181 }
5182
5183 /* enc = SerializePublicKey(pkE) */
5184 enc_buf = crypto_ec_key_get_pubkey_point(sk_e, 1);
5185 if (!enc_buf)
5186 goto fail;
5187 os_memcpy(enc, wpabuf_head(enc_buf), wpabuf_len(enc_buf));
5188
5189 /* pkRm = SerializePublicKey(pkR) */
5190 pk_rm = crypto_ec_key_get_pubkey_point(pk_r, 1);
5191 if (!pk_rm)
5192 goto fail;
5193
5194 /* kem_context = concat(enc, pkRm) */
5195 /* shared_secret = ExtractAndExpand(dh, kem_context) */
5196 /* return shared_secret, enc */
5197 res = hpke_extract_and_expand(ctx, dhss, dhss_len, enc, ctx->n_pk,
5198 wpabuf_head(pk_rm),
5199 wpabuf_len(pk_rm), shared_secret);
5200 fail:
5201 bin_clear_free(dhss, dhss_len);
5202 crypto_ec_key_deinit(sk_e);
5203 EVP_PKEY_CTX_free(pctx);
5204 wpabuf_free(enc_buf);
5205 wpabuf_free(pk_rm);
5206 return res;
5207 }
5208
5209
5210 static struct wpabuf *
hpke_aead_seal(struct hpke_context * ctx,const u8 * aad,size_t aad_len,const u8 * pt,size_t pt_len)5211 hpke_aead_seal(struct hpke_context *ctx, const u8 *aad, size_t aad_len,
5212 const u8 *pt, size_t pt_len)
5213 {
5214 EVP_CIPHER_CTX *cctx;
5215 int len = 0;
5216 struct wpabuf *ct = NULL;
5217
5218 /* No need to xor in sequence number since we support only the
5219 * single-shot API, i.e., base_nonce can be used as-is. */
5220
5221 cctx = EVP_CIPHER_CTX_new();
5222 if (!cctx ||
5223 EVP_EncryptInit_ex(cctx, ctx->cipher, NULL, ctx->key,
5224 ctx->base_nonce) != 1) {
5225 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptInit_ex failed",
5226 __func__);
5227 goto fail;
5228 }
5229 if (aad && aad_len &&
5230 EVP_EncryptUpdate(cctx, NULL, &len, aad, aad_len) != 1) {
5231 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_EncryptUpdate(AAD) failed",
5232 __func__);
5233 goto fail;
5234 }
5235 ct = wpabuf_alloc(pt_len + AES_BLOCK_SIZE + ctx->n_t);
5236 if (!ct)
5237 goto fail;
5238 if (EVP_EncryptUpdate(cctx, wpabuf_put(ct, 0), &len, pt, pt_len) != 1) {
5239 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_EncryptUpdate failed",
5240 __func__);
5241 goto fail;
5242 }
5243 wpabuf_put(ct, len);
5244
5245 if (EVP_EncryptFinal(cctx, wpabuf_put(ct, 0), &len) != 1) {
5246 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptFinal failed",
5247 __func__);
5248 wpabuf_free(ct);
5249 ct = NULL;
5250 goto fail;
5251 }
5252
5253 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, ctx->n_t,
5254 wpabuf_put(ct, ctx->n_t)) != 1) {
5255 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not get tag",
5256 __func__);
5257 wpabuf_free(ct);
5258 ct = NULL;
5259 goto fail;
5260 }
5261 fail:
5262 EVP_CIPHER_CTX_free(cctx);
5263 return ct;
5264 }
5265
5266
hpke_base_seal_int(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * peer_pub,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * pt,size_t pt_len)5267 static struct wpabuf * hpke_base_seal_int(enum hpke_kem_id kem_id,
5268 enum hpke_kdf_id kdf_id,
5269 enum hpke_aead_id aead_id,
5270 struct crypto_ec_key *peer_pub,
5271 const u8 *info, size_t info_len,
5272 const u8 *aad, size_t aad_len,
5273 const u8 *pt, size_t pt_len)
5274 {
5275 struct hpke_context *ctx;
5276 u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
5277 u8 enc[1 + 2 * HPKE_MAX_PUB_LEN];
5278 struct wpabuf *ct = NULL, *enc_ct = NULL;
5279
5280 ctx = hpke_get_context(kem_id, kdf_id, aead_id, peer_pub);
5281 if (!ctx)
5282 return NULL;
5283
5284 /* shared_secret, enc = Encap(pkR) */
5285 if (hpke_encap(ctx, peer_pub, shared_secret, enc) < 0)
5286 goto fail;
5287
5288 /* KeyScheduleS(mode_base, shared_secret, info,
5289 * default_psk, default_psk_id) */
5290 if (hpke_key_schedule(ctx, shared_secret, info, info_len) < 0)
5291 goto fail;
5292
5293 /* ct = ctx.Seal(aad, pt) */
5294 ct = hpke_aead_seal(ctx, aad, aad_len, pt, pt_len);
5295 if (!ct)
5296 goto fail;
5297
5298 /* return enc, ct */
5299 enc_ct = wpabuf_alloc(ctx->n_pk + wpabuf_len(ct));
5300 if (!enc_ct)
5301 goto fail;
5302 wpabuf_put_data(enc_ct, enc, ctx->n_pk);
5303 wpabuf_put_buf(enc_ct, ct);
5304
5305 fail:
5306 forced_memzero(shared_secret, sizeof(shared_secret));
5307 hpke_free_context(ctx);
5308 wpabuf_free(ct);
5309 return enc_ct;
5310 }
5311
5312
hpke_decap(struct hpke_context * ctx,const u8 * enc,size_t enc_ct_len,struct crypto_ec_key * sk_r,u8 * shared_secret)5313 static int hpke_decap(struct hpke_context *ctx, const u8 *enc,
5314 size_t enc_ct_len, struct crypto_ec_key *sk_r,
5315 u8 *shared_secret)
5316 {
5317 EVP_PKEY_CTX *pctx = NULL;
5318 struct wpabuf *pk_rm = NULL;
5319 size_t len;
5320 int res = -1;
5321 struct crypto_ec_key *pk_e = NULL;
5322 u8 *dhss = NULL;
5323 size_t dhss_len = 0;
5324
5325 /* pkE = DeserializePublicKey(enc) */
5326 if (enc_ct_len < ctx->n_pk)
5327 return -1; /* not enough room for enc */
5328 if (enc[0] != 0x04)
5329 return -1; /* not in uncompressed form */
5330 len = (ctx->n_pk - 1) / 2;
5331 pk_e = crypto_ec_key_set_pub(ctx->iana_group, &enc[1],
5332 &enc[1 + len], len);
5333 if (!pk_e)
5334 return -1; /* invalid public key point */
5335 /* dh = DH(skR, pkE) */
5336 pctx = EVP_PKEY_CTX_new((EVP_PKEY *) sk_r, NULL);
5337 if (!pctx ||
5338 EVP_PKEY_derive_init(pctx) != 1 ||
5339 EVP_PKEY_derive_set_peer(pctx, (EVP_PKEY *) pk_e) != 1 ||
5340 EVP_PKEY_derive(pctx, NULL, &dhss_len) != 1 ||
5341 !(dhss = os_malloc(dhss_len)) ||
5342 EVP_PKEY_derive(pctx, dhss, &dhss_len) != 1 ||
5343 dhss_len > HPKE_MAX_SHARED_SECRET_LEN) {
5344 wpa_printf(MSG_INFO,
5345 "OpenSSL: hpke_decap: EVP_PKEY_derive failed (dhss_len=%zu): %s",
5346 dhss_len, ERR_error_string(ERR_get_error(), NULL));
5347 goto fail;
5348 }
5349
5350 /* pkRm = SerializePublicKey(pk(skR)) */
5351 pk_rm = crypto_ec_key_get_pubkey_point(sk_r, 1);
5352 if (!pk_rm)
5353 goto fail;
5354
5355 /* kem_context = concat(enc, pkRm) */
5356 /* shared_secret = ExtractAndExpand(dh, kem_context) */
5357 res = hpke_extract_and_expand(ctx, dhss, dhss_len, enc, ctx->n_pk,
5358 wpabuf_head(pk_rm),
5359 wpabuf_len(pk_rm), shared_secret);
5360 fail:
5361 bin_clear_free(dhss, dhss_len);
5362 crypto_ec_key_deinit(pk_e);
5363 EVP_PKEY_CTX_free(pctx);
5364 wpabuf_free(pk_rm);
5365 return res;
5366 }
5367
5368
5369 static struct wpabuf *
hpke_aead_open(struct hpke_context * ctx,const u8 * aad,size_t aad_len,const u8 * ct,size_t ct_len)5370 hpke_aead_open(struct hpke_context *ctx, const u8 *aad, size_t aad_len,
5371 const u8 *ct, size_t ct_len)
5372 {
5373 EVP_CIPHER_CTX *cctx;
5374 int len = 0;
5375 const u8 *tag;
5376 struct wpabuf *pt = NULL;
5377
5378 if (ct_len < ctx->n_t)
5379 return NULL;
5380 tag = ct + ct_len - ctx->n_t;
5381 ct_len -= ctx->n_t;
5382
5383 /* No need to xor in sequence number since we support only the
5384 * single-shot API, i.e., base_nonce can be used as-is. */
5385
5386 cctx = EVP_CIPHER_CTX_new();
5387 if (!cctx ||
5388 EVP_DecryptInit_ex(cctx, ctx->cipher, NULL, ctx->key,
5389 ctx->base_nonce) != 1) {
5390 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptInit_ex failed",
5391 __func__);
5392 goto fail;
5393 }
5394 if (aad && aad_len &&
5395 EVP_DecryptUpdate(cctx, NULL, &len, aad, aad_len) != 1) {
5396 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptUpdate(AAD) failed",
5397 __func__);
5398 goto fail;
5399 }
5400 pt = wpabuf_alloc(ct_len + AES_BLOCK_SIZE);
5401 if (!pt)
5402 goto fail;
5403 if (EVP_DecryptUpdate(cctx, wpabuf_put(pt, 0), &len, ct, ct_len) != 1) {
5404 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptUpdate failed",
5405 __func__);
5406 goto fail;
5407 }
5408 wpabuf_put(pt, len);
5409
5410 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_SET_TAG, ctx->n_t,
5411 (void *) tag) != 1) {
5412 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not set tag",
5413 __func__);
5414 wpabuf_free(pt);
5415 pt = NULL;
5416 goto fail;
5417 }
5418
5419 if (EVP_DecryptFinal(cctx, wpabuf_put(pt, 0), &len) != 1) {
5420 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptFinal failed",
5421 __func__);
5422 wpabuf_free(pt);
5423 pt = NULL;
5424 }
5425 fail:
5426 EVP_CIPHER_CTX_free(cctx);
5427 return pt;
5428 }
5429
5430
hpke_base_open_int(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * own_priv,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * enc_ct,size_t enc_ct_len)5431 static struct wpabuf * hpke_base_open_int(enum hpke_kem_id kem_id,
5432 enum hpke_kdf_id kdf_id,
5433 enum hpke_aead_id aead_id,
5434 struct crypto_ec_key *own_priv,
5435 const u8 *info, size_t info_len,
5436 const u8 *aad, size_t aad_len,
5437 const u8 *enc_ct, size_t enc_ct_len)
5438 {
5439 struct hpke_context *ctx;
5440 u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
5441 struct wpabuf *pt = NULL;
5442
5443 ctx = hpke_get_context(kem_id, kdf_id, aead_id, own_priv);
5444 if (!ctx)
5445 return NULL;
5446
5447 /* shared_secret = Decap(enc, skR) */
5448 if (hpke_decap(ctx, enc_ct, enc_ct_len, own_priv, shared_secret) < 0)
5449 goto fail;
5450
5451 /* KeyScheduleR(mode_base, shared_secret, info,
5452 * default_psk, default_psk_id) */
5453 if (hpke_key_schedule(ctx, shared_secret, info, info_len) < 0)
5454 goto fail;
5455
5456 /* return ctx.Open(aad, ct) */
5457 pt = hpke_aead_open(ctx, aad, aad_len,
5458 &enc_ct[ctx->n_pk], enc_ct_len - ctx->n_pk);
5459
5460 fail:
5461 forced_memzero(shared_secret, sizeof(shared_secret));
5462 hpke_free_context(ctx);
5463 return pt;
5464 }
5465
5466
5467 #if OPENSSL_VERSION_NUMBER >= 0x30200000L
5468
hpke_set_suite(OSSL_HPKE_SUITE * suite,enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id)5469 static bool hpke_set_suite(OSSL_HPKE_SUITE *suite,
5470 enum hpke_kem_id kem_id,
5471 enum hpke_kdf_id kdf_id,
5472 enum hpke_aead_id aead_id)
5473 {
5474 os_memset(suite, 0, sizeof(*suite));
5475
5476 switch (kem_id) {
5477 case HPKE_DHKEM_P256_HKDF_SHA256:
5478 suite->kem_id = OSSL_HPKE_KEM_ID_P256;
5479 break;
5480 case HPKE_DHKEM_P384_HKDF_SHA384:
5481 suite->kem_id = OSSL_HPKE_KEM_ID_P384;
5482 break;
5483 case HPKE_DHKEM_P521_HKDF_SHA512:
5484 suite->kem_id = OSSL_HPKE_KEM_ID_P521;
5485 break;
5486 default:
5487 return false;
5488 }
5489
5490 switch (kdf_id) {
5491 case HPKE_KDF_HKDF_SHA256:
5492 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA256;
5493 break;
5494 case HPKE_KDF_HKDF_SHA384:
5495 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA384;
5496 break;
5497 case HPKE_KDF_HKDF_SHA512:
5498 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA512;
5499 break;
5500 default:
5501 return false;
5502 }
5503
5504 switch (aead_id) {
5505 case HPKE_AEAD_AES_128_GCM:
5506 suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_128;
5507 break;
5508 case HPKE_AEAD_AES_256_GCM:
5509 suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_256;
5510 break;
5511 default:
5512 return false;
5513 }
5514
5515 if (!OSSL_HPKE_suite_check(*suite)) {
5516 wpa_printf(MSG_INFO,
5517 "OpenSSL: HPKE suite kem_id=%d kdf_id=%d aead_id=%d not supported",
5518 kem_id, kdf_id, aead_id);
5519 return false;
5520 }
5521
5522 return true;
5523 }
5524
5525
hpke_base_seal(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * peer_pub,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * pt,size_t pt_len)5526 struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
5527 enum hpke_kdf_id kdf_id,
5528 enum hpke_aead_id aead_id,
5529 struct crypto_ec_key *peer_pub,
5530 const u8 *info, size_t info_len,
5531 const u8 *aad, size_t aad_len,
5532 const u8 *pt, size_t pt_len)
5533 {
5534 OSSL_HPKE_SUITE suite;
5535 OSSL_HPKE_CTX *ctx = NULL;
5536 struct wpabuf *res = NULL, *buf, *pub = NULL;
5537 size_t enc_len, ct_len;
5538 int group;
5539
5540 group = crypto_ec_key_group(peer_pub);
5541 if (group == 28 || group == 29 || group == 30) {
5542 /* Use the internal routines for the special DPP use case with
5543 * brainpool curves, */
5544 return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
5545 info, info_len, aad, aad_len,
5546 pt, pt_len);
5547 }
5548
5549
5550 if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
5551 return NULL;
5552
5553 enc_len = OSSL_HPKE_get_public_encap_size(suite);
5554 ct_len = OSSL_HPKE_get_ciphertext_size(suite, pt_len);
5555 buf = wpabuf_alloc(enc_len + ct_len);
5556 if (!buf)
5557 goto out;
5558
5559 pub = crypto_ec_key_get_pubkey_point(peer_pub, 1);
5560 if (!pub)
5561 goto out;
5562
5563 ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
5564 OSSL_HPKE_ROLE_SENDER, NULL, NULL);
5565 if (!ctx)
5566 goto out;
5567
5568 if (OSSL_HPKE_encap(ctx, wpabuf_put(buf, 0), &enc_len,
5569 wpabuf_head(pub), wpabuf_len(pub),
5570 info, info_len) != 1) {
5571 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_encap failed: %s",
5572 ERR_error_string(ERR_get_error(), NULL));
5573 goto out;
5574 }
5575 wpabuf_put(buf, enc_len);
5576
5577 if (OSSL_HPKE_seal(ctx, wpabuf_put(buf, 0), &ct_len, aad, aad_len,
5578 pt, pt_len) != 1) {
5579 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_seal failed: %s",
5580 ERR_error_string(ERR_get_error(), NULL));
5581 goto out;
5582 }
5583 wpabuf_put(buf, ct_len);
5584 res = buf;
5585 buf = NULL;
5586
5587 out:
5588 OSSL_HPKE_CTX_free(ctx);
5589 wpabuf_free(buf);
5590 wpabuf_free(pub);
5591 return res;
5592 }
5593
5594
hpke_base_open(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * own_priv,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * enc_ct,size_t enc_ct_len)5595 struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
5596 enum hpke_kdf_id kdf_id,
5597 enum hpke_aead_id aead_id,
5598 struct crypto_ec_key *own_priv,
5599 const u8 *info, size_t info_len,
5600 const u8 *aad, size_t aad_len,
5601 const u8 *enc_ct, size_t enc_ct_len)
5602 {
5603 OSSL_HPKE_SUITE suite;
5604 OSSL_HPKE_CTX *ctx;
5605 struct wpabuf *buf = NULL, *res = NULL;
5606 size_t len, enc_len;
5607 int group;
5608
5609 group = crypto_ec_key_group(own_priv);
5610 if (group == 28 || group == 29 || group == 30) {
5611 /* Use the internal routines for the special DPP use case with
5612 * brainpool curves, */
5613 return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
5614 info, info_len, aad, aad_len,
5615 enc_ct, enc_ct_len);
5616 }
5617
5618 if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
5619 return NULL;
5620
5621 enc_len = OSSL_HPKE_get_public_encap_size(suite);
5622 if (enc_ct_len < enc_len) {
5623 wpa_printf(MSG_DEBUG, "OpenSSL: Too short HPKE enc_ct data");
5624 return NULL;
5625 }
5626
5627 ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
5628 OSSL_HPKE_ROLE_RECEIVER, NULL, NULL);
5629 if (!ctx)
5630 goto out;
5631
5632 if (OSSL_HPKE_decap(ctx, enc_ct, enc_len, (EVP_PKEY *) own_priv,
5633 info, info_len) != 1) {
5634 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_decap failed: %s",
5635 ERR_error_string(ERR_get_error(), NULL));
5636 goto out;
5637 }
5638
5639 len = enc_ct_len;
5640 buf = wpabuf_alloc(len);
5641 if (!buf)
5642 goto out;
5643
5644 if (OSSL_HPKE_open(ctx, wpabuf_put(buf, 0), &len, aad, aad_len,
5645 enc_ct + enc_len, enc_ct_len - enc_len) != 1) {
5646 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_open failed: %s",
5647 ERR_error_string(ERR_get_error(), NULL));
5648 goto out;
5649 }
5650
5651 wpabuf_put(buf, len);
5652 res = buf;
5653 buf = NULL;
5654
5655 out:
5656 OSSL_HPKE_CTX_free(ctx);
5657 wpabuf_free(buf);
5658 return res;
5659 }
5660
5661 #else /* OpenSSL < 3.2 */
5662
hpke_base_seal(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * peer_pub,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * pt,size_t pt_len)5663 struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
5664 enum hpke_kdf_id kdf_id,
5665 enum hpke_aead_id aead_id,
5666 struct crypto_ec_key *peer_pub,
5667 const u8 *info, size_t info_len,
5668 const u8 *aad, size_t aad_len,
5669 const u8 *pt, size_t pt_len)
5670 {
5671 return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
5672 info, info_len, aad, aad_len, pt, pt_len);
5673 }
5674
5675
hpke_base_open(enum hpke_kem_id kem_id,enum hpke_kdf_id kdf_id,enum hpke_aead_id aead_id,struct crypto_ec_key * own_priv,const u8 * info,size_t info_len,const u8 * aad,size_t aad_len,const u8 * enc_ct,size_t enc_ct_len)5676 struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
5677 enum hpke_kdf_id kdf_id,
5678 enum hpke_aead_id aead_id,
5679 struct crypto_ec_key *own_priv,
5680 const u8 *info, size_t info_len,
5681 const u8 *aad, size_t aad_len,
5682 const u8 *enc_ct, size_t enc_ct_len)
5683 {
5684 return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
5685 info, info_len, aad, aad_len,
5686 enc_ct, enc_ct_len);
5687 }
5688
5689 #endif /* OpenSSL < 3.2 */
5690
5691 #endif /* CONFIG_DPP3 */
5692
5693
crypto_unload(void)5694 void crypto_unload(void)
5695 {
5696 openssl_unload_legacy_provider();
5697 openssl_unload_default_provider();
5698 }
5699