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] = { 0 };
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_NULL
965 case CRYPTO_CIPHER_NULL:
966 cipher = EVP_enc_null();
967 break;
968 #endif /* OPENSSL_NO_NULL */
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
1884 #ifdef CONFIG_SHA256
pbkdf2_sha256(const char * passphrase,const u8 * salt,size_t salt_len,int iterations,u8 * buf,size_t buflen)1885 int pbkdf2_sha256(const char *passphrase, const u8 *salt, size_t salt_len,
1886 int iterations, u8 *buf, size_t buflen)
1887 {
1888 if (PKCS5_PBKDF2_HMAC(passphrase, os_strlen(passphrase), salt,
1889 salt_len, iterations, EVP_sha256(), buflen,
1890 buf) != 1)
1891 return -1;
1892 return 0;
1893 }
1894 #endif /* CONFIG_SHA256 */
1895
1896
1897 #ifdef CONFIG_SHA384
pbkdf2_sha384(const char * passphrase,const u8 * salt,size_t salt_len,int iterations,u8 * buf,size_t buflen)1898 int pbkdf2_sha384(const char *passphrase, const u8 *salt, size_t salt_len,
1899 int iterations, u8 *buf, size_t buflen)
1900 {
1901 if (PKCS5_PBKDF2_HMAC(passphrase, os_strlen(passphrase), salt,
1902 salt_len, iterations, EVP_sha384(), buflen,
1903 buf) != 1)
1904 return -1;
1905 return 0;
1906 }
1907 #endif /* CONFIG_SHA384 */
1908
1909
crypto_get_random(void * buf,size_t len)1910 int crypto_get_random(void *buf, size_t len)
1911 {
1912 if (RAND_bytes(buf, len) != 1)
1913 return -1;
1914 return 0;
1915 }
1916
1917
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1918 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1919 const u8 *addr[], const size_t *len, u8 *mac)
1920 {
1921 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1922 EVP_MAC_CTX *ctx = NULL;
1923 EVP_MAC *emac;
1924 int ret = -1;
1925 size_t outlen, i;
1926 OSSL_PARAM params[2];
1927 char *cipher = NULL;
1928
1929 if (TEST_FAIL())
1930 return -1;
1931
1932 emac = EVP_MAC_fetch(NULL, "CMAC", NULL);
1933
1934 if (key_len == 32)
1935 cipher = "aes-256-cbc";
1936 else if (key_len == 24)
1937 cipher = "aes-192-cbc";
1938 else if (key_len == 16)
1939 cipher = "aes-128-cbc";
1940
1941 params[0] = OSSL_PARAM_construct_utf8_string("cipher", cipher, 0);
1942 params[1] = OSSL_PARAM_construct_end();
1943
1944 if (!emac || !cipher ||
1945 !(ctx = EVP_MAC_CTX_new(emac)) ||
1946 EVP_MAC_init(ctx, key, key_len, params) != 1) {
1947 wpa_printf(MSG_INFO,
1948 "OpenSSL: EVP_MAC_init(cmac,cipher=%s) failed: %s",
1949 cipher, ERR_error_string(ERR_get_error(), NULL));
1950 goto fail;
1951 }
1952
1953 for (i = 0; i < num_elem; i++) {
1954 if (!EVP_MAC_update(ctx, addr[i], len[i]))
1955 goto fail;
1956 }
1957 if (EVP_MAC_final(ctx, mac, &outlen, 16) != 1 || outlen != 16)
1958 goto fail;
1959
1960 ret = 0;
1961 fail:
1962 EVP_MAC_CTX_free(ctx);
1963 EVP_MAC_free(emac);
1964 return ret;
1965 #else /* OpenSSL version >= 3.0 */
1966 CMAC_CTX *ctx;
1967 int ret = -1;
1968 size_t outlen, i;
1969
1970 if (TEST_FAIL())
1971 return -1;
1972
1973 ctx = CMAC_CTX_new();
1974 if (ctx == NULL)
1975 return -1;
1976
1977 if (key_len == 32) {
1978 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
1979 goto fail;
1980 } else if (key_len == 24) {
1981 if (!CMAC_Init(ctx, key, 24, EVP_aes_192_cbc(), NULL))
1982 goto fail;
1983 } else if (key_len == 16) {
1984 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
1985 goto fail;
1986 } else {
1987 goto fail;
1988 }
1989 for (i = 0; i < num_elem; i++) {
1990 if (!CMAC_Update(ctx, addr[i], len[i]))
1991 goto fail;
1992 }
1993 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
1994 goto fail;
1995
1996 ret = 0;
1997 fail:
1998 CMAC_CTX_free(ctx);
1999 return ret;
2000 #endif /* OpenSSL version >= 3.0 */
2001 }
2002
2003
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)2004 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
2005 const u8 *addr[], const size_t *len, u8 *mac)
2006 {
2007 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
2008 }
2009
2010
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)2011 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
2012 {
2013 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
2014 }
2015
2016
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)2017 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
2018 {
2019 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
2020 }
2021
2022
crypto_bignum_init(void)2023 struct crypto_bignum * crypto_bignum_init(void)
2024 {
2025 if (TEST_FAIL())
2026 return NULL;
2027 return (struct crypto_bignum *) BN_new();
2028 }
2029
2030
crypto_bignum_init_set(const u8 * buf,size_t len)2031 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
2032 {
2033 BIGNUM *bn;
2034
2035 if (TEST_FAIL())
2036 return NULL;
2037
2038 bn = BN_bin2bn(buf, len, NULL);
2039 return (struct crypto_bignum *) bn;
2040 }
2041
2042
crypto_bignum_init_uint(unsigned int val)2043 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
2044 {
2045 BIGNUM *bn;
2046
2047 if (TEST_FAIL())
2048 return NULL;
2049
2050 bn = BN_new();
2051 if (!bn)
2052 return NULL;
2053 if (BN_set_word(bn, val) != 1) {
2054 BN_free(bn);
2055 return NULL;
2056 }
2057 return (struct crypto_bignum *) bn;
2058 }
2059
2060
crypto_bignum_deinit(struct crypto_bignum * n,int clear)2061 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
2062 {
2063 if (clear)
2064 BN_clear_free((BIGNUM *) n);
2065 else
2066 BN_free((BIGNUM *) n);
2067 }
2068
2069
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)2070 int crypto_bignum_to_bin(const struct crypto_bignum *a,
2071 u8 *buf, size_t buflen, size_t padlen)
2072 {
2073 int num_bytes, offset;
2074
2075 if (TEST_FAIL())
2076 return -1;
2077
2078 if (padlen > buflen)
2079 return -1;
2080
2081 if (padlen) {
2082 #ifdef OPENSSL_IS_BORINGSSL
2083 if (BN_bn2bin_padded(buf, padlen, (const BIGNUM *) a) == 0)
2084 return -1;
2085 return padlen;
2086 #else /* OPENSSL_IS_BORINGSSL */
2087 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
2088 return BN_bn2binpad((const BIGNUM *) a, buf, padlen);
2089 #endif
2090 #endif
2091 }
2092
2093 num_bytes = BN_num_bytes((const BIGNUM *) a);
2094 if ((size_t) num_bytes > buflen)
2095 return -1;
2096 if (padlen > (size_t) num_bytes)
2097 offset = padlen - num_bytes;
2098 else
2099 offset = 0;
2100
2101 os_memset(buf, 0, offset);
2102 BN_bn2bin((const BIGNUM *) a, buf + offset);
2103
2104 return num_bytes + offset;
2105 }
2106
2107
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)2108 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
2109 {
2110 if (TEST_FAIL())
2111 return -1;
2112 return BN_rand_range((BIGNUM *) r, (const BIGNUM *) m) == 1 ? 0 : -1;
2113 }
2114
2115
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2116 int crypto_bignum_add(const struct crypto_bignum *a,
2117 const struct crypto_bignum *b,
2118 struct crypto_bignum *c)
2119 {
2120 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
2121 0 : -1;
2122 }
2123
2124
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2125 int crypto_bignum_mod(const struct crypto_bignum *a,
2126 const struct crypto_bignum *b,
2127 struct crypto_bignum *c)
2128 {
2129 int res;
2130 BN_CTX *bnctx;
2131
2132 bnctx = BN_CTX_new();
2133 if (bnctx == NULL)
2134 return -1;
2135 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
2136 bnctx);
2137 BN_CTX_free(bnctx);
2138
2139 return res ? 0 : -1;
2140 }
2141
2142
crypto_bignum_exptmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2143 int crypto_bignum_exptmod(const struct crypto_bignum *a,
2144 const struct crypto_bignum *b,
2145 const struct crypto_bignum *c,
2146 struct crypto_bignum *d)
2147 {
2148 int res;
2149 BN_CTX *bnctx;
2150
2151 if (TEST_FAIL())
2152 return -1;
2153
2154 bnctx = BN_CTX_new();
2155 if (bnctx == NULL)
2156 return -1;
2157 res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
2158 (const BIGNUM *) b, (const BIGNUM *) c,
2159 bnctx, NULL);
2160 BN_CTX_free(bnctx);
2161
2162 return res ? 0 : -1;
2163 }
2164
2165
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2166 int crypto_bignum_inverse(const struct crypto_bignum *a,
2167 const struct crypto_bignum *b,
2168 struct crypto_bignum *c)
2169 {
2170 BIGNUM *res;
2171 BN_CTX *bnctx;
2172
2173 if (TEST_FAIL())
2174 return -1;
2175 bnctx = BN_CTX_new();
2176 if (bnctx == NULL)
2177 return -1;
2178 #ifdef OPENSSL_IS_BORINGSSL
2179 /* TODO: use BN_mod_inverse_blinded() ? */
2180 #else /* OPENSSL_IS_BORINGSSL */
2181 BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
2182 #endif /* OPENSSL_IS_BORINGSSL */
2183 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
2184 (const BIGNUM *) b, bnctx);
2185 BN_CTX_free(bnctx);
2186
2187 return res ? 0 : -1;
2188 }
2189
2190
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2191 int crypto_bignum_sub(const struct crypto_bignum *a,
2192 const struct crypto_bignum *b,
2193 struct crypto_bignum *c)
2194 {
2195 if (TEST_FAIL())
2196 return -1;
2197 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
2198 0 : -1;
2199 }
2200
2201
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2202 int crypto_bignum_div(const struct crypto_bignum *a,
2203 const struct crypto_bignum *b,
2204 struct crypto_bignum *c)
2205 {
2206 int res;
2207
2208 BN_CTX *bnctx;
2209
2210 if (TEST_FAIL())
2211 return -1;
2212
2213 bnctx = BN_CTX_new();
2214 if (bnctx == NULL)
2215 return -1;
2216 #ifndef OPENSSL_IS_BORINGSSL
2217 BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
2218 #endif /* OPENSSL_IS_BORINGSSL */
2219 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
2220 (const BIGNUM *) b, bnctx);
2221 BN_CTX_free(bnctx);
2222
2223 return res ? 0 : -1;
2224 }
2225
2226
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2227 int crypto_bignum_addmod(const struct crypto_bignum *a,
2228 const struct crypto_bignum *b,
2229 const struct crypto_bignum *c,
2230 struct crypto_bignum *d)
2231 {
2232 int res;
2233 BN_CTX *bnctx;
2234
2235 if (TEST_FAIL())
2236 return -1;
2237
2238 bnctx = BN_CTX_new();
2239 if (!bnctx)
2240 return -1;
2241 res = BN_mod_add((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
2242 (const BIGNUM *) c, bnctx);
2243 BN_CTX_free(bnctx);
2244
2245 return res ? 0 : -1;
2246 }
2247
2248
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)2249 int crypto_bignum_mulmod(const struct crypto_bignum *a,
2250 const struct crypto_bignum *b,
2251 const struct crypto_bignum *c,
2252 struct crypto_bignum *d)
2253 {
2254 int res;
2255
2256 BN_CTX *bnctx;
2257
2258 if (TEST_FAIL())
2259 return -1;
2260
2261 bnctx = BN_CTX_new();
2262 if (bnctx == NULL)
2263 return -1;
2264 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
2265 (const BIGNUM *) c, bnctx);
2266 BN_CTX_free(bnctx);
2267
2268 return res ? 0 : -1;
2269 }
2270
2271
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)2272 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
2273 const struct crypto_bignum *b,
2274 struct crypto_bignum *c)
2275 {
2276 int res;
2277 BN_CTX *bnctx;
2278
2279 if (TEST_FAIL())
2280 return -1;
2281
2282 bnctx = BN_CTX_new();
2283 if (!bnctx)
2284 return -1;
2285 res = BN_mod_sqr((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
2286 bnctx);
2287 BN_CTX_free(bnctx);
2288
2289 return res ? 0 : -1;
2290 }
2291
2292
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)2293 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
2294 struct crypto_bignum *r)
2295 {
2296 return BN_rshift((BIGNUM *) r, (const BIGNUM *) a, n) == 1 ? 0 : -1;
2297 }
2298
2299
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)2300 int crypto_bignum_cmp(const struct crypto_bignum *a,
2301 const struct crypto_bignum *b)
2302 {
2303 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
2304 }
2305
2306
crypto_bignum_is_zero(const struct crypto_bignum * a)2307 int crypto_bignum_is_zero(const struct crypto_bignum *a)
2308 {
2309 return BN_is_zero((const BIGNUM *) a);
2310 }
2311
2312
crypto_bignum_is_one(const struct crypto_bignum * a)2313 int crypto_bignum_is_one(const struct crypto_bignum *a)
2314 {
2315 return BN_is_one((const BIGNUM *) a);
2316 }
2317
2318
crypto_bignum_is_odd(const struct crypto_bignum * a)2319 int crypto_bignum_is_odd(const struct crypto_bignum *a)
2320 {
2321 return BN_is_odd((const BIGNUM *) a);
2322 }
2323
2324
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)2325 int crypto_bignum_legendre(const struct crypto_bignum *a,
2326 const struct crypto_bignum *p)
2327 {
2328 BN_CTX *bnctx;
2329 BIGNUM *exp = NULL, *tmp = NULL;
2330 int res = -2;
2331 unsigned int mask;
2332
2333 if (TEST_FAIL())
2334 return -2;
2335
2336 bnctx = BN_CTX_new();
2337 if (bnctx == NULL)
2338 return -2;
2339
2340 exp = BN_new();
2341 tmp = BN_new();
2342 if (!exp || !tmp ||
2343 /* exp = (p-1) / 2 */
2344 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
2345 !BN_rshift1(exp, exp) ||
2346 !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
2347 (const BIGNUM *) p, bnctx, NULL))
2348 goto fail;
2349
2350 /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
2351 * constant time selection to avoid branches here. */
2352 res = -1;
2353 mask = const_time_eq(BN_is_word(tmp, 1), 1);
2354 res = const_time_select_int(mask, 1, res);
2355 mask = const_time_eq(BN_is_zero(tmp), 1);
2356 res = const_time_select_int(mask, 0, res);
2357
2358 fail:
2359 BN_clear_free(tmp);
2360 BN_clear_free(exp);
2361 BN_CTX_free(bnctx);
2362 return res;
2363 }
2364
2365
2366 #ifdef CONFIG_ECC
2367
2368 struct crypto_ec {
2369 EC_GROUP *group;
2370 int nid;
2371 int iana_group;
2372 BN_CTX *bnctx;
2373 BIGNUM *prime;
2374 BIGNUM *order;
2375 BIGNUM *a;
2376 BIGNUM *b;
2377 };
2378
2379
crypto_ec_group_2_nid(int group)2380 static int crypto_ec_group_2_nid(int group)
2381 {
2382 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
2383 switch (group) {
2384 case 19:
2385 return NID_X9_62_prime256v1;
2386 case 20:
2387 return NID_secp384r1;
2388 case 21:
2389 return NID_secp521r1;
2390 case 25:
2391 return NID_X9_62_prime192v1;
2392 case 26:
2393 return NID_secp224r1;
2394 #ifdef NID_brainpoolP224r1
2395 case 27:
2396 return NID_brainpoolP224r1;
2397 #endif /* NID_brainpoolP224r1 */
2398 #ifdef NID_brainpoolP256r1
2399 case 28:
2400 return NID_brainpoolP256r1;
2401 #endif /* NID_brainpoolP256r1 */
2402 #ifdef NID_brainpoolP384r1
2403 case 29:
2404 return NID_brainpoolP384r1;
2405 #endif /* NID_brainpoolP384r1 */
2406 #ifdef NID_brainpoolP512r1
2407 case 30:
2408 return NID_brainpoolP512r1;
2409 #endif /* NID_brainpoolP512r1 */
2410 default:
2411 return -1;
2412 }
2413 }
2414
2415
2416 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
crypto_ec_group_2_name(int group)2417 static const char * crypto_ec_group_2_name(int group)
2418 {
2419 /* Map from IANA registry for IKE D-H groups to OpenSSL group name */
2420 switch (group) {
2421 case 19:
2422 return "prime256v1";
2423 case 20:
2424 return "secp384r1";
2425 case 21:
2426 return "secp521r1";
2427 case 25:
2428 return "prime192v1";
2429 case 26:
2430 return "secp224r1";
2431 #ifdef NID_brainpoolP224r1
2432 case 27:
2433 return "brainpoolP224r1";
2434 #endif /* NID_brainpoolP224r1 */
2435 #ifdef NID_brainpoolP256r1
2436 case 28:
2437 return "brainpoolP256r1";
2438 #endif /* NID_brainpoolP256r1 */
2439 #ifdef NID_brainpoolP384r1
2440 case 29:
2441 return "brainpoolP384r1";
2442 #endif /* NID_brainpoolP384r1 */
2443 #ifdef NID_brainpoolP512r1
2444 case 30:
2445 return "brainpoolP512r1";
2446 #endif /* NID_brainpoolP512r1 */
2447 default:
2448 return NULL;
2449 }
2450 }
2451 #endif /* OpenSSL version >= 3.0 */
2452
2453
crypto_ec_init(int group)2454 struct crypto_ec * crypto_ec_init(int group)
2455 {
2456 struct crypto_ec *e;
2457 int nid;
2458
2459 nid = crypto_ec_group_2_nid(group);
2460 if (nid < 0)
2461 return NULL;
2462
2463 e = os_zalloc(sizeof(*e));
2464 if (e == NULL)
2465 return NULL;
2466
2467 e->nid = nid;
2468 e->iana_group = group;
2469 e->bnctx = BN_CTX_new();
2470 e->group = EC_GROUP_new_by_curve_name(nid);
2471 e->prime = BN_new();
2472 e->order = BN_new();
2473 e->a = BN_new();
2474 e->b = BN_new();
2475 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
2476 e->order == NULL || e->a == NULL || e->b == NULL ||
2477 !EC_GROUP_get_curve(e->group, e->prime, e->a, e->b, e->bnctx) ||
2478 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
2479 crypto_ec_deinit(e);
2480 e = NULL;
2481 }
2482
2483 return e;
2484 }
2485
2486
crypto_ec_deinit(struct crypto_ec * e)2487 void crypto_ec_deinit(struct crypto_ec *e)
2488 {
2489 if (e == NULL)
2490 return;
2491 BN_clear_free(e->b);
2492 BN_clear_free(e->a);
2493 BN_clear_free(e->order);
2494 BN_clear_free(e->prime);
2495 EC_GROUP_free(e->group);
2496 BN_CTX_free(e->bnctx);
2497 os_free(e);
2498 }
2499
2500
crypto_ec_point_init(struct crypto_ec * e)2501 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
2502 {
2503 if (TEST_FAIL())
2504 return NULL;
2505 if (e == NULL)
2506 return NULL;
2507 return (struct crypto_ec_point *) EC_POINT_new(e->group);
2508 }
2509
2510
crypto_ec_prime_len(struct crypto_ec * e)2511 size_t crypto_ec_prime_len(struct crypto_ec *e)
2512 {
2513 return BN_num_bytes(e->prime);
2514 }
2515
2516
crypto_ec_prime_len_bits(struct crypto_ec * e)2517 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
2518 {
2519 return BN_num_bits(e->prime);
2520 }
2521
2522
crypto_ec_order_len(struct crypto_ec * e)2523 size_t crypto_ec_order_len(struct crypto_ec *e)
2524 {
2525 return BN_num_bytes(e->order);
2526 }
2527
2528
crypto_ec_get_prime(struct crypto_ec * e)2529 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
2530 {
2531 return (const struct crypto_bignum *) e->prime;
2532 }
2533
2534
crypto_ec_get_order(struct crypto_ec * e)2535 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
2536 {
2537 return (const struct crypto_bignum *) e->order;
2538 }
2539
2540
crypto_ec_get_a(struct crypto_ec * e)2541 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
2542 {
2543 return (const struct crypto_bignum *) e->a;
2544 }
2545
2546
crypto_ec_get_b(struct crypto_ec * e)2547 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
2548 {
2549 return (const struct crypto_bignum *) e->b;
2550 }
2551
2552
crypto_ec_get_generator(struct crypto_ec * e)2553 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
2554 {
2555 return (const struct crypto_ec_point *)
2556 EC_GROUP_get0_generator(e->group);
2557 }
2558
2559
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)2560 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
2561 {
2562 if (clear)
2563 EC_POINT_clear_free((EC_POINT *) p);
2564 else
2565 EC_POINT_free((EC_POINT *) p);
2566 }
2567
2568
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)2569 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
2570 struct crypto_bignum *x)
2571 {
2572 return EC_POINT_get_affine_coordinates(e->group,
2573 (const EC_POINT *) p,
2574 (BIGNUM *) x, NULL,
2575 e->bnctx) == 1 ? 0 : -1;
2576 }
2577
2578
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)2579 int crypto_ec_point_to_bin(struct crypto_ec *e,
2580 const struct crypto_ec_point *point, u8 *x, u8 *y)
2581 {
2582 BIGNUM *x_bn, *y_bn;
2583 int ret = -1;
2584 int len = BN_num_bytes(e->prime);
2585
2586 if (TEST_FAIL())
2587 return -1;
2588
2589 x_bn = BN_new();
2590 y_bn = BN_new();
2591
2592 if (x_bn && y_bn &&
2593 EC_POINT_get_affine_coordinates(e->group, (EC_POINT *) point,
2594 x_bn, y_bn, e->bnctx)) {
2595 if (x) {
2596 ret = crypto_bignum_to_bin(
2597 (struct crypto_bignum *) x_bn, x, len, len);
2598 }
2599 if (ret >= 0 && y) {
2600 ret = crypto_bignum_to_bin(
2601 (struct crypto_bignum *) y_bn, y, len, len);
2602 }
2603
2604 if (ret > 0)
2605 ret = 0;
2606 }
2607
2608 BN_clear_free(x_bn);
2609 BN_clear_free(y_bn);
2610 return ret;
2611 }
2612
2613
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)2614 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
2615 const u8 *val)
2616 {
2617 BIGNUM *x, *y;
2618 EC_POINT *elem;
2619 int len = BN_num_bytes(e->prime);
2620
2621 if (TEST_FAIL())
2622 return NULL;
2623
2624 x = BN_bin2bn(val, len, NULL);
2625 y = BN_bin2bn(val + len, len, NULL);
2626 elem = EC_POINT_new(e->group);
2627 if (x == NULL || y == NULL || elem == NULL) {
2628 BN_clear_free(x);
2629 BN_clear_free(y);
2630 EC_POINT_clear_free(elem);
2631 return NULL;
2632 }
2633
2634 if (!EC_POINT_set_affine_coordinates(e->group, elem, x, y, e->bnctx)) {
2635 EC_POINT_clear_free(elem);
2636 elem = NULL;
2637 }
2638
2639 BN_clear_free(x);
2640 BN_clear_free(y);
2641
2642 return (struct crypto_ec_point *) elem;
2643 }
2644
2645
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)2646 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
2647 const struct crypto_ec_point *b,
2648 struct crypto_ec_point *c)
2649 {
2650 if (TEST_FAIL())
2651 return -1;
2652 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
2653 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
2654 }
2655
2656
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2657 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2658 const struct crypto_bignum *b,
2659 struct crypto_ec_point *res)
2660 {
2661 if (TEST_FAIL())
2662 return -1;
2663 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
2664 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
2665 ? 0 : -1;
2666 }
2667
2668
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2669 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2670 {
2671 if (TEST_FAIL())
2672 return -1;
2673 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
2674 }
2675
2676
2677 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2678 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2679 const struct crypto_bignum *x)
2680 {
2681 BIGNUM *tmp;
2682
2683 if (TEST_FAIL())
2684 return NULL;
2685
2686 tmp = BN_new();
2687
2688 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2689 if (tmp &&
2690 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
2691 BN_mod_add_quick(tmp, e->a, tmp, e->prime) &&
2692 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
2693 BN_mod_add_quick(tmp, tmp, e->b, e->prime))
2694 return (struct crypto_bignum *) tmp;
2695
2696 BN_clear_free(tmp);
2697 return NULL;
2698 }
2699
2700
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2701 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2702 const struct crypto_ec_point *p)
2703 {
2704 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
2705 }
2706
2707
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2708 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2709 const struct crypto_ec_point *p)
2710 {
2711 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
2712 e->bnctx) == 1;
2713 }
2714
2715
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2716 int crypto_ec_point_cmp(const struct crypto_ec *e,
2717 const struct crypto_ec_point *a,
2718 const struct crypto_ec_point *b)
2719 {
2720 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
2721 (const EC_POINT *) b, e->bnctx);
2722 }
2723
2724
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2725 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2726 const struct crypto_ec_point *p,
2727 const char *title)
2728 {
2729 BIGNUM *x, *y;
2730 char *x_str = NULL, *y_str = NULL;
2731
2732 x = BN_new();
2733 y = BN_new();
2734 if (!x || !y ||
2735 EC_POINT_get_affine_coordinates(e->group, (const EC_POINT *) p,
2736 x, y, e->bnctx) != 1)
2737 goto fail;
2738
2739 x_str = BN_bn2hex(x);
2740 y_str = BN_bn2hex(y);
2741 if (!x_str || !y_str)
2742 goto fail;
2743
2744 wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
2745
2746 fail:
2747 OPENSSL_free(x_str);
2748 OPENSSL_free(y_str);
2749 BN_free(x);
2750 BN_free(y);
2751 }
2752
2753
2754 struct crypto_ecdh {
2755 struct crypto_ec *ec;
2756 EVP_PKEY *pkey;
2757 };
2758
crypto_ecdh_init(int group)2759 struct crypto_ecdh * crypto_ecdh_init(int group)
2760 {
2761 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2762 struct crypto_ecdh *ecdh;
2763 const char *name;
2764
2765 ecdh = os_zalloc(sizeof(*ecdh));
2766 if (!ecdh)
2767 goto fail;
2768
2769 ecdh->ec = crypto_ec_init(group);
2770 if (!ecdh->ec)
2771 goto fail;
2772
2773 name = OSSL_EC_curve_nid2name(ecdh->ec->nid);
2774 if (!name)
2775 goto fail;
2776
2777 ecdh->pkey = EVP_EC_gen(name);
2778 if (!ecdh->pkey) {
2779 wpa_printf(MSG_INFO,
2780 "OpenSSL: EVP_EC_gen(group=%d) failed: %s",
2781 group, ERR_error_string(ERR_get_error(), NULL));
2782 goto fail;
2783 }
2784
2785 done:
2786 return ecdh;
2787 fail:
2788 crypto_ecdh_deinit(ecdh);
2789 ecdh = NULL;
2790 goto done;
2791 #else /* OpenSSL version >= 3.0 */
2792 struct crypto_ecdh *ecdh;
2793 EVP_PKEY *params = NULL;
2794 EC_KEY *ec_params = NULL;
2795 EVP_PKEY_CTX *kctx = NULL;
2796
2797 ecdh = os_zalloc(sizeof(*ecdh));
2798 if (!ecdh)
2799 goto fail;
2800
2801 ecdh->ec = crypto_ec_init(group);
2802 if (!ecdh->ec)
2803 goto fail;
2804
2805 ec_params = EC_KEY_new_by_curve_name(ecdh->ec->nid);
2806 if (!ec_params) {
2807 wpa_printf(MSG_ERROR,
2808 "OpenSSL: Failed to generate EC_KEY parameters");
2809 goto fail;
2810 }
2811 EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
2812 params = EVP_PKEY_new();
2813 if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
2814 wpa_printf(MSG_ERROR,
2815 "OpenSSL: Failed to generate EVP_PKEY parameters");
2816 goto fail;
2817 }
2818
2819 kctx = EVP_PKEY_CTX_new(params, NULL);
2820 if (!kctx)
2821 goto fail;
2822
2823 if (EVP_PKEY_keygen_init(kctx) != 1) {
2824 wpa_printf(MSG_ERROR,
2825 "OpenSSL: EVP_PKEY_keygen_init failed: %s",
2826 ERR_error_string(ERR_get_error(), NULL));
2827 goto fail;
2828 }
2829
2830 if (EVP_PKEY_keygen(kctx, &ecdh->pkey) != 1) {
2831 wpa_printf(MSG_ERROR, "OpenSSL: EVP_PKEY_keygen failed: %s",
2832 ERR_error_string(ERR_get_error(), NULL));
2833 goto fail;
2834 }
2835
2836 done:
2837 EC_KEY_free(ec_params);
2838 EVP_PKEY_free(params);
2839 EVP_PKEY_CTX_free(kctx);
2840
2841 return ecdh;
2842 fail:
2843 crypto_ecdh_deinit(ecdh);
2844 ecdh = NULL;
2845 goto done;
2846 #endif /* OpenSSL version >= 3.0 */
2847 }
2848
2849
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2850 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2851 {
2852 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2853 struct crypto_ecdh *ecdh;
2854
2855 ecdh = os_zalloc(sizeof(*ecdh));
2856 if (!ecdh)
2857 goto fail;
2858
2859 ecdh->ec = crypto_ec_init(group);
2860 if (!ecdh->ec)
2861 goto fail;
2862
2863 ecdh->pkey = EVP_PKEY_dup((EVP_PKEY *) own_key);
2864 if (!ecdh->pkey)
2865 goto fail;
2866
2867 return ecdh;
2868 fail:
2869 crypto_ecdh_deinit(ecdh);
2870 return NULL;
2871 #else /* OpenSSL version >= 3.0 */
2872 struct crypto_ecdh *ecdh;
2873
2874 ecdh = os_zalloc(sizeof(*ecdh));
2875 if (!ecdh)
2876 goto fail;
2877
2878 ecdh->ec = crypto_ec_init(group);
2879 if (!ecdh->ec)
2880 goto fail;
2881
2882 ecdh->pkey = EVP_PKEY_new();
2883 if (!ecdh->pkey ||
2884 EVP_PKEY_assign_EC_KEY(ecdh->pkey,
2885 EVP_PKEY_get1_EC_KEY((EVP_PKEY *) own_key))
2886 != 1)
2887 goto fail;
2888
2889 return ecdh;
2890 fail:
2891 crypto_ecdh_deinit(ecdh);
2892 return NULL;
2893 #endif /* OpenSSL version >= 3.0 */
2894 }
2895
2896
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2897 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2898 {
2899 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2900 struct wpabuf *buf = NULL;
2901 unsigned char *pub;
2902 size_t len, exp_len;
2903
2904 len = EVP_PKEY_get1_encoded_public_key(ecdh->pkey, &pub);
2905 if (len == 0)
2906 return NULL;
2907
2908 /* Encoded using SECG SEC 1, Sec. 2.3.4 format */
2909 exp_len = 1 + 2 * crypto_ec_prime_len(ecdh->ec);
2910 if (len != exp_len) {
2911 wpa_printf(MSG_ERROR,
2912 "OpenSSL:%s: Unexpected encoded public key length %zu (expected %zu)",
2913 __func__, len, exp_len);
2914 goto fail;
2915 }
2916 buf = wpabuf_alloc_copy(pub + 1, inc_y ? len - 1 : len / 2);
2917 fail:
2918 OPENSSL_free(pub);
2919 return buf;
2920 #else /* OpenSSL version >= 3.0 */
2921 struct wpabuf *buf = NULL;
2922 EC_KEY *eckey;
2923 const EC_POINT *pubkey;
2924 BIGNUM *x, *y = NULL;
2925 int len = BN_num_bytes(ecdh->ec->prime);
2926 int res;
2927
2928 eckey = EVP_PKEY_get1_EC_KEY(ecdh->pkey);
2929 if (!eckey)
2930 return NULL;
2931
2932 pubkey = EC_KEY_get0_public_key(eckey);
2933 if (!pubkey)
2934 return NULL;
2935
2936 x = BN_new();
2937 if (inc_y) {
2938 y = BN_new();
2939 if (!y)
2940 goto fail;
2941 }
2942 buf = wpabuf_alloc(inc_y ? 2 * len : len);
2943 if (!x || !buf)
2944 goto fail;
2945
2946 if (EC_POINT_get_affine_coordinates(ecdh->ec->group, pubkey,
2947 x, y, ecdh->ec->bnctx) != 1) {
2948 wpa_printf(MSG_ERROR,
2949 "OpenSSL: EC_POINT_get_affine_coordinates failed: %s",
2950 ERR_error_string(ERR_get_error(), NULL));
2951 goto fail;
2952 }
2953
2954 res = crypto_bignum_to_bin((struct crypto_bignum *) x,
2955 wpabuf_put(buf, len), len, len);
2956 if (res < 0)
2957 goto fail;
2958
2959 if (inc_y) {
2960 res = crypto_bignum_to_bin((struct crypto_bignum *) y,
2961 wpabuf_put(buf, len), len, len);
2962 if (res < 0)
2963 goto fail;
2964 }
2965
2966 done:
2967 BN_clear_free(x);
2968 BN_clear_free(y);
2969 EC_KEY_free(eckey);
2970
2971 return buf;
2972 fail:
2973 wpabuf_free(buf);
2974 buf = NULL;
2975 goto done;
2976 #endif /* OpenSSL version >= 3.0 */
2977 }
2978
2979
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2980 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2981 const u8 *key, size_t len)
2982 {
2983 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2984 EVP_PKEY *peerkey = EVP_PKEY_new();
2985 EVP_PKEY_CTX *ctx;
2986 size_t res_len;
2987 struct wpabuf *res = NULL;
2988 u8 *peer;
2989
2990 /* Encode using SECG SEC 1, Sec. 2.3.4 format */
2991 peer = os_malloc(1 + len);
2992 if (!peer) {
2993 EVP_PKEY_free(peerkey);
2994 return NULL;
2995 }
2996 peer[0] = inc_y ? 0x04 : 0x02;
2997 os_memcpy(peer + 1, key, len);
2998
2999 if (!peerkey ||
3000 EVP_PKEY_copy_parameters(peerkey, ecdh->pkey) != 1 ||
3001 EVP_PKEY_set1_encoded_public_key(peerkey, peer, 1 + len) != 1) {
3002 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_set1_encoded_public_key failed: %s",
3003 ERR_error_string(ERR_get_error(), NULL));
3004 EVP_PKEY_free(peerkey);
3005 os_free(peer);
3006 return NULL;
3007 }
3008 os_free(peer);
3009
3010 ctx = EVP_PKEY_CTX_new(ecdh->pkey, NULL);
3011 if (!ctx ||
3012 EVP_PKEY_derive_init(ctx) != 1 ||
3013 EVP_PKEY_derive_set_peer(ctx, peerkey) != 1 ||
3014 EVP_PKEY_derive(ctx, NULL, &res_len) != 1 ||
3015 !(res = wpabuf_alloc(res_len)) ||
3016 EVP_PKEY_derive(ctx, wpabuf_mhead(res), &res_len) != 1) {
3017 wpa_printf(MSG_INFO, "OpenSSL: EVP_PKEY_derive failed: %s",
3018 ERR_error_string(ERR_get_error(), NULL));
3019 wpabuf_free(res);
3020 res = NULL;
3021 } else {
3022 wpabuf_put(res, res_len);
3023 }
3024
3025 EVP_PKEY_free(peerkey);
3026 EVP_PKEY_CTX_free(ctx);
3027 return res;
3028 #else /* OpenSSL version >= 3.0 */
3029 BIGNUM *x, *y = NULL;
3030 EVP_PKEY_CTX *ctx = NULL;
3031 EVP_PKEY *peerkey = NULL;
3032 struct wpabuf *secret = NULL;
3033 size_t secret_len;
3034 EC_POINT *pub;
3035 EC_KEY *eckey = NULL;
3036
3037 x = BN_bin2bn(key, inc_y ? len / 2 : len, NULL);
3038 pub = EC_POINT_new(ecdh->ec->group);
3039 if (!x || !pub)
3040 goto fail;
3041
3042 if (inc_y) {
3043 y = BN_bin2bn(key + len / 2, len / 2, NULL);
3044 if (!y)
3045 goto fail;
3046 if (!EC_POINT_set_affine_coordinates(ecdh->ec->group, pub,
3047 x, y, ecdh->ec->bnctx)) {
3048 wpa_printf(MSG_ERROR,
3049 "OpenSSL: EC_POINT_set_affine_coordinates failed: %s",
3050 ERR_error_string(ERR_get_error(), NULL));
3051 goto fail;
3052 }
3053 } else if (!EC_POINT_set_compressed_coordinates(ecdh->ec->group,
3054 pub, x, 0,
3055 ecdh->ec->bnctx)) {
3056 wpa_printf(MSG_ERROR,
3057 "OpenSSL: EC_POINT_set_compressed_coordinates failed: %s",
3058 ERR_error_string(ERR_get_error(), NULL));
3059 goto fail;
3060 }
3061
3062 if (!EC_POINT_is_on_curve(ecdh->ec->group, pub, ecdh->ec->bnctx)) {
3063 wpa_printf(MSG_ERROR,
3064 "OpenSSL: ECDH peer public key is not on curve");
3065 goto fail;
3066 }
3067
3068 eckey = EC_KEY_new_by_curve_name(ecdh->ec->nid);
3069 if (!eckey || EC_KEY_set_public_key(eckey, pub) != 1) {
3070 wpa_printf(MSG_ERROR,
3071 "OpenSSL: EC_KEY_set_public_key failed: %s",
3072 ERR_error_string(ERR_get_error(), NULL));
3073 goto fail;
3074 }
3075
3076 peerkey = EVP_PKEY_new();
3077 if (!peerkey || EVP_PKEY_set1_EC_KEY(peerkey, eckey) != 1)
3078 goto fail;
3079
3080 ctx = EVP_PKEY_CTX_new(ecdh->pkey, NULL);
3081 if (!ctx || EVP_PKEY_derive_init(ctx) != 1 ||
3082 EVP_PKEY_derive_set_peer(ctx, peerkey) != 1 ||
3083 EVP_PKEY_derive(ctx, NULL, &secret_len) != 1) {
3084 wpa_printf(MSG_ERROR,
3085 "OpenSSL: EVP_PKEY_derive(1) failed: %s",
3086 ERR_error_string(ERR_get_error(), NULL));
3087 goto fail;
3088 }
3089
3090 secret = wpabuf_alloc(secret_len);
3091 if (!secret)
3092 goto fail;
3093 if (EVP_PKEY_derive(ctx, wpabuf_put(secret, 0), &secret_len) != 1) {
3094 wpa_printf(MSG_ERROR,
3095 "OpenSSL: EVP_PKEY_derive(2) failed: %s",
3096 ERR_error_string(ERR_get_error(), NULL));
3097 goto fail;
3098 }
3099 if (secret->size != secret_len)
3100 wpa_printf(MSG_DEBUG,
3101 "OpenSSL: EVP_PKEY_derive(2) changed secret_len %d -> %d",
3102 (int) secret->size, (int) secret_len);
3103 wpabuf_put(secret, secret_len);
3104
3105 done:
3106 BN_free(x);
3107 BN_free(y);
3108 EC_KEY_free(eckey);
3109 EC_POINT_free(pub);
3110 EVP_PKEY_CTX_free(ctx);
3111 EVP_PKEY_free(peerkey);
3112 return secret;
3113 fail:
3114 wpabuf_free(secret);
3115 secret = NULL;
3116 goto done;
3117 #endif /* OpenSSL version >= 3.0 */
3118 }
3119
3120
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)3121 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
3122 {
3123 if (ecdh) {
3124 crypto_ec_deinit(ecdh->ec);
3125 EVP_PKEY_free(ecdh->pkey);
3126 os_free(ecdh);
3127 }
3128 }
3129
3130
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)3131 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
3132 {
3133 return crypto_ec_prime_len(ecdh->ec);
3134 }
3135
3136
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)3137 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
3138 {
3139 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3140 EVP_PKEY *pkey = NULL;
3141 OSSL_DECODER_CTX *ctx;
3142
3143 ctx = OSSL_DECODER_CTX_new_for_pkey(
3144 &pkey, "DER", NULL, "EC",
3145 OSSL_KEYMGMT_SELECT_KEYPAIR |
3146 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
3147 NULL, NULL);
3148 if (!ctx ||
3149 OSSL_DECODER_from_data(ctx, &der, &der_len) != 1) {
3150 wpa_printf(MSG_INFO,
3151 "OpenSSL: Decoding EC private key (DER) failed: %s",
3152 ERR_error_string(ERR_get_error(), NULL));
3153 if (ctx)
3154 OSSL_DECODER_CTX_free(ctx);
3155 goto fail;
3156 }
3157
3158 OSSL_DECODER_CTX_free(ctx);
3159 return (struct crypto_ec_key *) pkey;
3160 fail:
3161 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3162 return NULL;
3163 #else /* OpenSSL version >= 3.0 */
3164 EVP_PKEY *pkey = NULL;
3165 EC_KEY *eckey;
3166
3167 eckey = d2i_ECPrivateKey(NULL, &der, der_len);
3168 if (!eckey) {
3169 wpa_printf(MSG_INFO, "OpenSSL: d2i_ECPrivateKey() failed: %s",
3170 ERR_error_string(ERR_get_error(), NULL));
3171 goto fail;
3172 }
3173 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3174
3175 pkey = EVP_PKEY_new();
3176 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3177 EC_KEY_free(eckey);
3178 goto fail;
3179 }
3180
3181 return (struct crypto_ec_key *) pkey;
3182 fail:
3183 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3184 return NULL;
3185 #endif /* OpenSSL version >= 3.0 */
3186 }
3187
3188
crypto_ec_key_set_priv(int group,const u8 * raw,size_t raw_len)3189 struct crypto_ec_key * crypto_ec_key_set_priv(int group,
3190 const u8 *raw, size_t raw_len)
3191 {
3192 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3193 const char *group_name;
3194 OSSL_PARAM params[4];
3195 EVP_PKEY_CTX *ctx = NULL;
3196 EVP_PKEY *pkey = NULL;
3197 BIGNUM *priv;
3198 EC_POINT *pub = NULL;
3199 EC_GROUP *ec_group = NULL;
3200 size_t len;
3201 u8 *pub_bin = NULL;
3202 u8 *priv_bin = NULL;
3203 int priv_bin_len;
3204
3205 group_name = crypto_ec_group_2_name(group);
3206 if (!group_name)
3207 return NULL;
3208
3209 priv = BN_bin2bn(raw, raw_len, NULL);
3210 if (!priv)
3211 return NULL;
3212 priv_bin = os_malloc(raw_len);
3213 if (!priv_bin)
3214 goto fail;
3215 priv_bin_len = BN_bn2lebinpad(priv, priv_bin, raw_len);
3216 if (priv_bin_len < 0)
3217 goto fail;
3218
3219 ec_group = EC_GROUP_new_by_curve_name(crypto_ec_group_2_nid(group));
3220 if (!ec_group)
3221 goto fail;
3222 pub = EC_POINT_new(ec_group);
3223 if (!pub ||
3224 EC_POINT_mul(ec_group, pub, priv, NULL, NULL, NULL) != 1)
3225 goto fail;
3226 len = EC_POINT_point2oct(ec_group, pub, POINT_CONVERSION_UNCOMPRESSED,
3227 NULL, 0, NULL);
3228 if (len == 0)
3229 goto fail;
3230 pub_bin = os_malloc(len);
3231 if (!pub_bin)
3232 goto fail;
3233 len = EC_POINT_point2oct(ec_group, pub, POINT_CONVERSION_UNCOMPRESSED,
3234 pub_bin, len, NULL);
3235 if (len == 0)
3236 goto fail;
3237
3238 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3239 (char *) group_name, 0);
3240 params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY,
3241 priv_bin, priv_bin_len);
3242 params[2] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
3243 pub_bin, len);
3244 params[3] = OSSL_PARAM_construct_end();
3245
3246 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3247 if (!ctx ||
3248 EVP_PKEY_fromdata_init(ctx) <= 0 ||
3249 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
3250 goto fail;
3251
3252 out:
3253 bin_clear_free(priv_bin, raw_len);
3254 os_free(pub_bin);
3255 BN_clear_free(priv);
3256 EVP_PKEY_CTX_free(ctx);
3257 EC_POINT_free(pub);
3258 EC_GROUP_free(ec_group);
3259 return (struct crypto_ec_key *) pkey;
3260
3261 fail:
3262 EVP_PKEY_free(pkey);
3263 pkey = NULL;
3264 goto out;
3265 #else /* OpenSSL version >= 3.0 */
3266 EC_KEY *eckey = NULL;
3267 EVP_PKEY *pkey = NULL;
3268 BIGNUM *priv = NULL;
3269 int nid;
3270 const EC_GROUP *ec_group;
3271 EC_POINT *pub = NULL;
3272
3273 nid = crypto_ec_group_2_nid(group);
3274 if (nid < 0) {
3275 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3276 return NULL;
3277 }
3278
3279 eckey = EC_KEY_new_by_curve_name(nid);
3280 priv = BN_bin2bn(raw, raw_len, NULL);
3281 if (!eckey || !priv ||
3282 EC_KEY_set_private_key(eckey, priv) != 1) {
3283 wpa_printf(MSG_ERROR,
3284 "OpenSSL: Failed to set EC_KEY: %s",
3285 ERR_error_string(ERR_get_error(), NULL));
3286 goto fail;
3287 }
3288
3289 ec_group = EC_KEY_get0_group(eckey);
3290 if (!ec_group)
3291 goto fail;
3292 pub = EC_POINT_new(ec_group);
3293 if (!pub ||
3294 EC_POINT_mul(ec_group, pub, priv, NULL, NULL, NULL) != 1 ||
3295 EC_KEY_set_public_key(eckey, pub) != 1) {
3296 wpa_printf(MSG_ERROR,
3297 "OpenSSL: Failed to set EC_KEY(pub): %s",
3298 ERR_error_string(ERR_get_error(), NULL));
3299 goto fail;
3300 }
3301
3302 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3303
3304 pkey = EVP_PKEY_new();
3305 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3306 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3307 goto fail;
3308 }
3309
3310 out:
3311 BN_clear_free(priv);
3312 EC_POINT_free(pub);
3313 return (struct crypto_ec_key *) pkey;
3314
3315 fail:
3316 EC_KEY_free(eckey);
3317 EVP_PKEY_free(pkey);
3318 pkey = NULL;
3319 goto out;
3320 #endif /* OpenSSL version >= 3.0 */
3321 }
3322
3323
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)3324 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
3325 {
3326 EVP_PKEY *pkey;
3327
3328 pkey = d2i_PUBKEY(NULL, &der, der_len);
3329 if (!pkey) {
3330 wpa_printf(MSG_INFO, "OpenSSL: d2i_PUBKEY() failed: %s",
3331 ERR_error_string(ERR_get_error(), NULL));
3332 goto fail;
3333 }
3334
3335 /* Ensure this is an EC key */
3336 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3337 if (!EVP_PKEY_is_a(pkey, "EC"))
3338 goto fail;
3339 #else /* OpenSSL version >= 3.0 */
3340 if (!EVP_PKEY_get0_EC_KEY(pkey))
3341 goto fail;
3342 #endif /* OpenSSL version >= 3.0 */
3343 return (struct crypto_ec_key *) pkey;
3344 fail:
3345 crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
3346 return NULL;
3347 }
3348
3349
crypto_ec_key_set_pub(int group,const u8 * buf_x,const u8 * buf_y,size_t len)3350 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *buf_x,
3351 const u8 *buf_y, size_t len)
3352 {
3353 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3354 const char *group_name;
3355 OSSL_PARAM params[3];
3356 u8 *pub;
3357 EVP_PKEY_CTX *ctx;
3358 EVP_PKEY *pkey = NULL;
3359
3360 group_name = crypto_ec_group_2_name(group);
3361 if (!group_name)
3362 return NULL;
3363
3364 pub = os_malloc(1 + len * 2);
3365 if (!pub)
3366 return NULL;
3367 pub[0] = 0x04; /* uncompressed */
3368 os_memcpy(pub + 1, buf_x, len);
3369 os_memcpy(pub + 1 + len, buf_y, len);
3370
3371 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3372 (char *) group_name, 0);
3373 params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
3374 pub, 1 + len * 2);
3375 params[2] = OSSL_PARAM_construct_end();
3376
3377 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3378 if (!ctx) {
3379 os_free(pub);
3380 return NULL;
3381 }
3382 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
3383 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
3384 os_free(pub);
3385 EVP_PKEY_CTX_free(ctx);
3386 return NULL;
3387 }
3388
3389 os_free(pub);
3390 EVP_PKEY_CTX_free(ctx);
3391
3392 return (struct crypto_ec_key *) pkey;
3393 #else /* OpenSSL version >= 3.0 */
3394 EC_KEY *eckey = NULL;
3395 EVP_PKEY *pkey = NULL;
3396 EC_GROUP *ec_group = NULL;
3397 BN_CTX *ctx;
3398 EC_POINT *point = NULL;
3399 BIGNUM *x = NULL, *y = NULL;
3400 int nid;
3401
3402 if (!buf_x || !buf_y)
3403 return NULL;
3404
3405 nid = crypto_ec_group_2_nid(group);
3406 if (nid < 0) {
3407 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3408 return NULL;
3409 }
3410
3411 ctx = BN_CTX_new();
3412 if (!ctx)
3413 goto fail;
3414
3415 ec_group = EC_GROUP_new_by_curve_name(nid);
3416 if (!ec_group)
3417 goto fail;
3418
3419 x = BN_bin2bn(buf_x, len, NULL);
3420 y = BN_bin2bn(buf_y, len, NULL);
3421 point = EC_POINT_new(ec_group);
3422 if (!x || !y || !point)
3423 goto fail;
3424
3425 if (!EC_POINT_set_affine_coordinates(ec_group, point, x, y, ctx)) {
3426 wpa_printf(MSG_ERROR,
3427 "OpenSSL: EC_POINT_set_affine_coordinates failed: %s",
3428 ERR_error_string(ERR_get_error(), NULL));
3429 goto fail;
3430 }
3431
3432 if (!EC_POINT_is_on_curve(ec_group, point, ctx) ||
3433 EC_POINT_is_at_infinity(ec_group, point)) {
3434 wpa_printf(MSG_ERROR, "OpenSSL: Invalid point");
3435 goto fail;
3436 }
3437
3438 eckey = EC_KEY_new();
3439 if (!eckey ||
3440 EC_KEY_set_group(eckey, ec_group) != 1 ||
3441 EC_KEY_set_public_key(eckey, point) != 1) {
3442 wpa_printf(MSG_ERROR,
3443 "OpenSSL: Failed to set EC_KEY: %s",
3444 ERR_error_string(ERR_get_error(), NULL));
3445 goto fail;
3446 }
3447 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3448
3449 pkey = EVP_PKEY_new();
3450 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3451 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3452 goto fail;
3453 }
3454
3455 out:
3456 EC_GROUP_free(ec_group);
3457 BN_free(x);
3458 BN_free(y);
3459 EC_POINT_free(point);
3460 BN_CTX_free(ctx);
3461 return (struct crypto_ec_key *) pkey;
3462
3463 fail:
3464 EC_KEY_free(eckey);
3465 EVP_PKEY_free(pkey);
3466 pkey = NULL;
3467 goto out;
3468 #endif /* OpenSSL version >= 3.0 */
3469 }
3470
3471
3472 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * ec,const struct crypto_ec_point * pub)3473 crypto_ec_key_set_pub_point(struct crypto_ec *ec,
3474 const struct crypto_ec_point *pub)
3475 {
3476 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3477 int len = BN_num_bytes(ec->prime);
3478 struct crypto_ec_key *key;
3479 u8 *buf;
3480
3481 buf = os_malloc(2 * len);
3482 if (!buf)
3483 return NULL;
3484 if (crypto_ec_point_to_bin(ec, pub, buf, buf + len) < 0) {
3485 os_free(buf);
3486 return NULL;
3487 }
3488
3489 key = crypto_ec_key_set_pub(ec->iana_group, buf, buf + len, len);
3490 os_free(buf);
3491
3492 return key;
3493 #else /* OpenSSL version >= 3.0 */
3494 EC_KEY *eckey;
3495 EVP_PKEY *pkey = NULL;
3496
3497 eckey = EC_KEY_new();
3498 if (!eckey ||
3499 EC_KEY_set_group(eckey, ec->group) != 1 ||
3500 EC_KEY_set_public_key(eckey, (const EC_POINT *) pub) != 1) {
3501 wpa_printf(MSG_ERROR,
3502 "OpenSSL: Failed to set EC_KEY: %s",
3503 ERR_error_string(ERR_get_error(), NULL));
3504 goto fail;
3505 }
3506 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
3507
3508 pkey = EVP_PKEY_new();
3509 if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
3510 wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
3511 goto fail;
3512 }
3513
3514 out:
3515 return (struct crypto_ec_key *) pkey;
3516
3517 fail:
3518 EVP_PKEY_free(pkey);
3519 EC_KEY_free(eckey);
3520 pkey = NULL;
3521 goto out;
3522 #endif /* OpenSSL version >= 3.0 */
3523 }
3524
3525
crypto_ec_key_gen(int group)3526 struct crypto_ec_key * crypto_ec_key_gen(int group)
3527 {
3528 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3529 EVP_PKEY_CTX *ctx;
3530 OSSL_PARAM params[2];
3531 const char *group_name;
3532 EVP_PKEY *pkey = NULL;
3533
3534 group_name = crypto_ec_group_2_name(group);
3535 if (!group_name)
3536 return NULL;
3537
3538 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3539 (char *) group_name, 0);
3540 params[1] = OSSL_PARAM_construct_end();
3541
3542 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
3543 if (!ctx ||
3544 EVP_PKEY_keygen_init(ctx) != 1 ||
3545 EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
3546 EVP_PKEY_generate(ctx, &pkey) != 1) {
3547 wpa_printf(MSG_INFO,
3548 "OpenSSL: Failed to generate EC keypair (group=%d): %s",
3549 group, ERR_error_string(ERR_get_error(), NULL));
3550 pkey = NULL;
3551 }
3552
3553 EVP_PKEY_CTX_free(ctx);
3554
3555 return (struct crypto_ec_key *) pkey;
3556 #else /* OpenSSL version >= 3.0 */
3557 EVP_PKEY_CTX *kctx = NULL;
3558 EC_KEY *ec_params = NULL, *eckey;
3559 EVP_PKEY *params = NULL, *key = NULL;
3560 int nid;
3561
3562 nid = crypto_ec_group_2_nid(group);
3563 if (nid < 0) {
3564 wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
3565 return NULL;
3566 }
3567
3568 ec_params = EC_KEY_new_by_curve_name(nid);
3569 if (!ec_params) {
3570 wpa_printf(MSG_ERROR,
3571 "OpenSSL: Failed to generate EC_KEY parameters");
3572 goto fail;
3573 }
3574 EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
3575 params = EVP_PKEY_new();
3576 if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
3577 wpa_printf(MSG_ERROR,
3578 "OpenSSL: Failed to generate EVP_PKEY parameters");
3579 goto fail;
3580 }
3581
3582 kctx = EVP_PKEY_CTX_new(params, NULL);
3583 if (!kctx ||
3584 EVP_PKEY_keygen_init(kctx) != 1 ||
3585 EVP_PKEY_keygen(kctx, &key) != 1) {
3586 wpa_printf(MSG_ERROR, "OpenSSL: Failed to generate EC key");
3587 key = NULL;
3588 goto fail;
3589 }
3590
3591 eckey = EVP_PKEY_get1_EC_KEY(key);
3592 if (!eckey) {
3593 key = NULL;
3594 goto fail;
3595 }
3596 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3597 EC_KEY_free(eckey);
3598
3599 fail:
3600 EC_KEY_free(ec_params);
3601 EVP_PKEY_free(params);
3602 EVP_PKEY_CTX_free(kctx);
3603 return (struct crypto_ec_key *) key;
3604 #endif /* OpenSSL version >= 3.0 */
3605 }
3606
3607
crypto_ec_key_deinit(struct crypto_ec_key * key)3608 void crypto_ec_key_deinit(struct crypto_ec_key *key)
3609 {
3610 EVP_PKEY_free((EVP_PKEY *) key);
3611 }
3612
3613
3614 #ifdef OPENSSL_IS_BORINGSSL
3615
3616 /* BoringSSL version of i2d_PUBKEY() always outputs public EC key using
3617 * uncompressed form so define a custom function to export EC pubkey using
3618 * the compressed format that is explicitly required for some protocols. */
3619
3620 #include <openssl/asn1.h>
3621 #include <openssl/asn1t.h>
3622
3623 typedef struct {
3624 /* AlgorithmIdentifier ecPublicKey with optional parameters present
3625 * as an OID identifying the curve */
3626 X509_ALGOR *alg;
3627 /* Compressed format public key per ANSI X9.63 */
3628 ASN1_BIT_STRING *pub_key;
3629 } EC_COMP_PUBKEY;
3630
3631 ASN1_SEQUENCE(EC_COMP_PUBKEY) = {
3632 ASN1_SIMPLE(EC_COMP_PUBKEY, alg, X509_ALGOR),
3633 ASN1_SIMPLE(EC_COMP_PUBKEY, pub_key, ASN1_BIT_STRING)
3634 } ASN1_SEQUENCE_END(EC_COMP_PUBKEY);
3635
3636 IMPLEMENT_ASN1_FUNCTIONS(EC_COMP_PUBKEY);
3637
3638 #endif /* OPENSSL_IS_BORINGSSL */
3639
3640
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)3641 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
3642 {
3643 EVP_PKEY *pkey = (EVP_PKEY *) key;
3644 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3645 OSSL_ENCODER_CTX *ctx;
3646 int selection;
3647 unsigned char *pdata = NULL;
3648 size_t pdata_len = 0;
3649 EVP_PKEY *copy = NULL;
3650 struct wpabuf *buf = NULL;
3651
3652 if (EVP_PKEY_get_ec_point_conv_form(pkey) !=
3653 POINT_CONVERSION_COMPRESSED) {
3654 copy = EVP_PKEY_dup(pkey);
3655 if (!copy)
3656 return NULL;
3657 if (EVP_PKEY_set_utf8_string_param(
3658 copy, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
3659 OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED) !=
3660 1) {
3661 wpa_printf(MSG_INFO,
3662 "OpenSSL: Failed to set compressed format");
3663 EVP_PKEY_free(copy);
3664 return NULL;
3665 }
3666 pkey = copy;
3667 }
3668
3669 selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS |
3670 OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
3671
3672 ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "DER",
3673 "SubjectPublicKeyInfo",
3674 NULL);
3675 if (!ctx || OSSL_ENCODER_to_data(ctx, &pdata, &pdata_len) != 1) {
3676 wpa_printf(MSG_INFO,
3677 "OpenSSL: Failed to encode SubjectPublicKeyInfo: %s",
3678 ERR_error_string(ERR_get_error(), NULL));
3679 pdata = NULL;
3680 }
3681 OSSL_ENCODER_CTX_free(ctx);
3682 if (pdata) {
3683 buf = wpabuf_alloc_copy(pdata, pdata_len);
3684 OPENSSL_free(pdata);
3685 }
3686
3687 EVP_PKEY_free(copy);
3688
3689 return buf;
3690 #else /* OpenSSL version >= 3.0 */
3691 #ifdef OPENSSL_IS_BORINGSSL
3692 unsigned char *der = NULL;
3693 int der_len;
3694 const EC_KEY *eckey;
3695 struct wpabuf *ret = NULL;
3696 size_t len;
3697 const EC_GROUP *group;
3698 const EC_POINT *point;
3699 BN_CTX *ctx;
3700 EC_COMP_PUBKEY *pubkey = NULL;
3701 int nid;
3702
3703 ctx = BN_CTX_new();
3704 eckey = EVP_PKEY_get0_EC_KEY(pkey);
3705 if (!ctx || !eckey)
3706 goto fail;
3707
3708 group = EC_KEY_get0_group(eckey);
3709 point = EC_KEY_get0_public_key(eckey);
3710 if (!group || !point)
3711 goto fail;
3712 nid = EC_GROUP_get_curve_name(group);
3713
3714 pubkey = EC_COMP_PUBKEY_new();
3715 if (!pubkey ||
3716 X509_ALGOR_set0(pubkey->alg, OBJ_nid2obj(EVP_PKEY_EC),
3717 V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1)
3718 goto fail;
3719
3720 len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
3721 NULL, 0, ctx);
3722 if (len == 0)
3723 goto fail;
3724
3725 der = OPENSSL_malloc(len);
3726 if (!der)
3727 goto fail;
3728 len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
3729 der, len, ctx);
3730
3731 OPENSSL_free(pubkey->pub_key->data);
3732 pubkey->pub_key->data = der;
3733 der = NULL;
3734 pubkey->pub_key->length = len;
3735 /* No unused bits */
3736 pubkey->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
3737 pubkey->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
3738
3739 der_len = i2d_EC_COMP_PUBKEY(pubkey, &der);
3740 if (der_len <= 0) {
3741 wpa_printf(MSG_ERROR,
3742 "BoringSSL: Failed to build DER encoded public key");
3743 goto fail;
3744 }
3745
3746 ret = wpabuf_alloc_copy(der, der_len);
3747 fail:
3748 EC_COMP_PUBKEY_free(pubkey);
3749 OPENSSL_free(der);
3750 BN_CTX_free(ctx);
3751 return ret;
3752 #else /* OPENSSL_IS_BORINGSSL */
3753 unsigned char *der = NULL;
3754 int der_len;
3755 struct wpabuf *buf;
3756 EC_KEY *eckey;
3757
3758 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3759 if (!eckey)
3760 return NULL;
3761
3762 /* For now, all users expect COMPRESSED form */
3763 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
3764
3765 der_len = i2d_PUBKEY((EVP_PKEY *) key, &der);
3766 EC_KEY_free(eckey);
3767 if (der_len <= 0) {
3768 wpa_printf(MSG_INFO, "OpenSSL: i2d_PUBKEY() failed: %s",
3769 ERR_error_string(ERR_get_error(), NULL));
3770 return NULL;
3771 }
3772
3773 buf = wpabuf_alloc_copy(der, der_len);
3774 OPENSSL_free(der);
3775 return buf;
3776 #endif /* OPENSSL_IS_BORINGSSL */
3777 #endif /* OpenSSL version >= 3.0 */
3778 }
3779
3780
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)3781 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
3782 bool include_pub)
3783 {
3784 EVP_PKEY *pkey = (EVP_PKEY *) key;
3785 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3786 OSSL_ENCODER_CTX *ctx;
3787 int selection;
3788 unsigned char *pdata = NULL;
3789 size_t pdata_len = 0;
3790 struct wpabuf *buf;
3791 EVP_PKEY *copy = NULL;
3792
3793 selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS |
3794 OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
3795 if (include_pub) {
3796 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
3797 } else {
3798 /* Not including OSSL_KEYMGMT_SELECT_PUBLIC_KEY does not seem
3799 * to really be sufficient, so clone the key and explicitly
3800 * mark it not to include the public key. */
3801 copy = EVP_PKEY_dup(pkey);
3802 if (!copy)
3803 return NULL;
3804 EVP_PKEY_set_int_param(copy, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC,
3805 0);
3806 pkey = copy;
3807 }
3808
3809 ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "DER",
3810 "type-specific", NULL);
3811 if (!ctx || OSSL_ENCODER_to_data(ctx, &pdata, &pdata_len) != 1) {
3812 wpa_printf(MSG_INFO, "OpenSSL: OSSL_ENCODER failed: %s",
3813 ERR_error_string(ERR_get_error(), NULL));
3814 OSSL_ENCODER_CTX_free(ctx);
3815 EVP_PKEY_free(copy);
3816 return NULL;
3817 }
3818 OSSL_ENCODER_CTX_free(ctx);
3819 buf = wpabuf_alloc_copy(pdata, pdata_len);
3820 OPENSSL_free(pdata);
3821 EVP_PKEY_free(copy);
3822 return buf;
3823 #else /* OpenSSL version >= 3.0 */
3824 EC_KEY *eckey;
3825 unsigned char *der = NULL;
3826 int der_len;
3827 struct wpabuf *buf;
3828 unsigned int key_flags;
3829
3830 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3831 if (!eckey)
3832 return NULL;
3833
3834 key_flags = EC_KEY_get_enc_flags(eckey);
3835 if (include_pub)
3836 key_flags &= ~EC_PKEY_NO_PUBKEY;
3837 else
3838 key_flags |= EC_PKEY_NO_PUBKEY;
3839 EC_KEY_set_enc_flags(eckey, key_flags);
3840
3841 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
3842
3843 der_len = i2d_ECPrivateKey(eckey, &der);
3844 EC_KEY_free(eckey);
3845 if (der_len <= 0)
3846 return NULL;
3847 buf = wpabuf_alloc_copy(der, der_len);
3848 OPENSSL_free(der);
3849
3850 return buf;
3851 #endif /* OpenSSL version >= 3.0 */
3852 }
3853
3854
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)3855 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
3856 int prefix)
3857 {
3858 EVP_PKEY *pkey = (EVP_PKEY *) key;
3859 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3860 struct wpabuf *buf;
3861 unsigned char *pos;
3862 size_t pub_len = OSSL_PARAM_UNMODIFIED;
3863
3864 buf = NULL;
3865 if (!EVP_PKEY_is_a(pkey, "EC") ||
3866 EVP_PKEY_get_octet_string_param(pkey,
3867 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
3868 NULL, 0, &pub_len) < 0 ||
3869 pub_len == OSSL_PARAM_UNMODIFIED ||
3870 !(buf = wpabuf_alloc(pub_len)) ||
3871 EVP_PKEY_get_octet_string_param(pkey,
3872 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
3873 wpabuf_put(buf, pub_len),
3874 pub_len, NULL) != 1 ||
3875 wpabuf_head_u8(buf)[0] != 0x04) {
3876 wpa_printf(MSG_INFO,
3877 "OpenSSL: Failed to get encoded public key: %s",
3878 ERR_error_string(ERR_get_error(), NULL));
3879 wpabuf_free(buf);
3880 return NULL;
3881 }
3882
3883 if (!prefix) {
3884 /* Remove 0x04 prefix if requested */
3885 pos = wpabuf_mhead(buf);
3886 os_memmove(pos, pos + 1, pub_len - 1);
3887 buf->used--;
3888 }
3889
3890 return buf;
3891 #else /* OpenSSL version >= 3.0 */
3892 int len, res;
3893 EC_KEY *eckey;
3894 struct wpabuf *buf;
3895 unsigned char *pos;
3896
3897 eckey = EVP_PKEY_get1_EC_KEY(pkey);
3898 if (!eckey)
3899 return NULL;
3900 EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
3901 len = i2o_ECPublicKey(eckey, NULL);
3902 if (len <= 0) {
3903 wpa_printf(MSG_ERROR,
3904 "OpenSSL: Failed to determine public key encoding length");
3905 EC_KEY_free(eckey);
3906 return NULL;
3907 }
3908
3909 buf = wpabuf_alloc(len);
3910 if (!buf) {
3911 EC_KEY_free(eckey);
3912 return NULL;
3913 }
3914
3915 pos = wpabuf_put(buf, len);
3916 res = i2o_ECPublicKey(eckey, &pos);
3917 EC_KEY_free(eckey);
3918 if (res != len) {
3919 wpa_printf(MSG_ERROR,
3920 "OpenSSL: Failed to encode public key (res=%d/%d)",
3921 res, len);
3922 wpabuf_free(buf);
3923 return NULL;
3924 }
3925
3926 if (!prefix) {
3927 /* Remove 0x04 prefix if requested */
3928 pos = wpabuf_mhead(buf);
3929 os_memmove(pos, pos + 1, len - 1);
3930 buf->used--;
3931 }
3932
3933 return buf;
3934 #endif /* OpenSSL version >= 3.0 */
3935 }
3936
3937
3938 struct crypto_ec_point *
crypto_ec_key_get_public_key(struct crypto_ec_key * key)3939 crypto_ec_key_get_public_key(struct crypto_ec_key *key)
3940 {
3941 EVP_PKEY *pkey = (EVP_PKEY *) key;
3942 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
3943 char group[64];
3944 unsigned char pub[256];
3945 size_t len;
3946 EC_POINT *point = NULL;
3947 EC_GROUP *grp;
3948 int res = 0;
3949 OSSL_PARAM params[2];
3950
3951 if (!EVP_PKEY_is_a(pkey, "EC") ||
3952 EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
3953 group, sizeof(group), &len) != 1 ||
3954 EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
3955 pub, sizeof(pub), &len) != 1)
3956 return NULL;
3957
3958 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3959 group, 0);
3960 params[1] = OSSL_PARAM_construct_end();
3961 grp = EC_GROUP_new_from_params(params, NULL, NULL);
3962 if (!grp)
3963 goto fail;
3964 point = EC_POINT_new(grp);
3965 if (!point)
3966 goto fail;
3967 res = EC_POINT_oct2point(grp, point, pub, len, NULL);
3968
3969 fail:
3970 if (res != 1) {
3971 EC_POINT_free(point);
3972 point = NULL;
3973 }
3974
3975 EC_GROUP_free(grp);
3976
3977 return (struct crypto_ec_point *) point;
3978 #else /* OpenSSL version >= 3.0 */
3979 const EC_KEY *eckey;
3980 const EC_POINT *point;
3981 const EC_GROUP *group;
3982
3983 eckey = EVP_PKEY_get0_EC_KEY(pkey);
3984 if (!eckey)
3985 return NULL;
3986 group = EC_KEY_get0_group(eckey);
3987 if (!group)
3988 return NULL;
3989 point = EC_KEY_get0_public_key(eckey);
3990 if (!point)
3991 return NULL;
3992 return (struct crypto_ec_point *) EC_POINT_dup(point, group);
3993 #endif /* OpenSSL version >= 3.0 */
3994 }
3995
3996
3997 struct crypto_bignum *
crypto_ec_key_get_private_key(struct crypto_ec_key * key)3998 crypto_ec_key_get_private_key(struct crypto_ec_key *key)
3999 {
4000 EVP_PKEY *pkey = (EVP_PKEY *) key;
4001 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4002 BIGNUM *bn = NULL;
4003
4004 if (!EVP_PKEY_is_a(pkey, "EC") ||
4005 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn) != 1)
4006 return NULL;
4007 return (struct crypto_bignum *) bn;
4008 #else /* OpenSSL version >= 3.0 */
4009 const EC_KEY *eckey;
4010 const BIGNUM *bn;
4011
4012 eckey = EVP_PKEY_get0_EC_KEY(pkey);
4013 if (!eckey)
4014 return NULL;
4015 bn = EC_KEY_get0_private_key(eckey);
4016 if (!bn)
4017 return NULL;
4018 return (struct crypto_bignum *) BN_dup(bn);
4019 #endif /* OpenSSL version >= 3.0 */
4020 }
4021
4022
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)4023 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
4024 size_t len)
4025 {
4026 EVP_PKEY_CTX *pkctx;
4027 struct wpabuf *sig_der;
4028 size_t sig_len;
4029
4030 sig_len = EVP_PKEY_size((EVP_PKEY *) key);
4031 sig_der = wpabuf_alloc(sig_len);
4032 if (!sig_der)
4033 return NULL;
4034
4035 pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
4036 if (!pkctx ||
4037 EVP_PKEY_sign_init(pkctx) <= 0 ||
4038 EVP_PKEY_sign(pkctx, wpabuf_put(sig_der, 0), &sig_len,
4039 data, len) <= 0) {
4040 wpabuf_free(sig_der);
4041 sig_der = NULL;
4042 } else {
4043 wpabuf_put(sig_der, sig_len);
4044 }
4045
4046 EVP_PKEY_CTX_free(pkctx);
4047 return sig_der;
4048 }
4049
4050
openssl_evp_pkey_ec_prime_len(struct crypto_ec_key * key)4051 static int openssl_evp_pkey_ec_prime_len(struct crypto_ec_key *key)
4052 {
4053 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4054 char gname[50];
4055 int nid;
4056 EC_GROUP *group;
4057 BIGNUM *prime = NULL;
4058 int prime_len = -1;
4059
4060 if (EVP_PKEY_get_group_name((EVP_PKEY *) key, gname, sizeof(gname),
4061 NULL) != 1)
4062 return -1;
4063 nid = OBJ_txt2nid(gname);
4064 group = EC_GROUP_new_by_curve_name(nid);
4065 prime = BN_new();
4066 if (!group || !prime)
4067 goto fail;
4068 if (EC_GROUP_get_curve(group, prime, NULL, NULL, NULL) == 1)
4069 prime_len = BN_num_bytes(prime);
4070 fail:
4071 EC_GROUP_free(group);
4072 BN_free(prime);
4073 return prime_len;
4074 #else
4075 const EC_GROUP *group;
4076 const EC_KEY *eckey;
4077 BIGNUM *prime = NULL;
4078 int prime_len = -1;
4079
4080 eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
4081 if (!eckey)
4082 goto fail;
4083 group = EC_KEY_get0_group(eckey);
4084 prime = BN_new();
4085 if (!prime || !group ||
4086 !EC_GROUP_get_curve(group, prime, NULL, NULL, NULL))
4087 goto fail;
4088 prime_len = BN_num_bytes(prime);
4089 fail:
4090 BN_free(prime);
4091 return prime_len;
4092 #endif
4093 }
4094
4095
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)4096 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
4097 const u8 *data, size_t len)
4098 {
4099 ECDSA_SIG *sig = NULL;
4100 const BIGNUM *r, *s;
4101 u8 *r_buf, *s_buf;
4102 struct wpabuf *buf;
4103 const unsigned char *p;
4104 int prime_len;
4105
4106 prime_len = openssl_evp_pkey_ec_prime_len(key);
4107 if (prime_len < 0)
4108 return NULL;
4109
4110 buf = crypto_ec_key_sign(key, data, len);
4111 if (!buf)
4112 return NULL;
4113
4114 /* Extract (r,s) from Ecdsa-Sig-Value */
4115
4116 p = wpabuf_head(buf);
4117 sig = d2i_ECDSA_SIG(NULL, &p, wpabuf_len(buf));
4118 if (!sig)
4119 goto fail;
4120 ECDSA_SIG_get0(sig, &r, &s);
4121
4122 /* Re-use wpabuf returned by crypto_ec_key_sign() */
4123 buf->used = 0;
4124 r_buf = wpabuf_put(buf, prime_len);
4125 s_buf = wpabuf_put(buf, prime_len);
4126 if (crypto_bignum_to_bin((const struct crypto_bignum *) r, r_buf,
4127 prime_len, prime_len) < 0 ||
4128 crypto_bignum_to_bin((const struct crypto_bignum *) s, s_buf,
4129 prime_len, prime_len) < 0)
4130 goto fail;
4131
4132 out:
4133 ECDSA_SIG_free(sig);
4134 return buf;
4135 fail:
4136 wpabuf_clear_free(buf);
4137 buf = NULL;
4138 goto out;
4139 }
4140
4141
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)4142 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
4143 size_t len, const u8 *sig, size_t sig_len)
4144 {
4145 EVP_PKEY_CTX *pkctx;
4146 int ret;
4147
4148 pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
4149 if (!pkctx || EVP_PKEY_verify_init(pkctx) <= 0) {
4150 EVP_PKEY_CTX_free(pkctx);
4151 return -1;
4152 }
4153
4154 ret = EVP_PKEY_verify(pkctx, sig, sig_len, data, len);
4155 EVP_PKEY_CTX_free(pkctx);
4156 if (ret == 1)
4157 return 1; /* signature ok */
4158 if (ret == 0)
4159 return 0; /* incorrect signature */
4160 return -1;
4161 }
4162
4163
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)4164 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
4165 const u8 *data, size_t len,
4166 const u8 *r, size_t r_len,
4167 const u8 *s, size_t s_len)
4168 {
4169 ECDSA_SIG *sig;
4170 BIGNUM *r_bn, *s_bn;
4171 unsigned char *der = NULL;
4172 int der_len;
4173 int ret = -1;
4174
4175 r_bn = BN_bin2bn(r, r_len, NULL);
4176 s_bn = BN_bin2bn(s, s_len, NULL);
4177 sig = ECDSA_SIG_new();
4178 if (!r_bn || !s_bn || !sig || ECDSA_SIG_set0(sig, r_bn, s_bn) != 1)
4179 goto fail;
4180 r_bn = NULL;
4181 s_bn = NULL;
4182
4183 der_len = i2d_ECDSA_SIG(sig, &der);
4184 if (der_len <= 0) {
4185 wpa_printf(MSG_DEBUG,
4186 "OpenSSL: Could not DER encode signature");
4187 goto fail;
4188 }
4189
4190 ret = crypto_ec_key_verify_signature(key, data, len, der, der_len);
4191
4192 fail:
4193 OPENSSL_free(der);
4194 BN_free(r_bn);
4195 BN_free(s_bn);
4196 ECDSA_SIG_free(sig);
4197 return ret;
4198 }
4199
4200
crypto_ec_key_group(struct crypto_ec_key * key)4201 int crypto_ec_key_group(struct crypto_ec_key *key)
4202 {
4203 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4204 char gname[50];
4205 int nid;
4206
4207 if (EVP_PKEY_get_group_name((EVP_PKEY *) key, gname, sizeof(gname),
4208 NULL) != 1)
4209 return -1;
4210 nid = OBJ_txt2nid(gname);
4211 #else
4212 const EC_KEY *eckey;
4213 const EC_GROUP *group;
4214 int nid;
4215
4216 eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
4217 if (!eckey)
4218 return -1;
4219 group = EC_KEY_get0_group(eckey);
4220 if (!group)
4221 return -1;
4222 nid = EC_GROUP_get_curve_name(group);
4223 #endif
4224 switch (nid) {
4225 case NID_X9_62_prime256v1:
4226 return 19;
4227 case NID_secp384r1:
4228 return 20;
4229 case NID_secp521r1:
4230 return 21;
4231 #ifdef NID_brainpoolP256r1
4232 case NID_brainpoolP256r1:
4233 return 28;
4234 #endif /* NID_brainpoolP256r1 */
4235 #ifdef NID_brainpoolP384r1
4236 case NID_brainpoolP384r1:
4237 return 29;
4238 #endif /* NID_brainpoolP384r1 */
4239 #ifdef NID_brainpoolP512r1
4240 case NID_brainpoolP512r1:
4241 return 30;
4242 #endif /* NID_brainpoolP512r1 */
4243 default:
4244 wpa_printf(MSG_ERROR,
4245 "OpenSSL: Unsupported curve (nid=%d) in EC key",
4246 nid);
4247 return -1;
4248 }
4249 }
4250
4251
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)4252 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
4253 {
4254 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4255 if (EVP_PKEY_eq((EVP_PKEY *) key1, (EVP_PKEY *) key2) != 1)
4256 return -1;
4257 #else
4258 if (EVP_PKEY_cmp((EVP_PKEY *) key1, (EVP_PKEY *) key2) != 1)
4259 return -1;
4260 #endif
4261 return 0;
4262 }
4263
4264
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)4265 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
4266 const char *title)
4267 {
4268 BIO *out;
4269 size_t rlen;
4270 char *txt;
4271 int res;
4272
4273 out = BIO_new(BIO_s_mem());
4274 if (!out)
4275 return;
4276
4277 EVP_PKEY_print_private(out, (EVP_PKEY *) key, 0, NULL);
4278 rlen = BIO_ctrl_pending(out);
4279 txt = os_malloc(rlen + 1);
4280 if (txt) {
4281 res = BIO_read(out, txt, rlen);
4282 if (res > 0) {
4283 txt[res] = '\0';
4284 wpa_printf(MSG_DEBUG, "%s: %s", title, txt);
4285 }
4286 os_free(txt);
4287 }
4288 BIO_free(out);
4289 }
4290
4291
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)4292 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
4293 {
4294 #ifdef OPENSSL_IS_BORINGSSL
4295 CBS pkcs7_cbs;
4296 #else /* OPENSSL_IS_BORINGSSL */
4297 PKCS7 *p7 = NULL;
4298 const unsigned char *p = wpabuf_head(pkcs7);
4299 #endif /* OPENSSL_IS_BORINGSSL */
4300 STACK_OF(X509) *certs;
4301 int i, num;
4302 BIO *out = NULL;
4303 size_t rlen;
4304 struct wpabuf *pem = NULL;
4305 int res;
4306
4307 #ifdef OPENSSL_IS_BORINGSSL
4308 certs = sk_X509_new_null();
4309 if (!certs)
4310 goto fail;
4311 CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7));
4312 if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
4313 wpa_printf(MSG_INFO,
4314 "OpenSSL: Could not parse PKCS#7 object: %s",
4315 ERR_error_string(ERR_get_error(), NULL));
4316 goto fail;
4317 }
4318 #else /* OPENSSL_IS_BORINGSSL */
4319 p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7));
4320 if (!p7) {
4321 wpa_printf(MSG_INFO,
4322 "OpenSSL: Could not parse PKCS#7 object: %s",
4323 ERR_error_string(ERR_get_error(), NULL));
4324 goto fail;
4325 }
4326
4327 switch (OBJ_obj2nid(p7->type)) {
4328 case NID_pkcs7_signed:
4329 certs = p7->d.sign->cert;
4330 break;
4331 case NID_pkcs7_signedAndEnveloped:
4332 certs = p7->d.signed_and_enveloped->cert;
4333 break;
4334 default:
4335 certs = NULL;
4336 break;
4337 }
4338 #endif /* OPENSSL_IS_BORINGSSL */
4339
4340 if (!certs || ((num = sk_X509_num(certs)) == 0)) {
4341 wpa_printf(MSG_INFO,
4342 "OpenSSL: No certificates found in PKCS#7 object");
4343 goto fail;
4344 }
4345
4346 out = BIO_new(BIO_s_mem());
4347 if (!out)
4348 goto fail;
4349
4350 for (i = 0; i < num; i++) {
4351 X509 *cert = sk_X509_value(certs, i);
4352
4353 PEM_write_bio_X509(out, cert);
4354 }
4355
4356 rlen = BIO_ctrl_pending(out);
4357 pem = wpabuf_alloc(rlen);
4358 if (!pem)
4359 goto fail;
4360 res = BIO_read(out, wpabuf_put(pem, 0), rlen);
4361 if (res <= 0) {
4362 wpabuf_free(pem);
4363 pem = NULL;
4364 goto fail;
4365 }
4366 wpabuf_put(pem, res);
4367
4368 fail:
4369 #ifdef OPENSSL_IS_BORINGSSL
4370 if (certs)
4371 sk_X509_pop_free(certs, X509_free);
4372 #else /* OPENSSL_IS_BORINGSSL */
4373 PKCS7_free(p7);
4374 #endif /* OPENSSL_IS_BORINGSSL */
4375 if (out)
4376 BIO_free_all(out);
4377
4378 return pem;
4379 }
4380
4381
crypto_csr_init(void)4382 struct crypto_csr * crypto_csr_init(void)
4383 {
4384 return (struct crypto_csr *)X509_REQ_new();
4385 }
4386
4387
crypto_csr_verify(const struct wpabuf * req)4388 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
4389 {
4390 X509_REQ *csr;
4391 EVP_PKEY *pkey = NULL;
4392 const u8 *der = wpabuf_head(req);
4393
4394 csr = d2i_X509_REQ(NULL, &der, wpabuf_len(req));
4395 if (!csr)
4396 return NULL;
4397
4398 pkey = X509_REQ_get_pubkey((X509_REQ *)csr);
4399 if (!pkey)
4400 goto fail;
4401
4402 if (X509_REQ_verify((X509_REQ *)csr, pkey) != 1)
4403 goto fail;
4404
4405 EVP_PKEY_free(pkey);
4406 return (struct crypto_csr *)csr;
4407 fail:
4408 EVP_PKEY_free(pkey);
4409 X509_REQ_free(csr);
4410 return NULL;
4411 }
4412
4413
crypto_csr_deinit(struct crypto_csr * csr)4414 void crypto_csr_deinit(struct crypto_csr *csr)
4415 {
4416 X509_REQ_free((X509_REQ *)csr);
4417 }
4418
4419
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)4420 int crypto_csr_set_ec_public_key(struct crypto_csr *csr, struct crypto_ec_key *key)
4421 {
4422 if (!X509_REQ_set_pubkey((X509_REQ *)csr, (EVP_PKEY *)key))
4423 return -1;
4424
4425 return 0;
4426 }
4427
4428
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)4429 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
4430 const char *name)
4431 {
4432 X509_NAME *n;
4433 int nid;
4434 int ret = -1;
4435
4436 switch (type) {
4437 case CSR_NAME_CN:
4438 nid = NID_commonName;
4439 break;
4440 case CSR_NAME_SN:
4441 nid = NID_surname;
4442 break;
4443 case CSR_NAME_C:
4444 nid = NID_countryName;
4445 break;
4446 case CSR_NAME_O:
4447 nid = NID_organizationName;
4448 break;
4449 case CSR_NAME_OU:
4450 nid = NID_organizationalUnitName;
4451 break;
4452 default:
4453 return -1;
4454 }
4455
4456 n = X509_NAME_new();
4457 if (!n)
4458 return -1;
4459
4460 #if OPENSSL_VERSION_NUMBER < 0x10100000L
4461 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
4462 (unsigned char *) name,
4463 os_strlen(name), -1, 0))
4464 goto fail;
4465 #else
4466 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
4467 (const unsigned char *) name,
4468 os_strlen(name), -1, 0))
4469 goto fail;
4470 #endif
4471
4472 if (X509_REQ_set_subject_name((X509_REQ *) csr, n) != 1)
4473 goto fail;
4474
4475 ret = 0;
4476 fail:
4477 X509_NAME_free(n);
4478 return ret;
4479 }
4480
4481
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)4482 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
4483 int attr_type, const u8 *value, size_t len)
4484 {
4485 int nid;
4486
4487 switch (attr) {
4488 case CSR_ATTR_CHALLENGE_PASSWORD:
4489 nid = NID_pkcs9_challengePassword;
4490 break;
4491 default:
4492 return -1;
4493 }
4494
4495 if (!X509_REQ_add1_attr_by_NID((X509_REQ *) csr, nid, attr_type, value,
4496 len))
4497 return -1;
4498
4499 return 0;
4500 }
4501
4502
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)4503 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
4504 enum crypto_csr_attr attr,
4505 size_t *len, int *type)
4506 {
4507 X509_ATTRIBUTE *attrib;
4508 const ASN1_TYPE *attrib_type;
4509 const ASN1_STRING *data;
4510 int loc;
4511 int nid;
4512
4513 switch (attr) {
4514 case CSR_ATTR_CHALLENGE_PASSWORD:
4515 nid = NID_pkcs9_challengePassword;
4516 break;
4517 default:
4518 return NULL;
4519 }
4520
4521 loc = X509_REQ_get_attr_by_NID((X509_REQ *) csr, nid, -1);
4522 if (loc < 0)
4523 return NULL;
4524
4525 attrib = X509_REQ_get_attr((X509_REQ *) csr, loc);
4526 if (!attrib)
4527 return NULL;
4528
4529 attrib_type = X509_ATTRIBUTE_get0_type(attrib, 0);
4530 if (!attrib_type)
4531 return NULL;
4532 *type = ASN1_TYPE_get(attrib_type);
4533 data = X509_ATTRIBUTE_get0_data(attrib, 0, *type, NULL);
4534 if (!data)
4535 return NULL;
4536 *len = ASN1_STRING_length(data);
4537 return ASN1_STRING_get0_data(data);
4538 }
4539
4540
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)4541 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
4542 struct crypto_ec_key *key,
4543 enum crypto_hash_alg algo)
4544 {
4545 const EVP_MD *sign_md;
4546 struct wpabuf *buf;
4547 unsigned char *der = NULL;
4548 int der_len;
4549
4550 switch (algo) {
4551 case CRYPTO_HASH_ALG_SHA256:
4552 sign_md = EVP_sha256();
4553 break;
4554 case CRYPTO_HASH_ALG_SHA384:
4555 sign_md = EVP_sha384();
4556 break;
4557 case CRYPTO_HASH_ALG_SHA512:
4558 sign_md = EVP_sha512();
4559 break;
4560 default:
4561 return NULL;
4562 }
4563
4564 if (!X509_REQ_sign((X509_REQ *) csr, (EVP_PKEY *) key, sign_md))
4565 return NULL;
4566
4567 der_len = i2d_X509_REQ((X509_REQ *) csr, &der);
4568 if (der_len < 0)
4569 return NULL;
4570
4571 buf = wpabuf_alloc_copy(der, der_len);
4572 OPENSSL_free(der);
4573
4574 return buf;
4575 }
4576
4577 #endif /* CONFIG_ECC */
4578
4579
crypto_rsa_key_read_public(FILE * f)4580 static EVP_PKEY * crypto_rsa_key_read_public(FILE *f)
4581 {
4582 EVP_PKEY *pkey;
4583 X509 *x509;
4584 const ASN1_TIME *not_before, *not_after;
4585 int res_before, res_after;
4586
4587 pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
4588 if (pkey)
4589 return pkey;
4590
4591 rewind(f);
4592 x509 = PEM_read_X509(f, NULL, NULL, NULL);
4593 if (!x509)
4594 return NULL;
4595
4596 not_before = X509_get0_notBefore(x509);
4597 not_after = X509_get0_notAfter(x509);
4598 if (!not_before || !not_after)
4599 goto fail;
4600 res_before = X509_cmp_current_time(not_before);
4601 res_after = X509_cmp_current_time(not_after);
4602 if (!res_before || !res_after)
4603 goto fail;
4604 if (res_before > 0 || res_after < 0) {
4605 wpa_printf(MSG_INFO,
4606 "OpenSSL: Certificate for RSA public key is not valid at this time (%d %d)",
4607 res_before, res_after);
4608 goto fail;
4609 }
4610
4611 pkey = X509_get_pubkey(x509);
4612 X509_free(x509);
4613
4614 if (!pkey)
4615 return NULL;
4616 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
4617 wpa_printf(MSG_INFO, "OpenSSL: No RSA public key found");
4618 EVP_PKEY_free(pkey);
4619 return NULL;
4620 }
4621
4622 return pkey;
4623 fail:
4624 X509_free(x509);
4625 return NULL;
4626 }
4627
4628
crypto_rsa_key_read(const char * file,bool private_key)4629 struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key)
4630 {
4631 FILE *f;
4632 EVP_PKEY *pkey;
4633
4634 f = fopen(file, "r");
4635 if (!f)
4636 return NULL;
4637 if (private_key)
4638 pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
4639 else
4640 pkey = crypto_rsa_key_read_public(f);
4641 fclose(f);
4642 return (struct crypto_rsa_key *) pkey;
4643 }
4644
4645
4646 #ifndef OPENSSL_NO_SHA256
4647
crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key * key,const struct wpabuf * in)4648 struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
4649 const struct wpabuf *in)
4650 {
4651 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x30400000L
4652 EVP_PKEY *pkey = (EVP_PKEY *) key;
4653 EVP_PKEY_CTX *pkctx;
4654 struct wpabuf *res = NULL;
4655 size_t outlen;
4656
4657 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
4658 if (!pkctx)
4659 goto fail;
4660
4661 if (EVP_PKEY_encrypt_init(pkctx) != 1 ||
4662 EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
4663 EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
4664 EVP_PKEY_encrypt(pkctx, NULL, &outlen, wpabuf_head(in),
4665 wpabuf_len(in)) != 1 ||
4666 !(res = wpabuf_alloc(outlen)) ||
4667 EVP_PKEY_encrypt(pkctx, wpabuf_put(res, 0), &outlen,
4668 wpabuf_head(in), wpabuf_len(in)) != 1) {
4669 wpabuf_free(res);
4670 res = NULL;
4671 goto fail;
4672 }
4673 wpabuf_put(res, outlen);
4674
4675 fail:
4676 EVP_PKEY_CTX_free(pkctx);
4677 return res;
4678 #else
4679 wpa_printf(MSG_ERROR, "%s() not supported", __func__);
4680 return NULL;
4681 #endif
4682 }
4683
4684
crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key * key,const struct wpabuf * in)4685 struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
4686 const struct wpabuf *in)
4687 {
4688 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x30400000L
4689 EVP_PKEY *pkey = (EVP_PKEY *) key;
4690 EVP_PKEY_CTX *pkctx;
4691 struct wpabuf *res = NULL;
4692 size_t outlen;
4693
4694 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
4695 if (!pkctx)
4696 goto fail;
4697
4698 if (EVP_PKEY_decrypt_init(pkctx) != 1 ||
4699 EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
4700 EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
4701 EVP_PKEY_decrypt(pkctx, NULL, &outlen, wpabuf_head(in),
4702 wpabuf_len(in)) != 1 ||
4703 !(res = wpabuf_alloc(outlen)) ||
4704 EVP_PKEY_decrypt(pkctx, wpabuf_put(res, 0), &outlen,
4705 wpabuf_head(in), wpabuf_len(in)) != 1) {
4706 wpabuf_free(res);
4707 res = NULL;
4708 goto fail;
4709 }
4710 wpabuf_put(res, outlen);
4711
4712 fail:
4713 EVP_PKEY_CTX_free(pkctx);
4714 return res;
4715 #else
4716 wpa_printf(MSG_ERROR, "%s() not supported", __func__);
4717 return NULL;
4718 #endif
4719 }
4720
4721 #endif /* OPENSSL_NO_SHA256 */
4722
4723
crypto_rsa_key_free(struct crypto_rsa_key * key)4724 void crypto_rsa_key_free(struct crypto_rsa_key *key)
4725 {
4726 EVP_PKEY_free((EVP_PKEY *) key);
4727 }
4728
4729
4730 #ifdef CONFIG_DPP3
4731
4732 #define HPKE_MAX_SHARED_SECRET_LEN 66
4733 #define HPKE_MAX_HASH_LEN 64
4734 #define HPKE_MAX_KEY_LEN 32
4735 #define HPKE_MAX_NONCE_LEN 12
4736 #define HPKE_MAX_PUB_LEN (1 + 2 * 66)
4737
4738 struct hpke_context {
4739 /* KEM */
4740 enum hpke_kem_id kem_id;
4741 int kem_nid;
4742 int iana_group;
4743 size_t n_pk;
4744 size_t n_secret;
4745 const EVP_MD *kem_h;
4746 size_t kem_n_h;
4747
4748 /* KDF */
4749 enum hpke_kdf_id kdf_id;
4750 const EVP_MD *kdf_h;
4751 size_t n_h;
4752
4753 /* AEAD */
4754 enum hpke_aead_id aead_id;
4755 const EVP_CIPHER *cipher;
4756 size_t n_k;
4757 size_t n_n;
4758 size_t n_t;
4759 u8 key[HPKE_MAX_KEY_LEN];
4760 u8 base_nonce[HPKE_MAX_NONCE_LEN];
4761 };
4762
4763
hpke_free_context(struct hpke_context * ctx)4764 static void hpke_free_context(struct hpke_context *ctx)
4765 {
4766 bin_clear_free(ctx, sizeof(*ctx));
4767 }
4768
4769
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)4770 static struct hpke_context * hpke_get_context(enum hpke_kem_id kem_id,
4771 enum hpke_kdf_id kdf_id,
4772 enum hpke_aead_id aead_id,
4773 struct crypto_ec_key *key)
4774 {
4775 struct hpke_context *ctx;
4776 int group;
4777
4778 ctx = os_zalloc(sizeof(*ctx));
4779 if (!ctx)
4780 return NULL;
4781
4782 ctx->kem_id = kem_id;
4783 switch (kem_id) {
4784 case HPKE_DHKEM_P256_HKDF_SHA256:
4785 ctx->kem_nid = NID_X9_62_prime256v1;
4786 ctx->iana_group = 19;
4787 ctx->n_pk = 65;
4788 ctx->n_secret = 32;
4789 ctx->kem_h = EVP_sha256();
4790 ctx->kem_n_h = 32;
4791 break;
4792 case HPKE_DHKEM_P384_HKDF_SHA384:
4793 ctx->kem_nid = NID_secp384r1;
4794 ctx->iana_group = 20;
4795 ctx->n_pk = 97;
4796 ctx->n_secret = 48;
4797 ctx->kem_h = EVP_sha384();
4798 ctx->kem_n_h = 48;
4799 break;
4800 case HPKE_DHKEM_P521_HKDF_SHA512:
4801 ctx->kem_nid = NID_secp521r1;
4802 ctx->iana_group = 21;
4803 ctx->n_pk = 133;
4804 ctx->n_secret = 64;
4805 ctx->kem_h = EVP_sha512();
4806 ctx->kem_n_h = 64;
4807 break;
4808 default:
4809 goto fail;
4810 }
4811
4812 ctx->kdf_id = kdf_id;
4813 switch (kdf_id) {
4814 case HPKE_KDF_HKDF_SHA256:
4815 ctx->kdf_h = EVP_sha256();
4816 ctx->n_h = 32;
4817 break;
4818 case HPKE_KDF_HKDF_SHA384:
4819 ctx->kdf_h = EVP_sha384();
4820 ctx->n_h = 48;
4821 break;
4822 case HPKE_KDF_HKDF_SHA512:
4823 ctx->kdf_h = EVP_sha512();
4824 ctx->n_h = 64;
4825 break;
4826 default:
4827 goto fail;
4828 }
4829
4830 ctx->aead_id = aead_id;
4831 switch (aead_id) {
4832 case HPKE_AEAD_AES_128_GCM:
4833 ctx->cipher = EVP_aes_128_gcm();
4834 ctx->n_k = 16;
4835 ctx->n_n = 12;
4836 ctx->n_t = 16;
4837 break;
4838 case HPKE_AEAD_AES_256_GCM:
4839 ctx->cipher = EVP_aes_256_gcm();
4840 ctx->n_k = 32;
4841 ctx->n_n = 12;
4842 ctx->n_t = 16;
4843 break;
4844 default:
4845 goto fail;
4846 }
4847
4848 /* Convert BP-256/384/512 to P-256/384/521 for DPP */
4849 group = crypto_ec_key_group(key);
4850 if (group == 28 && ctx->iana_group == 19) {
4851 ctx->iana_group = 28;
4852 } else if (group == 29 && ctx->iana_group == 20) {
4853 ctx->iana_group = 29;
4854 } else if (group == 30 && ctx->iana_group == 21) {
4855 ctx->iana_group = 30;
4856 ctx->n_pk = 129;
4857 }
4858 if (group != ctx->iana_group) {
4859 wpa_printf(MSG_INFO, "OpenSSL:%s:group mismatch (%d != %d)",
4860 __func__, group, ctx->iana_group);
4861 goto fail;
4862 }
4863
4864 return ctx;
4865 fail:
4866 hpke_free_context(ctx);
4867 return NULL;
4868 }
4869
4870
hpke_suite_id(struct hpke_context * ctx,bool kem,u8 * suite_id)4871 static size_t hpke_suite_id(struct hpke_context *ctx, bool kem, u8 *suite_id)
4872 {
4873 size_t suite_id_len;
4874
4875 if (kem) {
4876 os_memcpy(suite_id, "KEM", 3);
4877 WPA_PUT_BE16(&suite_id[3], ctx->kem_id);
4878 suite_id_len = 5;
4879 } else {
4880 os_memcpy(suite_id, "HPKE", 4);
4881 WPA_PUT_BE16(&suite_id[4], ctx->kem_id);
4882 WPA_PUT_BE16(&suite_id[6], ctx->kdf_id);
4883 WPA_PUT_BE16(&suite_id[8], ctx->aead_id);
4884 suite_id_len = 10;
4885 }
4886 return suite_id_len;
4887 }
4888
4889
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)4890 static int hpke_labeled_extract(struct hpke_context *ctx, bool kem,
4891 const u8 *salt, size_t salt_len,
4892 const char *label,
4893 const u8 *ikm, size_t ikm_len, u8 *prk)
4894 {
4895 u8 zero[HPKE_MAX_HASH_LEN];
4896 u8 suite_id[10];
4897 size_t suite_id_len;
4898 unsigned int mdlen = kem ? ctx->kem_n_h : ctx->n_h;
4899 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4900 EVP_MAC *hmac;
4901 OSSL_PARAM params[2];
4902 EVP_MAC_CTX *hctx;
4903 size_t mlen;
4904 int res;
4905 #else /* OpenSSL version >= 3.0 */
4906 HMAC_CTX *hctx;
4907 int res;
4908 #endif /* OpenSSL version >= 3.0 */
4909
4910 if (!salt || !salt_len) {
4911 salt_len = mdlen;
4912 os_memset(zero, 0, salt_len);
4913 salt = zero;
4914 }
4915
4916 suite_id_len = hpke_suite_id(ctx, kem, suite_id);
4917
4918 /* labeled_ikm = concat("HPKE-v1", suite_id, label, ikm)
4919 * return Extract(salt, labeled_ikm) */
4920
4921 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4922 hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
4923 if (!hmac)
4924 return -1;
4925
4926 params[0] = OSSL_PARAM_construct_utf8_string(
4927 "digest",
4928 (char *) EVP_MD_get0_name(kem ? ctx->kem_h : ctx->kdf_h), 0);
4929 params[1] = OSSL_PARAM_construct_end();
4930
4931 hctx = EVP_MAC_CTX_new(hmac);
4932 EVP_MAC_free(hmac);
4933 if (!hctx)
4934 return -1;
4935
4936 if (EVP_MAC_init(hctx, salt, salt_len, params) != 1) {
4937 wpa_printf(MSG_INFO,
4938 "OpenSSL: EVP_MAC_init(hmac,digest/HPKE) failed: %s",
4939 ERR_error_string(ERR_get_error(), NULL));
4940 goto fail;
4941 }
4942
4943 if (EVP_MAC_update(hctx, (const unsigned char *) "HPKE-v1", 7) != 1 ||
4944 EVP_MAC_update(hctx, suite_id, suite_id_len) != 1 ||
4945 EVP_MAC_update(hctx, (const unsigned char *) label,
4946 os_strlen(label)) != 1 ||
4947 EVP_MAC_update(hctx, ikm, ikm_len) != 1)
4948 goto fail;
4949
4950 res = EVP_MAC_final(hctx, prk, &mlen, mdlen);
4951 EVP_MAC_CTX_free(hctx);
4952
4953 return res == 1 ? 0 : -1;
4954 fail:
4955 EVP_MAC_CTX_free(hctx);
4956 return -1;
4957 #else /* OpenSSL version >= 3.0 */
4958 hctx = HMAC_CTX_new();
4959 if (!hctx)
4960 return -1;
4961 res = HMAC_Init_ex(hctx, salt, salt_len, kem ? ctx->kem_h : ctx->kdf_h,
4962 NULL);
4963 if (res != 1)
4964 goto done;
4965
4966 HMAC_Update(hctx, (const unsigned char *) "HPKE-v1", 7);
4967 HMAC_Update(hctx, suite_id, suite_id_len);
4968 HMAC_Update(hctx, (const unsigned char *) label, os_strlen(label));
4969 HMAC_Update(hctx, ikm, ikm_len);
4970
4971 res = HMAC_Final(hctx, prk, &mdlen);
4972 done:
4973 HMAC_CTX_free(hctx);
4974
4975 return res == 1 ? 0 : -1;
4976 #endif /* OpenSSL version >= 3.0 */
4977 }
4978
4979
4980 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)4981 hpke_labeled_expand(struct hpke_context *ctx, bool kem, const u8 *prk,
4982 const char *label, const u8 *info, size_t info_len,
4983 u8 *out, size_t out_len)
4984 {
4985 u8 suite_id[10];
4986 size_t suite_id_len;
4987 u8 hash[HPKE_MAX_HASH_LEN];
4988 u8 iter = 0;
4989 size_t label_len = os_strlen(label);
4990 u8 *pos;
4991 size_t left = out_len, clen;
4992 int res = -1;
4993 u8 *labeled_info;
4994 size_t labeled_info_len;
4995 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
4996 EVP_MAC *hmac;
4997 OSSL_PARAM params[2];
4998 EVP_MAC_CTX *hctx = NULL;
4999 size_t mdlen;
5000 #else /* OpenSSL version >= 3.0 */
5001 HMAC_CTX *hctx;
5002 unsigned int mdlen;
5003 #endif /* OpenSSL version >= 3.0 */
5004
5005 /* labeled_info = concat(I2OSP(L, 2), "HPKE-v1", suite_id,
5006 * label, info)
5007 * return Expand(prk, labeled_info, L) */
5008 suite_id_len = hpke_suite_id(ctx, kem, suite_id);
5009 labeled_info_len = 2 + 7 + suite_id_len + label_len + info_len;
5010 labeled_info = os_malloc(labeled_info_len);
5011 if (!labeled_info)
5012 return -1;
5013 pos = labeled_info;
5014 WPA_PUT_BE16(pos, out_len);
5015 pos += 2;
5016 os_memcpy(pos, "HPKE-v1", 7);
5017 pos += 7;
5018 os_memcpy(pos, suite_id, suite_id_len);
5019 pos += suite_id_len;
5020 os_memcpy(pos, label, label_len);
5021 pos += label_len;
5022 if (info && info_len)
5023 os_memcpy(pos, info, info_len);
5024
5025 pos = out;
5026 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
5027 hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
5028 if (!hmac)
5029 goto fail;
5030
5031 params[0] = OSSL_PARAM_construct_utf8_string(
5032 "digest",
5033 (char *) EVP_MD_get0_name(kem ? ctx->kem_h : ctx->kdf_h), 0);
5034 params[1] = OSSL_PARAM_construct_end();
5035 #else /* OpenSSL version >= 3.0 */
5036 hctx = HMAC_CTX_new();
5037 if (!hctx)
5038 goto fail;
5039 #endif /* OpenSSL version >= 3.0 */
5040
5041 while (left > 0) {
5042 mdlen = kem ? ctx->kem_n_h : ctx->n_h;
5043 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
5044 EVP_MAC_CTX_free(hctx);
5045 hctx = EVP_MAC_CTX_new(hmac);
5046 if (!hctx)
5047 goto fail;
5048
5049 if (EVP_MAC_init(hctx, prk, mdlen, params) != 1) {
5050 wpa_printf(MSG_INFO,
5051 "OpenSSL: EVP_MAC_init(hmac,digest/HPKE) failed: %s",
5052 ERR_error_string(ERR_get_error(), NULL));
5053 goto fail;
5054 }
5055
5056 if (iter > 0 && EVP_MAC_update(hctx, hash, mdlen) != 1)
5057 goto fail;
5058 if (iter == 255)
5059 goto fail;
5060 iter++;
5061
5062 if (EVP_MAC_update(hctx, labeled_info, labeled_info_len) != 1 ||
5063 EVP_MAC_update(hctx, &iter, sizeof(iter)) != 1)
5064 goto fail;
5065
5066 if (EVP_MAC_final(hctx, hash, &mdlen, mdlen) != 1)
5067 goto fail;
5068 #else /* OpenSSL version >= 3.0 */
5069 if (HMAC_Init_ex(hctx, prk, mdlen,
5070 kem ? ctx->kem_h : ctx->kdf_h,
5071 NULL) != 1)
5072 goto fail;
5073
5074 if (iter > 0)
5075 HMAC_Update(hctx, hash, mdlen);
5076 if (iter == 255)
5077 goto fail;
5078 iter++;
5079 HMAC_Update(hctx, labeled_info, labeled_info_len);
5080 HMAC_Update(hctx, &iter, sizeof(iter));
5081
5082 if (HMAC_Final(hctx, hash, &mdlen) != 1)
5083 goto fail;
5084 HMAC_CTX_reset(hctx);
5085 #endif /* OpenSSL version >= 3.0 */
5086
5087 clen = left > mdlen ? mdlen : left;
5088 os_memcpy(pos, hash, clen);
5089 pos += clen;
5090 left -= clen;
5091 }
5092 res = 0;
5093 fail:
5094 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
5095 EVP_MAC_free(hmac);
5096 EVP_MAC_CTX_free(hctx);
5097 #else /* OpenSSL version >= 3.0 */
5098 HMAC_CTX_free(hctx);
5099 #endif /* OpenSSL version >= 3.0 */
5100 os_free(labeled_info);
5101
5102 return res;
5103 }
5104
5105
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)5106 static int hpke_extract_and_expand(struct hpke_context *ctx,
5107 const u8 *dhss, size_t dhss_len,
5108 const u8 *enc, size_t enc_len,
5109 const u8 *pk_rm, size_t pk_rm_len,
5110 u8 *shared_secret)
5111 {
5112 u8 kem_context[2 * HPKE_MAX_PUB_LEN];
5113 u8 eae_prk[HPKE_MAX_HASH_LEN];
5114
5115 /* eae_prk = LabeledExtract("", "eae_prk", dh) */
5116 if (hpke_labeled_extract(ctx, true, NULL, 0, "eae_prk", dhss, dhss_len,
5117 eae_prk) < 0)
5118 return -1;
5119
5120 if (enc_len > HPKE_MAX_PUB_LEN || pk_rm_len > HPKE_MAX_PUB_LEN)
5121 return -1;
5122 /* kem_context = concat(enc, pkRm) */
5123 os_memcpy(kem_context, enc, enc_len);
5124 os_memcpy(&kem_context[enc_len], pk_rm, pk_rm_len);
5125
5126 /* shared_secret = LabeledExpand(eae_prk, "shared_secret",
5127 * kem_context, Nsecret) */
5128 if (hpke_labeled_expand(ctx, true, eae_prk, "shared_secret",
5129 kem_context, enc_len + pk_rm_len,
5130 shared_secret, ctx->n_secret) < 0)
5131 return -1;
5132
5133 forced_memzero(eae_prk, sizeof(eae_prk));
5134 return 0;
5135 }
5136
5137
hpke_key_schedule(struct hpke_context * ctx,const u8 * shared_secret,const u8 * info,size_t info_len)5138 static int hpke_key_schedule(struct hpke_context *ctx, const u8 *shared_secret,
5139 const u8 *info, size_t info_len)
5140 {
5141 u8 key_schedule_context[1 + 2 * HPKE_MAX_HASH_LEN];
5142 u8 secret[HPKE_MAX_HASH_LEN];
5143 int res = -1;
5144
5145 /* key_schedule_context = concat(mode, psk_id_hash, info_hash) */
5146 key_schedule_context[0] = HPKE_MODE_BASE;
5147
5148 /* psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id) */
5149 if (hpke_labeled_extract(ctx, false, NULL, 0, "psk_id_hash",
5150 NULL, 0, &key_schedule_context[1]) < 0)
5151 goto fail;
5152
5153 /* info_hash = LabeledExtract("", "info_hash", info) */
5154 if (hpke_labeled_extract(ctx, false, NULL, 0, "info_hash",
5155 info, info_len,
5156 &key_schedule_context[1 + ctx->n_h]) < 0)
5157 goto fail;
5158
5159 /* secret = LabeledExtract(shared_secret, "secret", psk) */
5160 if (hpke_labeled_extract(ctx, false, shared_secret, ctx->n_secret,
5161 "secret", NULL, 0, secret) < 0)
5162 goto fail;
5163
5164 /* key = LabeledExpand(secret, "key", key_schedule_context, Nk) */
5165 if (hpke_labeled_expand(ctx, false, secret, "key",
5166 key_schedule_context, 1 + 2 * ctx->n_h,
5167 ctx->key, ctx->n_k) < 0)
5168 goto fail;
5169
5170 /* base_nonce = LabeledExpand(secret, "base_nonce",
5171 * key_schedule_context, Nn) */
5172 if (hpke_labeled_expand(ctx, false, secret, "base_nonce",
5173 key_schedule_context, 1 + 2 * ctx->n_h,
5174 ctx->base_nonce, ctx->n_n) < 0)
5175 goto fail;
5176 res = 0;
5177 fail:
5178 forced_memzero(key_schedule_context, sizeof(key_schedule_context));
5179 forced_memzero(secret, sizeof(secret));
5180 return res;
5181 }
5182
5183
hpke_encap(struct hpke_context * ctx,struct crypto_ec_key * pk_r,u8 * shared_secret,u8 * enc)5184 static int hpke_encap(struct hpke_context *ctx, struct crypto_ec_key *pk_r,
5185 u8 *shared_secret, u8 *enc)
5186 {
5187 EVP_PKEY_CTX *pctx = NULL;
5188 struct crypto_ec_key *sk_e;
5189 int res = -1;
5190 u8 *dhss = NULL;
5191 size_t dhss_len = 0;
5192 struct wpabuf *enc_buf = NULL, *pk_rm = NULL;
5193
5194 /* skE, pkE = GenerateKeyPair() */
5195 sk_e = crypto_ec_key_gen(ctx->iana_group);
5196 if (!sk_e) {
5197 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not generate key pair",
5198 __func__);
5199 goto fail;
5200 }
5201
5202 /* dh = DH(skE, pkR) */
5203 dhss_len = sizeof(dhss);
5204 pctx = EVP_PKEY_CTX_new((EVP_PKEY *) sk_e, NULL);
5205 if (!pctx ||
5206 EVP_PKEY_derive_init(pctx) != 1 ||
5207 EVP_PKEY_derive_set_peer(pctx, (EVP_PKEY *) pk_r) != 1 ||
5208 EVP_PKEY_derive(pctx, NULL, &dhss_len) != 1 ||
5209 !(dhss = os_malloc(dhss_len)) ||
5210 EVP_PKEY_derive(pctx, dhss, &dhss_len) != 1 ||
5211 dhss_len > HPKE_MAX_SHARED_SECRET_LEN) {
5212 wpa_printf(MSG_INFO,
5213 "OpenSSL: hpke_encap: EVP_PKEY_derive failed (dhss_len=%zu): %s",
5214 dhss_len, ERR_error_string(ERR_get_error(), NULL));
5215 goto fail;
5216 }
5217
5218 /* enc = SerializePublicKey(pkE) */
5219 enc_buf = crypto_ec_key_get_pubkey_point(sk_e, 1);
5220 if (!enc_buf)
5221 goto fail;
5222 os_memcpy(enc, wpabuf_head(enc_buf), wpabuf_len(enc_buf));
5223
5224 /* pkRm = SerializePublicKey(pkR) */
5225 pk_rm = crypto_ec_key_get_pubkey_point(pk_r, 1);
5226 if (!pk_rm)
5227 goto fail;
5228
5229 /* kem_context = concat(enc, pkRm) */
5230 /* shared_secret = ExtractAndExpand(dh, kem_context) */
5231 /* return shared_secret, enc */
5232 res = hpke_extract_and_expand(ctx, dhss, dhss_len, enc, ctx->n_pk,
5233 wpabuf_head(pk_rm),
5234 wpabuf_len(pk_rm), shared_secret);
5235 fail:
5236 bin_clear_free(dhss, dhss_len);
5237 crypto_ec_key_deinit(sk_e);
5238 EVP_PKEY_CTX_free(pctx);
5239 wpabuf_free(enc_buf);
5240 wpabuf_free(pk_rm);
5241 return res;
5242 }
5243
5244
5245 static struct wpabuf *
hpke_aead_seal(struct hpke_context * ctx,const u8 * aad,size_t aad_len,const u8 * pt,size_t pt_len)5246 hpke_aead_seal(struct hpke_context *ctx, const u8 *aad, size_t aad_len,
5247 const u8 *pt, size_t pt_len)
5248 {
5249 EVP_CIPHER_CTX *cctx;
5250 int len = 0;
5251 struct wpabuf *ct = NULL;
5252
5253 /* No need to xor in sequence number since we support only the
5254 * single-shot API, i.e., base_nonce can be used as-is. */
5255
5256 cctx = EVP_CIPHER_CTX_new();
5257 if (!cctx ||
5258 EVP_EncryptInit_ex(cctx, ctx->cipher, NULL, ctx->key,
5259 ctx->base_nonce) != 1) {
5260 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptInit_ex failed",
5261 __func__);
5262 goto fail;
5263 }
5264 if (aad && aad_len &&
5265 EVP_EncryptUpdate(cctx, NULL, &len, aad, aad_len) != 1) {
5266 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_EncryptUpdate(AAD) failed",
5267 __func__);
5268 goto fail;
5269 }
5270 ct = wpabuf_alloc(pt_len + AES_BLOCK_SIZE + ctx->n_t);
5271 if (!ct)
5272 goto fail;
5273 if (EVP_EncryptUpdate(cctx, wpabuf_put(ct, 0), &len, pt, pt_len) != 1) {
5274 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_EncryptUpdate failed",
5275 __func__);
5276 goto fail;
5277 }
5278 wpabuf_put(ct, len);
5279
5280 if (EVP_EncryptFinal(cctx, wpabuf_put(ct, 0), &len) != 1) {
5281 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptFinal failed",
5282 __func__);
5283 wpabuf_free(ct);
5284 ct = NULL;
5285 goto fail;
5286 }
5287
5288 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, ctx->n_t,
5289 wpabuf_put(ct, ctx->n_t)) != 1) {
5290 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not get tag",
5291 __func__);
5292 wpabuf_free(ct);
5293 ct = NULL;
5294 goto fail;
5295 }
5296 fail:
5297 EVP_CIPHER_CTX_free(cctx);
5298 return ct;
5299 }
5300
5301
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)5302 static struct wpabuf * hpke_base_seal_int(enum hpke_kem_id kem_id,
5303 enum hpke_kdf_id kdf_id,
5304 enum hpke_aead_id aead_id,
5305 struct crypto_ec_key *peer_pub,
5306 const u8 *info, size_t info_len,
5307 const u8 *aad, size_t aad_len,
5308 const u8 *pt, size_t pt_len)
5309 {
5310 struct hpke_context *ctx;
5311 u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
5312 u8 enc[1 + 2 * HPKE_MAX_PUB_LEN];
5313 struct wpabuf *ct = NULL, *enc_ct = NULL;
5314
5315 ctx = hpke_get_context(kem_id, kdf_id, aead_id, peer_pub);
5316 if (!ctx)
5317 return NULL;
5318
5319 /* shared_secret, enc = Encap(pkR) */
5320 if (hpke_encap(ctx, peer_pub, shared_secret, enc) < 0)
5321 goto fail;
5322
5323 /* KeyScheduleS(mode_base, shared_secret, info,
5324 * default_psk, default_psk_id) */
5325 if (hpke_key_schedule(ctx, shared_secret, info, info_len) < 0)
5326 goto fail;
5327
5328 /* ct = ctx.Seal(aad, pt) */
5329 ct = hpke_aead_seal(ctx, aad, aad_len, pt, pt_len);
5330 if (!ct)
5331 goto fail;
5332
5333 /* return enc, ct */
5334 enc_ct = wpabuf_alloc(ctx->n_pk + wpabuf_len(ct));
5335 if (!enc_ct)
5336 goto fail;
5337 wpabuf_put_data(enc_ct, enc, ctx->n_pk);
5338 wpabuf_put_buf(enc_ct, ct);
5339
5340 fail:
5341 forced_memzero(shared_secret, sizeof(shared_secret));
5342 hpke_free_context(ctx);
5343 wpabuf_free(ct);
5344 return enc_ct;
5345 }
5346
5347
hpke_decap(struct hpke_context * ctx,const u8 * enc,size_t enc_ct_len,struct crypto_ec_key * sk_r,u8 * shared_secret)5348 static int hpke_decap(struct hpke_context *ctx, const u8 *enc,
5349 size_t enc_ct_len, struct crypto_ec_key *sk_r,
5350 u8 *shared_secret)
5351 {
5352 EVP_PKEY_CTX *pctx = NULL;
5353 struct wpabuf *pk_rm = NULL;
5354 size_t len;
5355 int res = -1;
5356 struct crypto_ec_key *pk_e = NULL;
5357 u8 *dhss = NULL;
5358 size_t dhss_len = 0;
5359
5360 /* pkE = DeserializePublicKey(enc) */
5361 if (enc_ct_len < ctx->n_pk)
5362 return -1; /* not enough room for enc */
5363 if (enc[0] != 0x04)
5364 return -1; /* not in uncompressed form */
5365 len = (ctx->n_pk - 1) / 2;
5366 pk_e = crypto_ec_key_set_pub(ctx->iana_group, &enc[1],
5367 &enc[1 + len], len);
5368 if (!pk_e)
5369 return -1; /* invalid public key point */
5370 /* dh = DH(skR, pkE) */
5371 pctx = EVP_PKEY_CTX_new((EVP_PKEY *) sk_r, NULL);
5372 if (!pctx ||
5373 EVP_PKEY_derive_init(pctx) != 1 ||
5374 EVP_PKEY_derive_set_peer(pctx, (EVP_PKEY *) pk_e) != 1 ||
5375 EVP_PKEY_derive(pctx, NULL, &dhss_len) != 1 ||
5376 !(dhss = os_malloc(dhss_len)) ||
5377 EVP_PKEY_derive(pctx, dhss, &dhss_len) != 1 ||
5378 dhss_len > HPKE_MAX_SHARED_SECRET_LEN) {
5379 wpa_printf(MSG_INFO,
5380 "OpenSSL: hpke_decap: EVP_PKEY_derive failed (dhss_len=%zu): %s",
5381 dhss_len, ERR_error_string(ERR_get_error(), NULL));
5382 goto fail;
5383 }
5384
5385 /* pkRm = SerializePublicKey(pk(skR)) */
5386 pk_rm = crypto_ec_key_get_pubkey_point(sk_r, 1);
5387 if (!pk_rm)
5388 goto fail;
5389
5390 /* kem_context = concat(enc, pkRm) */
5391 /* shared_secret = ExtractAndExpand(dh, kem_context) */
5392 res = hpke_extract_and_expand(ctx, dhss, dhss_len, enc, ctx->n_pk,
5393 wpabuf_head(pk_rm),
5394 wpabuf_len(pk_rm), shared_secret);
5395 fail:
5396 bin_clear_free(dhss, dhss_len);
5397 crypto_ec_key_deinit(pk_e);
5398 EVP_PKEY_CTX_free(pctx);
5399 wpabuf_free(pk_rm);
5400 return res;
5401 }
5402
5403
5404 static struct wpabuf *
hpke_aead_open(struct hpke_context * ctx,const u8 * aad,size_t aad_len,const u8 * ct,size_t ct_len)5405 hpke_aead_open(struct hpke_context *ctx, const u8 *aad, size_t aad_len,
5406 const u8 *ct, size_t ct_len)
5407 {
5408 EVP_CIPHER_CTX *cctx;
5409 int len = 0;
5410 const u8 *tag;
5411 struct wpabuf *pt = NULL;
5412
5413 if (ct_len < ctx->n_t)
5414 return NULL;
5415 tag = ct + ct_len - ctx->n_t;
5416 ct_len -= ctx->n_t;
5417
5418 /* No need to xor in sequence number since we support only the
5419 * single-shot API, i.e., base_nonce can be used as-is. */
5420
5421 cctx = EVP_CIPHER_CTX_new();
5422 if (!cctx ||
5423 EVP_DecryptInit_ex(cctx, ctx->cipher, NULL, ctx->key,
5424 ctx->base_nonce) != 1) {
5425 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptInit_ex failed",
5426 __func__);
5427 goto fail;
5428 }
5429 if (aad && aad_len &&
5430 EVP_DecryptUpdate(cctx, NULL, &len, aad, aad_len) != 1) {
5431 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptUpdate(AAD) failed",
5432 __func__);
5433 goto fail;
5434 }
5435 pt = wpabuf_alloc(ct_len + AES_BLOCK_SIZE);
5436 if (!pt)
5437 goto fail;
5438 if (EVP_DecryptUpdate(cctx, wpabuf_put(pt, 0), &len, ct, ct_len) != 1) {
5439 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptUpdate failed",
5440 __func__);
5441 goto fail;
5442 }
5443 wpabuf_put(pt, len);
5444
5445 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_SET_TAG, ctx->n_t,
5446 (void *) tag) != 1) {
5447 wpa_printf(MSG_INFO, "OpenSSL:%s:Could not set tag",
5448 __func__);
5449 wpabuf_free(pt);
5450 pt = NULL;
5451 goto fail;
5452 }
5453
5454 if (EVP_DecryptFinal(cctx, wpabuf_put(pt, 0), &len) != 1) {
5455 wpa_printf(MSG_INFO, "OpenSSL:%s:EVP_DecryptFinal failed",
5456 __func__);
5457 wpabuf_free(pt);
5458 pt = NULL;
5459 }
5460 fail:
5461 EVP_CIPHER_CTX_free(cctx);
5462 return pt;
5463 }
5464
5465
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)5466 static struct wpabuf * hpke_base_open_int(enum hpke_kem_id kem_id,
5467 enum hpke_kdf_id kdf_id,
5468 enum hpke_aead_id aead_id,
5469 struct crypto_ec_key *own_priv,
5470 const u8 *info, size_t info_len,
5471 const u8 *aad, size_t aad_len,
5472 const u8 *enc_ct, size_t enc_ct_len)
5473 {
5474 struct hpke_context *ctx;
5475 u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
5476 struct wpabuf *pt = NULL;
5477
5478 ctx = hpke_get_context(kem_id, kdf_id, aead_id, own_priv);
5479 if (!ctx)
5480 return NULL;
5481
5482 /* shared_secret = Decap(enc, skR) */
5483 if (hpke_decap(ctx, enc_ct, enc_ct_len, own_priv, shared_secret) < 0)
5484 goto fail;
5485
5486 /* KeyScheduleR(mode_base, shared_secret, info,
5487 * default_psk, default_psk_id) */
5488 if (hpke_key_schedule(ctx, shared_secret, info, info_len) < 0)
5489 goto fail;
5490
5491 /* return ctx.Open(aad, ct) */
5492 pt = hpke_aead_open(ctx, aad, aad_len,
5493 &enc_ct[ctx->n_pk], enc_ct_len - ctx->n_pk);
5494
5495 fail:
5496 forced_memzero(shared_secret, sizeof(shared_secret));
5497 hpke_free_context(ctx);
5498 return pt;
5499 }
5500
5501
5502 #if OPENSSL_VERSION_NUMBER >= 0x30200000L
5503
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)5504 static bool hpke_set_suite(OSSL_HPKE_SUITE *suite,
5505 enum hpke_kem_id kem_id,
5506 enum hpke_kdf_id kdf_id,
5507 enum hpke_aead_id aead_id)
5508 {
5509 os_memset(suite, 0, sizeof(*suite));
5510
5511 switch (kem_id) {
5512 case HPKE_DHKEM_P256_HKDF_SHA256:
5513 suite->kem_id = OSSL_HPKE_KEM_ID_P256;
5514 break;
5515 case HPKE_DHKEM_P384_HKDF_SHA384:
5516 suite->kem_id = OSSL_HPKE_KEM_ID_P384;
5517 break;
5518 case HPKE_DHKEM_P521_HKDF_SHA512:
5519 suite->kem_id = OSSL_HPKE_KEM_ID_P521;
5520 break;
5521 default:
5522 return false;
5523 }
5524
5525 switch (kdf_id) {
5526 case HPKE_KDF_HKDF_SHA256:
5527 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA256;
5528 break;
5529 case HPKE_KDF_HKDF_SHA384:
5530 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA384;
5531 break;
5532 case HPKE_KDF_HKDF_SHA512:
5533 suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA512;
5534 break;
5535 default:
5536 return false;
5537 }
5538
5539 switch (aead_id) {
5540 case HPKE_AEAD_AES_128_GCM:
5541 suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_128;
5542 break;
5543 case HPKE_AEAD_AES_256_GCM:
5544 suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_256;
5545 break;
5546 default:
5547 return false;
5548 }
5549
5550 if (!OSSL_HPKE_suite_check(*suite)) {
5551 wpa_printf(MSG_INFO,
5552 "OpenSSL: HPKE suite kem_id=%d kdf_id=%d aead_id=%d not supported",
5553 kem_id, kdf_id, aead_id);
5554 return false;
5555 }
5556
5557 return true;
5558 }
5559
5560
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)5561 struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
5562 enum hpke_kdf_id kdf_id,
5563 enum hpke_aead_id aead_id,
5564 struct crypto_ec_key *peer_pub,
5565 const u8 *info, size_t info_len,
5566 const u8 *aad, size_t aad_len,
5567 const u8 *pt, size_t pt_len)
5568 {
5569 OSSL_HPKE_SUITE suite;
5570 OSSL_HPKE_CTX *ctx = NULL;
5571 struct wpabuf *res = NULL, *buf, *pub = NULL;
5572 size_t enc_len, ct_len;
5573 int group;
5574
5575 group = crypto_ec_key_group(peer_pub);
5576 if (group == 28 || group == 29 || group == 30) {
5577 /* Use the internal routines for the special DPP use case with
5578 * brainpool curves, */
5579 return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
5580 info, info_len, aad, aad_len,
5581 pt, pt_len);
5582 }
5583
5584
5585 if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
5586 return NULL;
5587
5588 enc_len = OSSL_HPKE_get_public_encap_size(suite);
5589 ct_len = OSSL_HPKE_get_ciphertext_size(suite, pt_len);
5590 buf = wpabuf_alloc(enc_len + ct_len);
5591 if (!buf)
5592 goto out;
5593
5594 pub = crypto_ec_key_get_pubkey_point(peer_pub, 1);
5595 if (!pub)
5596 goto out;
5597
5598 ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
5599 OSSL_HPKE_ROLE_SENDER, NULL, NULL);
5600 if (!ctx)
5601 goto out;
5602
5603 if (OSSL_HPKE_encap(ctx, wpabuf_put(buf, 0), &enc_len,
5604 wpabuf_head(pub), wpabuf_len(pub),
5605 info, info_len) != 1) {
5606 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_encap failed: %s",
5607 ERR_error_string(ERR_get_error(), NULL));
5608 goto out;
5609 }
5610 wpabuf_put(buf, enc_len);
5611
5612 if (OSSL_HPKE_seal(ctx, wpabuf_put(buf, 0), &ct_len, aad, aad_len,
5613 pt, pt_len) != 1) {
5614 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_seal failed: %s",
5615 ERR_error_string(ERR_get_error(), NULL));
5616 goto out;
5617 }
5618 wpabuf_put(buf, ct_len);
5619 res = buf;
5620 buf = NULL;
5621
5622 out:
5623 OSSL_HPKE_CTX_free(ctx);
5624 wpabuf_free(buf);
5625 wpabuf_free(pub);
5626 return res;
5627 }
5628
5629
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)5630 struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
5631 enum hpke_kdf_id kdf_id,
5632 enum hpke_aead_id aead_id,
5633 struct crypto_ec_key *own_priv,
5634 const u8 *info, size_t info_len,
5635 const u8 *aad, size_t aad_len,
5636 const u8 *enc_ct, size_t enc_ct_len)
5637 {
5638 OSSL_HPKE_SUITE suite;
5639 OSSL_HPKE_CTX *ctx;
5640 struct wpabuf *buf = NULL, *res = NULL;
5641 size_t len, enc_len;
5642 int group;
5643
5644 group = crypto_ec_key_group(own_priv);
5645 if (group == 28 || group == 29 || group == 30) {
5646 /* Use the internal routines for the special DPP use case with
5647 * brainpool curves, */
5648 return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
5649 info, info_len, aad, aad_len,
5650 enc_ct, enc_ct_len);
5651 }
5652
5653 if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
5654 return NULL;
5655
5656 enc_len = OSSL_HPKE_get_public_encap_size(suite);
5657 if (enc_ct_len < enc_len) {
5658 wpa_printf(MSG_DEBUG, "OpenSSL: Too short HPKE enc_ct data");
5659 return NULL;
5660 }
5661
5662 ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
5663 OSSL_HPKE_ROLE_RECEIVER, NULL, NULL);
5664 if (!ctx)
5665 goto out;
5666
5667 if (OSSL_HPKE_decap(ctx, enc_ct, enc_len, (EVP_PKEY *) own_priv,
5668 info, info_len) != 1) {
5669 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_decap failed: %s",
5670 ERR_error_string(ERR_get_error(), NULL));
5671 goto out;
5672 }
5673
5674 len = enc_ct_len;
5675 buf = wpabuf_alloc(len);
5676 if (!buf)
5677 goto out;
5678
5679 if (OSSL_HPKE_open(ctx, wpabuf_put(buf, 0), &len, aad, aad_len,
5680 enc_ct + enc_len, enc_ct_len - enc_len) != 1) {
5681 wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_open failed: %s",
5682 ERR_error_string(ERR_get_error(), NULL));
5683 goto out;
5684 }
5685
5686 wpabuf_put(buf, len);
5687 res = buf;
5688 buf = NULL;
5689
5690 out:
5691 OSSL_HPKE_CTX_free(ctx);
5692 wpabuf_free(buf);
5693 return res;
5694 }
5695
5696 #else /* OpenSSL < 3.2 */
5697
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)5698 struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
5699 enum hpke_kdf_id kdf_id,
5700 enum hpke_aead_id aead_id,
5701 struct crypto_ec_key *peer_pub,
5702 const u8 *info, size_t info_len,
5703 const u8 *aad, size_t aad_len,
5704 const u8 *pt, size_t pt_len)
5705 {
5706 return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
5707 info, info_len, aad, aad_len, pt, pt_len);
5708 }
5709
5710
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)5711 struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
5712 enum hpke_kdf_id kdf_id,
5713 enum hpke_aead_id aead_id,
5714 struct crypto_ec_key *own_priv,
5715 const u8 *info, size_t info_len,
5716 const u8 *aad, size_t aad_len,
5717 const u8 *enc_ct, size_t enc_ct_len)
5718 {
5719 return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
5720 info, info_len, aad, aad_len,
5721 enc_ct, enc_ct_len);
5722 }
5723
5724 #endif /* OpenSSL < 3.2 */
5725
5726 #endif /* CONFIG_DPP3 */
5727
5728
crypto_unload(void)5729 void crypto_unload(void)
5730 {
5731 openssl_unload_legacy_provider();
5732 openssl_unload_default_provider();
5733 }
5734