blob: f47beebebf3157f1159f63bdb787bdf0399da5ad [file] [log] [blame]
Roshan Pius3a1667e2018-07-03 15:17:14 -07001/*
2 * Wrapper functions for libwolfssl
3 * Copyright (c) 2004-2017, 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
11#include "common.h"
12#include "crypto.h"
13
14/* wolfSSL headers */
15#include <wolfssl/options.h>
16#include <wolfssl/wolfcrypt/md4.h>
17#include <wolfssl/wolfcrypt/md5.h>
18#include <wolfssl/wolfcrypt/sha.h>
19#include <wolfssl/wolfcrypt/sha256.h>
20#include <wolfssl/wolfcrypt/sha512.h>
21#include <wolfssl/wolfcrypt/hmac.h>
22#include <wolfssl/wolfcrypt/pwdbased.h>
23#include <wolfssl/wolfcrypt/arc4.h>
24#include <wolfssl/wolfcrypt/des3.h>
25#include <wolfssl/wolfcrypt/aes.h>
26#include <wolfssl/wolfcrypt/dh.h>
27#include <wolfssl/wolfcrypt/cmac.h>
28#include <wolfssl/wolfcrypt/ecc.h>
Sunil Ravia04bd252022-05-02 22:54:18 -070029#include <wolfssl/wolfcrypt/asn_public.h>
30#include <wolfssl/wolfcrypt/error-crypt.h>
Roshan Pius3a1667e2018-07-03 15:17:14 -070031#include <wolfssl/openssl/bn.h>
32
33
34#ifndef CONFIG_FIPS
35
36int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
37{
38 Md4 md4;
39 size_t i;
40
41 if (TEST_FAIL())
42 return -1;
43
44 wc_InitMd4(&md4);
45
46 for (i = 0; i < num_elem; i++)
47 wc_Md4Update(&md4, addr[i], len[i]);
48
49 wc_Md4Final(&md4, mac);
50
51 return 0;
52}
53
54
55int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
56{
57 wc_Md5 md5;
58 size_t i;
59
60 if (TEST_FAIL())
61 return -1;
62
63 wc_InitMd5(&md5);
64
65 for (i = 0; i < num_elem; i++)
66 wc_Md5Update(&md5, addr[i], len[i]);
67
68 wc_Md5Final(&md5, mac);
69
70 return 0;
71}
72
73#endif /* CONFIG_FIPS */
74
75
76int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
77{
78 wc_Sha sha;
79 size_t i;
80
81 if (TEST_FAIL())
82 return -1;
83
84 wc_InitSha(&sha);
85
86 for (i = 0; i < num_elem; i++)
87 wc_ShaUpdate(&sha, addr[i], len[i]);
88
89 wc_ShaFinal(&sha, mac);
Sunil Ravia04bd252022-05-02 22:54:18 -070090 wc_ShaFree(&sha);
Roshan Pius3a1667e2018-07-03 15:17:14 -070091
92 return 0;
93}
94
95
96#ifndef NO_SHA256_WRAPPER
97int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
98 u8 *mac)
99{
100 wc_Sha256 sha256;
101 size_t i;
102
103 if (TEST_FAIL())
104 return -1;
105
106 wc_InitSha256(&sha256);
107
108 for (i = 0; i < num_elem; i++)
109 wc_Sha256Update(&sha256, addr[i], len[i]);
110
111 wc_Sha256Final(&sha256, mac);
Sunil Ravia04bd252022-05-02 22:54:18 -0700112 wc_Sha256Free(&sha256);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700113
114 return 0;
115}
116#endif /* NO_SHA256_WRAPPER */
117
118
119#ifdef CONFIG_SHA384
120int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
121 u8 *mac)
122{
123 wc_Sha384 sha384;
124 size_t i;
125
126 if (TEST_FAIL())
127 return -1;
128
129 wc_InitSha384(&sha384);
130
131 for (i = 0; i < num_elem; i++)
132 wc_Sha384Update(&sha384, addr[i], len[i]);
133
134 wc_Sha384Final(&sha384, mac);
Sunil Ravia04bd252022-05-02 22:54:18 -0700135 wc_Sha384Free(&sha384);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700136
137 return 0;
138}
139#endif /* CONFIG_SHA384 */
140
141
142#ifdef CONFIG_SHA512
143int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
144 u8 *mac)
145{
146 wc_Sha512 sha512;
147 size_t i;
148
149 if (TEST_FAIL())
150 return -1;
151
152 wc_InitSha512(&sha512);
153
154 for (i = 0; i < num_elem; i++)
155 wc_Sha512Update(&sha512, addr[i], len[i]);
156
157 wc_Sha512Final(&sha512, mac);
Sunil Ravia04bd252022-05-02 22:54:18 -0700158 wc_Sha512Free(&sha512);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700159
160 return 0;
161}
162#endif /* CONFIG_SHA512 */
163
164
165static int wolfssl_hmac_vector(int type, const u8 *key,
166 size_t key_len, size_t num_elem,
167 const u8 *addr[], const size_t *len, u8 *mac,
168 unsigned int mdlen)
169{
170 Hmac hmac;
171 size_t i;
172
173 (void) mdlen;
174
175 if (TEST_FAIL())
176 return -1;
177
Sunil Ravia04bd252022-05-02 22:54:18 -0700178 if (wc_HmacInit(&hmac, NULL, INVALID_DEVID) != 0 ||
179 wc_HmacSetKey(&hmac, type, key, (word32) key_len) != 0)
Roshan Pius3a1667e2018-07-03 15:17:14 -0700180 return -1;
181 for (i = 0; i < num_elem; i++)
182 if (wc_HmacUpdate(&hmac, addr[i], len[i]) != 0)
183 return -1;
184 if (wc_HmacFinal(&hmac, mac) != 0)
185 return -1;
Sunil Ravia04bd252022-05-02 22:54:18 -0700186 wc_HmacFree(&hmac);
187
Roshan Pius3a1667e2018-07-03 15:17:14 -0700188 return 0;
189}
190
191
192#ifndef CONFIG_FIPS
193
194int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
195 const u8 *addr[], const size_t *len, u8 *mac)
196{
197 return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len,
198 mac, 16);
199}
200
201
202int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
203 u8 *mac)
204{
205 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
206}
207
208#endif /* CONFIG_FIPS */
209
210
211int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
212 const u8 *addr[], const size_t *len, u8 *mac)
213{
214 return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len,
215 mac, 20);
216}
217
218
219int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
220 u8 *mac)
221{
222 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
223}
224
225
226#ifdef CONFIG_SHA256
227
228int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
229 const u8 *addr[], const size_t *len, u8 *mac)
230{
231 return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
232 mac, 32);
233}
234
235
236int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
237 size_t data_len, u8 *mac)
238{
239 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
240}
241
242#endif /* CONFIG_SHA256 */
243
244
245#ifdef CONFIG_SHA384
246
247int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
248 const u8 *addr[], const size_t *len, u8 *mac)
249{
250 return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
251 mac, 48);
252}
253
254
255int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
256 size_t data_len, u8 *mac)
257{
258 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
259}
260
261#endif /* CONFIG_SHA384 */
262
263
264#ifdef CONFIG_SHA512
265
266int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
267 const u8 *addr[], const size_t *len, u8 *mac)
268{
269 return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
270 mac, 64);
271}
272
273
274int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
275 size_t data_len, u8 *mac)
276{
277 return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
278}
279
280#endif /* CONFIG_SHA512 */
281
282
283int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
284 int iterations, u8 *buf, size_t buflen)
285{
Sunil Ravia04bd252022-05-02 22:54:18 -0700286 int ret;
287
288 ret = wc_PBKDF2(buf, (const byte *) passphrase, os_strlen(passphrase),
289 ssid, ssid_len, iterations, buflen, WC_SHA);
290 if (ret != 0) {
291 if (ret == HMAC_MIN_KEYLEN_E) {
292 wpa_printf(MSG_ERROR,
293 "wolfSSL: Password is too short. Make sure your password is at least %d characters long. This is a requirement for FIPS builds.",
294 HMAC_FIPS_MIN_KEY);
295 }
Roshan Pius3a1667e2018-07-03 15:17:14 -0700296 return -1;
Sunil Ravia04bd252022-05-02 22:54:18 -0700297 }
Roshan Pius3a1667e2018-07-03 15:17:14 -0700298 return 0;
299}
300
301
302#ifdef CONFIG_DES
303int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
304{
305 Des des;
306 u8 pkey[8], next, tmp;
307 int i;
308
309 /* Add parity bits to the key */
310 next = 0;
311 for (i = 0; i < 7; i++) {
312 tmp = key[i];
313 pkey[i] = (tmp >> i) | next | 1;
314 next = tmp << (7 - i);
315 }
316 pkey[i] = next | 1;
317
318 wc_Des_SetKey(&des, pkey, NULL, DES_ENCRYPTION);
319 wc_Des_EcbEncrypt(&des, cypher, clear, DES_BLOCK_SIZE);
320
321 return 0;
322}
323#endif /* CONFIG_DES */
324
325
326void * aes_encrypt_init(const u8 *key, size_t len)
327{
328 Aes *aes;
329
330 if (TEST_FAIL())
331 return NULL;
332
333 aes = os_malloc(sizeof(Aes));
334 if (!aes)
335 return NULL;
336
337 if (wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION) < 0) {
338 os_free(aes);
339 return NULL;
340 }
341
342 return aes;
343}
344
345
346int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
347{
348 wc_AesEncryptDirect(ctx, crypt, plain);
349 return 0;
350}
351
352
353void aes_encrypt_deinit(void *ctx)
354{
355 os_free(ctx);
356}
357
358
359void * aes_decrypt_init(const u8 *key, size_t len)
360{
361 Aes *aes;
362
363 if (TEST_FAIL())
364 return NULL;
365
366 aes = os_malloc(sizeof(Aes));
367 if (!aes)
368 return NULL;
369
370 if (wc_AesSetKey(aes, key, len, NULL, AES_DECRYPTION) < 0) {
371 os_free(aes);
372 return NULL;
373 }
374
375 return aes;
376}
377
378
379int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
380{
381 wc_AesDecryptDirect(ctx, plain, crypt);
382 return 0;
383}
384
385
386void aes_decrypt_deinit(void *ctx)
387{
388 os_free(ctx);
389}
390
391
392int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
393{
394 Aes aes;
395 int ret;
396
397 if (TEST_FAIL())
398 return -1;
399
400 ret = wc_AesSetKey(&aes, key, 16, iv, AES_ENCRYPTION);
401 if (ret != 0)
402 return -1;
403
404 ret = wc_AesCbcEncrypt(&aes, data, data, data_len);
405 if (ret != 0)
406 return -1;
407 return 0;
408}
409
410
411int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
412{
413 Aes aes;
414 int ret;
415
416 if (TEST_FAIL())
417 return -1;
418
419 ret = wc_AesSetKey(&aes, key, 16, iv, AES_DECRYPTION);
420 if (ret != 0)
421 return -1;
422
423 ret = wc_AesCbcDecrypt(&aes, data, data, data_len);
424 if (ret != 0)
425 return -1;
426 return 0;
427}
428
429
Sunil Ravia04bd252022-05-02 22:54:18 -0700430#ifndef CONFIG_FIPS
431#ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
Roshan Pius3a1667e2018-07-03 15:17:14 -0700432int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
433{
Sunil Ravia04bd252022-05-02 22:54:18 -0700434#ifdef HAVE_AES_KEYWRAP
Roshan Pius3a1667e2018-07-03 15:17:14 -0700435 int ret;
436
437 if (TEST_FAIL())
438 return -1;
439
440 ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
441 NULL);
442 return ret != (n + 1) * 8 ? -1 : 0;
Sunil Ravia04bd252022-05-02 22:54:18 -0700443#else /* HAVE_AES_KEYWRAP */
444 return -1;
445#endif /* HAVE_AES_KEYWRAP */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700446}
447
448
449int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
450 u8 *plain)
451{
Sunil Ravia04bd252022-05-02 22:54:18 -0700452#ifdef HAVE_AES_KEYWRAP
Roshan Pius3a1667e2018-07-03 15:17:14 -0700453 int ret;
454
455 if (TEST_FAIL())
456 return -1;
457
458 ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
459 NULL);
460 return ret != n * 8 ? -1 : 0;
Sunil Ravia04bd252022-05-02 22:54:18 -0700461#else /* HAVE_AES_KEYWRAP */
462 return -1;
463#endif /* HAVE_AES_KEYWRAP */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700464}
Sunil Ravia04bd252022-05-02 22:54:18 -0700465#endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
466#endif /* CONFIG_FIPS */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700467
468
469#ifndef CONFIG_NO_RC4
470int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data,
471 size_t data_len)
472{
473#ifndef NO_RC4
474 Arc4 arc4;
475 unsigned char skip_buf[16];
476
477 wc_Arc4SetKey(&arc4, key, keylen);
478
479 while (skip >= sizeof(skip_buf)) {
480 size_t len = skip;
481
482 if (len > sizeof(skip_buf))
483 len = sizeof(skip_buf);
484 wc_Arc4Process(&arc4, skip_buf, skip_buf, len);
485 skip -= len;
486 }
487
488 wc_Arc4Process(&arc4, data, data, data_len);
489
490 return 0;
491#else /* NO_RC4 */
492 return -1;
493#endif /* NO_RC4 */
494}
495#endif /* CONFIG_NO_RC4 */
496
497
498#if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \
499 || defined(EAP_SERVER_IKEV2)
500union wolfssl_cipher {
501 Aes aes;
502 Des3 des3;
503 Arc4 arc4;
504};
505
506struct crypto_cipher {
507 enum crypto_cipher_alg alg;
508 union wolfssl_cipher enc;
509 union wolfssl_cipher dec;
510};
511
512struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
513 const u8 *iv, const u8 *key,
514 size_t key_len)
515{
516 struct crypto_cipher *ctx;
517
518 ctx = os_zalloc(sizeof(*ctx));
519 if (!ctx)
520 return NULL;
521
522 switch (alg) {
523#ifndef CONFIG_NO_RC4
524#ifndef NO_RC4
525 case CRYPTO_CIPHER_ALG_RC4:
526 wc_Arc4SetKey(&ctx->enc.arc4, key, key_len);
527 wc_Arc4SetKey(&ctx->dec.arc4, key, key_len);
528 break;
529#endif /* NO_RC4 */
530#endif /* CONFIG_NO_RC4 */
531#ifndef NO_AES
532 case CRYPTO_CIPHER_ALG_AES:
533 switch (key_len) {
534 case 16:
535 case 24:
536 case 32:
537 break;
538 default:
539 os_free(ctx);
540 return NULL;
541 }
542 if (wc_AesSetKey(&ctx->enc.aes, key, key_len, iv,
543 AES_ENCRYPTION) ||
544 wc_AesSetKey(&ctx->dec.aes, key, key_len, iv,
545 AES_DECRYPTION)) {
546 os_free(ctx);
547 return NULL;
548 }
549 break;
550#endif /* NO_AES */
551#ifndef NO_DES3
552 case CRYPTO_CIPHER_ALG_3DES:
553 if (key_len != DES3_KEYLEN ||
554 wc_Des3_SetKey(&ctx->enc.des3, key, iv, DES_ENCRYPTION) ||
555 wc_Des3_SetKey(&ctx->dec.des3, key, iv, DES_DECRYPTION)) {
556 os_free(ctx);
557 return NULL;
558 }
559 break;
560#endif /* NO_DES3 */
561 case CRYPTO_CIPHER_ALG_RC2:
562 case CRYPTO_CIPHER_ALG_DES:
563 default:
564 os_free(ctx);
565 return NULL;
566 }
567
568 ctx->alg = alg;
569
570 return ctx;
571}
572
573
574int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
575 u8 *crypt, size_t len)
576{
577 switch (ctx->alg) {
578#ifndef CONFIG_NO_RC4
579#ifndef NO_RC4
580 case CRYPTO_CIPHER_ALG_RC4:
581 wc_Arc4Process(&ctx->enc.arc4, crypt, plain, len);
582 return 0;
583#endif /* NO_RC4 */
584#endif /* CONFIG_NO_RC4 */
585#ifndef NO_AES
586 case CRYPTO_CIPHER_ALG_AES:
587 if (wc_AesCbcEncrypt(&ctx->enc.aes, crypt, plain, len) != 0)
588 return -1;
589 return 0;
590#endif /* NO_AES */
591#ifndef NO_DES3
592 case CRYPTO_CIPHER_ALG_3DES:
593 if (wc_Des3_CbcEncrypt(&ctx->enc.des3, crypt, plain, len) != 0)
594 return -1;
595 return 0;
596#endif /* NO_DES3 */
597 default:
598 return -1;
599 }
600 return -1;
601}
602
603
604int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
605 u8 *plain, size_t len)
606{
607 switch (ctx->alg) {
608#ifndef CONFIG_NO_RC4
609#ifndef NO_RC4
610 case CRYPTO_CIPHER_ALG_RC4:
611 wc_Arc4Process(&ctx->dec.arc4, plain, crypt, len);
612 return 0;
613#endif /* NO_RC4 */
614#endif /* CONFIG_NO_RC4 */
615#ifndef NO_AES
616 case CRYPTO_CIPHER_ALG_AES:
617 if (wc_AesCbcDecrypt(&ctx->dec.aes, plain, crypt, len) != 0)
618 return -1;
619 return 0;
620#endif /* NO_AES */
621#ifndef NO_DES3
622 case CRYPTO_CIPHER_ALG_3DES:
623 if (wc_Des3_CbcDecrypt(&ctx->dec.des3, plain, crypt, len) != 0)
624 return -1;
625 return 0;
626#endif /* NO_DES3 */
627 default:
628 return -1;
629 }
630 return -1;
631}
632
633
634void crypto_cipher_deinit(struct crypto_cipher *ctx)
635{
636 os_free(ctx);
637}
638
639#endif
640
641
Hai Shaloma20dcd72022-02-04 13:43:00 -0800642#ifdef CONFIG_WPS
Roshan Pius3a1667e2018-07-03 15:17:14 -0700643
644static const unsigned char RFC3526_PRIME_1536[] = {
645 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
646 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
647 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
648 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
649 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
650 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
651 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
652 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
653 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
654 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
655 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
656 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
657 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
658 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
659 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
660 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
661};
662
663static const unsigned char RFC3526_GENERATOR_1536[] = {
664 0x02
665};
666
667#define RFC3526_LEN sizeof(RFC3526_PRIME_1536)
668
669
670void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
671{
672 WC_RNG rng;
673 DhKey *ret = NULL;
674 DhKey *dh = NULL;
675 struct wpabuf *privkey = NULL;
676 struct wpabuf *pubkey = NULL;
677 word32 priv_sz, pub_sz;
678
679 *priv = NULL;
680 wpabuf_free(*publ);
681 *publ = NULL;
682
683 dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
684 if (!dh)
685 return NULL;
686 wc_InitDhKey(dh);
687
688 if (wc_InitRng(&rng) != 0) {
689 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
690 return NULL;
691 }
692
693 privkey = wpabuf_alloc(RFC3526_LEN);
694 pubkey = wpabuf_alloc(RFC3526_LEN);
695 if (!privkey || !pubkey)
696 goto done;
697
698 if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
699 RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
700 != 0)
701 goto done;
702
Sunil Ravia04bd252022-05-02 22:54:18 -0700703 priv_sz = pub_sz = RFC3526_LEN;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700704 if (wc_DhGenerateKeyPair(dh, &rng, wpabuf_mhead(privkey), &priv_sz,
705 wpabuf_mhead(pubkey), &pub_sz) != 0)
706 goto done;
707
708 wpabuf_put(privkey, priv_sz);
709 wpabuf_put(pubkey, pub_sz);
710
711 ret = dh;
712 *priv = privkey;
713 *publ = pubkey;
714 dh = NULL;
715 privkey = NULL;
716 pubkey = NULL;
717done:
718 wpabuf_clear_free(pubkey);
719 wpabuf_clear_free(privkey);
720 if (dh) {
721 wc_FreeDhKey(dh);
722 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
723 }
724 wc_FreeRng(&rng);
725 return ret;
726}
727
728
Hai Shaloma20dcd72022-02-04 13:43:00 -0800729#ifdef CONFIG_WPS_NFC
730
Roshan Pius3a1667e2018-07-03 15:17:14 -0700731void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
732{
733 DhKey *ret = NULL;
734 DhKey *dh;
735 byte *secret;
736 word32 secret_sz;
737
738 dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
739 if (!dh)
740 return NULL;
741 wc_InitDhKey(dh);
742
743 secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
744 if (!secret)
745 goto done;
746
747 if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
748 RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
749 != 0)
750 goto done;
751
752 if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv),
753 wpabuf_len(priv), RFC3526_GENERATOR_1536,
754 sizeof(RFC3526_GENERATOR_1536)) != 0)
755 goto done;
756
757 if (secret_sz != wpabuf_len(publ) ||
758 os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0)
759 goto done;
760
761 ret = dh;
762 dh = NULL;
763done:
764 if (dh) {
765 wc_FreeDhKey(dh);
766 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
767 }
768 XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
769 return ret;
770}
771
Hai Shaloma20dcd72022-02-04 13:43:00 -0800772#endif /* CONFIG_WPS_NFC */
773
Roshan Pius3a1667e2018-07-03 15:17:14 -0700774
775struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
776 const struct wpabuf *own_private)
777{
778 struct wpabuf *ret = NULL;
779 struct wpabuf *secret;
780 word32 secret_sz;
781
782 secret = wpabuf_alloc(RFC3526_LEN);
783 if (!secret)
784 goto done;
785
786 if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz,
787 wpabuf_head(own_private), wpabuf_len(own_private),
788 wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0)
789 goto done;
790
791 wpabuf_put(secret, secret_sz);
792
793 ret = secret;
794 secret = NULL;
795done:
796 wpabuf_clear_free(secret);
797 return ret;
798}
799
800
801void dh5_free(void *ctx)
802{
803 if (!ctx)
804 return;
805
806 wc_FreeDhKey(ctx);
807 XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
808}
809
Hai Shaloma20dcd72022-02-04 13:43:00 -0800810#endif /* CONFIG_WPS */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700811
812
813int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
814 u8 *pubkey)
815{
816 int ret = -1;
817 WC_RNG rng;
818 DhKey *dh = NULL;
819 word32 priv_sz, pub_sz;
820
821 if (TEST_FAIL())
822 return -1;
823
824 dh = os_malloc(sizeof(DhKey));
825 if (!dh)
826 return -1;
827 wc_InitDhKey(dh);
828
829 if (wc_InitRng(&rng) != 0) {
830 os_free(dh);
831 return -1;
832 }
833
834 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
835 goto done;
836
Sunil Ravia04bd252022-05-02 22:54:18 -0700837 priv_sz = pub_sz = prime_len;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700838 if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz)
839 != 0)
840 goto done;
841
842 if (priv_sz < prime_len) {
843 size_t pad_sz = prime_len - priv_sz;
844
845 os_memmove(privkey + pad_sz, privkey, priv_sz);
846 os_memset(privkey, 0, pad_sz);
847 }
848
849 if (pub_sz < prime_len) {
850 size_t pad_sz = prime_len - pub_sz;
851
852 os_memmove(pubkey + pad_sz, pubkey, pub_sz);
853 os_memset(pubkey, 0, pad_sz);
854 }
855 ret = 0;
856done:
857 wc_FreeDhKey(dh);
858 os_free(dh);
859 wc_FreeRng(&rng);
860 return ret;
861}
862
863
864int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
Hai Shalom021b0b52019-04-10 11:17:58 -0700865 const u8 *order, size_t order_len,
Roshan Pius3a1667e2018-07-03 15:17:14 -0700866 const u8 *privkey, size_t privkey_len,
867 const u8 *pubkey, size_t pubkey_len,
868 u8 *secret, size_t *len)
869{
870 int ret = -1;
871 DhKey *dh;
872 word32 secret_sz;
873
874 dh = os_malloc(sizeof(DhKey));
875 if (!dh)
876 return -1;
877 wc_InitDhKey(dh);
878
879 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
880 goto done;
881
882 if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey,
883 pubkey_len) != 0)
884 goto done;
885
886 *len = secret_sz;
887 ret = 0;
888done:
889 wc_FreeDhKey(dh);
890 os_free(dh);
891 return ret;
892}
893
894
895#ifdef CONFIG_FIPS
896int crypto_get_random(void *buf, size_t len)
897{
898 int ret = 0;
899 WC_RNG rng;
900
901 if (wc_InitRng(&rng) != 0)
902 return -1;
903 if (wc_RNG_GenerateBlock(&rng, buf, len) != 0)
904 ret = -1;
905 wc_FreeRng(&rng);
906 return ret;
907}
908#endif /* CONFIG_FIPS */
909
910
911#if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
912struct crypto_hash {
913 Hmac hmac;
914 int size;
915};
916
917
918struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
919 size_t key_len)
920{
921 struct crypto_hash *ret = NULL;
922 struct crypto_hash *hash;
923 int type;
924
925 hash = os_zalloc(sizeof(*hash));
926 if (!hash)
927 goto done;
928
929 switch (alg) {
930#ifndef NO_MD5
931 case CRYPTO_HASH_ALG_HMAC_MD5:
932 hash->size = 16;
933 type = WC_MD5;
934 break;
935#endif /* NO_MD5 */
936#ifndef NO_SHA
937 case CRYPTO_HASH_ALG_HMAC_SHA1:
938 type = WC_SHA;
939 hash->size = 20;
940 break;
941#endif /* NO_SHA */
942#ifdef CONFIG_SHA256
943#ifndef NO_SHA256
944 case CRYPTO_HASH_ALG_HMAC_SHA256:
945 type = WC_SHA256;
946 hash->size = 32;
947 break;
948#endif /* NO_SHA256 */
949#endif /* CONFIG_SHA256 */
950 default:
951 goto done;
952 }
953
Sunil Ravia04bd252022-05-02 22:54:18 -0700954 if (wc_HmacInit(&hash->hmac, NULL, INVALID_DEVID) != 0 ||
955 wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0)
Roshan Pius3a1667e2018-07-03 15:17:14 -0700956 goto done;
957
958 ret = hash;
959 hash = NULL;
960done:
961 os_free(hash);
962 return ret;
963}
964
965
966void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
967{
968 if (!ctx)
969 return;
970 wc_HmacUpdate(&ctx->hmac, data, len);
971}
972
973
974int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
975{
976 int ret = 0;
977
978 if (!ctx)
979 return -2;
980
981 if (!mac || !len)
982 goto done;
983
984 if (wc_HmacFinal(&ctx->hmac, mac) != 0) {
985 ret = -1;
986 goto done;
987 }
988
989 *len = ctx->size;
990 ret = 0;
991done:
992 bin_clear_free(ctx, sizeof(*ctx));
Hai Shalom5f92bc92019-04-18 11:54:11 -0700993 if (TEST_FAIL())
994 return -1;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700995 return ret;
996}
997
998#endif
999
1000
1001int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1002 const u8 *addr[], const size_t *len, u8 *mac)
1003{
1004 Cmac cmac;
1005 size_t i;
1006 word32 sz;
1007
1008 if (TEST_FAIL())
1009 return -1;
1010
1011 if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0)
1012 return -1;
1013
1014 for (i = 0; i < num_elem; i++)
1015 if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0)
1016 return -1;
1017
1018 sz = AES_BLOCK_SIZE;
1019 if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE)
1020 return -1;
1021
1022 return 0;
1023}
1024
1025
1026int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1027 const u8 *addr[], const size_t *len, u8 *mac)
1028{
1029 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1030}
1031
1032
1033int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1034{
1035 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1036}
1037
1038
1039int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1040{
1041 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1042}
1043
1044
1045struct crypto_bignum * crypto_bignum_init(void)
1046{
1047 mp_int *a;
1048
1049 if (TEST_FAIL())
1050 return NULL;
1051
1052 a = os_malloc(sizeof(*a));
1053 if (!a || mp_init(a) != MP_OKAY) {
1054 os_free(a);
1055 a = NULL;
1056 }
1057
1058 return (struct crypto_bignum *) a;
1059}
1060
1061
1062struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1063{
1064 mp_int *a;
1065
1066 if (TEST_FAIL())
1067 return NULL;
1068
1069 a = (mp_int *) crypto_bignum_init();
1070 if (!a)
1071 return NULL;
1072
1073 if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) {
1074 os_free(a);
1075 a = NULL;
1076 }
1077
1078 return (struct crypto_bignum *) a;
1079}
1080
1081
Hai Shalomc3565922019-10-28 11:58:20 -07001082struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1083{
1084 mp_int *a;
1085
1086 if (TEST_FAIL())
1087 return NULL;
1088
1089 a = (mp_int *) crypto_bignum_init();
1090 if (!a)
1091 return NULL;
1092
1093 if (mp_set_int(a, val) != MP_OKAY) {
1094 os_free(a);
1095 a = NULL;
1096 }
1097
1098 return (struct crypto_bignum *) a;
1099}
1100
1101
Roshan Pius3a1667e2018-07-03 15:17:14 -07001102void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1103{
1104 if (!n)
1105 return;
1106
1107 if (clear)
1108 mp_forcezero((mp_int *) n);
1109 mp_clear((mp_int *) n);
1110 os_free((mp_int *) n);
1111}
1112
1113
1114int crypto_bignum_to_bin(const struct crypto_bignum *a,
1115 u8 *buf, size_t buflen, size_t padlen)
1116{
1117 int num_bytes, offset;
1118
1119 if (TEST_FAIL())
1120 return -1;
1121
1122 if (padlen > buflen)
1123 return -1;
1124
1125 num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1126 if ((size_t) num_bytes > buflen)
1127 return -1;
1128 if (padlen > (size_t) num_bytes)
1129 offset = padlen - num_bytes;
1130 else
1131 offset = 0;
1132
1133 os_memset(buf, 0, offset);
1134 mp_to_unsigned_bin((mp_int *) a, buf + offset);
1135
1136 return num_bytes + offset;
1137}
1138
1139
1140int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1141{
1142 int ret = 0;
1143 WC_RNG rng;
Hai Shalom4fbc08f2020-05-18 12:37:00 -07001144 size_t len;
1145 u8 *buf;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001146
Hai Shalom5f92bc92019-04-18 11:54:11 -07001147 if (TEST_FAIL())
1148 return -1;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001149 if (wc_InitRng(&rng) != 0)
1150 return -1;
Hai Shalom4fbc08f2020-05-18 12:37:00 -07001151 len = (mp_count_bits((mp_int *) m) + 7) / 8;
1152 buf = os_malloc(len);
1153 if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
1154 mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
Roshan Pius3a1667e2018-07-03 15:17:14 -07001155 mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1156 ret = -1;
1157 wc_FreeRng(&rng);
Hai Shalom4fbc08f2020-05-18 12:37:00 -07001158 bin_clear_free(buf, len);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001159 return ret;
1160}
1161
1162
1163int crypto_bignum_add(const struct crypto_bignum *a,
1164 const struct crypto_bignum *b,
1165 struct crypto_bignum *r)
1166{
1167 return mp_add((mp_int *) a, (mp_int *) b,
1168 (mp_int *) r) == MP_OKAY ? 0 : -1;
1169}
1170
1171
1172int crypto_bignum_mod(const struct crypto_bignum *a,
1173 const struct crypto_bignum *m,
1174 struct crypto_bignum *r)
1175{
1176 return mp_mod((mp_int *) a, (mp_int *) m,
1177 (mp_int *) r) == MP_OKAY ? 0 : -1;
1178}
1179
1180
1181int crypto_bignum_exptmod(const struct crypto_bignum *b,
1182 const struct crypto_bignum *e,
1183 const struct crypto_bignum *m,
1184 struct crypto_bignum *r)
1185{
1186 if (TEST_FAIL())
1187 return -1;
1188
1189 return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1190 (mp_int *) r) == MP_OKAY ? 0 : -1;
1191}
1192
1193
1194int crypto_bignum_inverse(const struct crypto_bignum *a,
1195 const struct crypto_bignum *m,
1196 struct crypto_bignum *r)
1197{
1198 if (TEST_FAIL())
1199 return -1;
1200
1201 return mp_invmod((mp_int *) a, (mp_int *) m,
1202 (mp_int *) r) == MP_OKAY ? 0 : -1;
1203}
1204
1205
1206int crypto_bignum_sub(const struct crypto_bignum *a,
1207 const struct crypto_bignum *b,
1208 struct crypto_bignum *r)
1209{
1210 if (TEST_FAIL())
1211 return -1;
1212
Hai Shalomc3565922019-10-28 11:58:20 -07001213 return mp_sub((mp_int *) a, (mp_int *) b,
Roshan Pius3a1667e2018-07-03 15:17:14 -07001214 (mp_int *) r) == MP_OKAY ? 0 : -1;
1215}
1216
1217
1218int crypto_bignum_div(const struct crypto_bignum *a,
1219 const struct crypto_bignum *b,
1220 struct crypto_bignum *d)
1221{
1222 if (TEST_FAIL())
1223 return -1;
1224
1225 return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1226 NULL) == MP_OKAY ? 0 : -1;
1227}
1228
1229
Hai Shalomc3565922019-10-28 11:58:20 -07001230int crypto_bignum_addmod(const struct crypto_bignum *a,
1231 const struct crypto_bignum *b,
1232 const struct crypto_bignum *c,
1233 struct crypto_bignum *d)
1234{
1235 if (TEST_FAIL())
1236 return -1;
1237
1238 return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1239 (mp_int *) d) == MP_OKAY ? 0 : -1;
1240}
1241
1242
Roshan Pius3a1667e2018-07-03 15:17:14 -07001243int crypto_bignum_mulmod(const struct crypto_bignum *a,
1244 const struct crypto_bignum *b,
1245 const struct crypto_bignum *m,
1246 struct crypto_bignum *d)
1247{
1248 if (TEST_FAIL())
1249 return -1;
1250
1251 return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1252 (mp_int *) d) == MP_OKAY ? 0 : -1;
1253}
1254
1255
Hai Shalomc3565922019-10-28 11:58:20 -07001256int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1257 const struct crypto_bignum *b,
1258 struct crypto_bignum *c)
1259{
1260 if (TEST_FAIL())
1261 return -1;
1262
1263 return mp_sqrmod((mp_int *) a, (mp_int *) b,
1264 (mp_int *) c) == MP_OKAY ? 0 : -1;
1265}
1266
1267
Roshan Pius3a1667e2018-07-03 15:17:14 -07001268int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1269 struct crypto_bignum *r)
1270{
1271 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1272 return -1;
1273 mp_rshb((mp_int *) r, n);
1274 return 0;
1275}
1276
1277
1278int crypto_bignum_cmp(const struct crypto_bignum *a,
1279 const struct crypto_bignum *b)
1280{
1281 return mp_cmp((mp_int *) a, (mp_int *) b);
1282}
1283
1284
Roshan Pius3a1667e2018-07-03 15:17:14 -07001285int crypto_bignum_is_zero(const struct crypto_bignum *a)
1286{
1287 return mp_iszero((mp_int *) a);
1288}
1289
1290
1291int crypto_bignum_is_one(const struct crypto_bignum *a)
1292{
1293 return mp_isone((const mp_int *) a);
1294}
1295
1296int crypto_bignum_is_odd(const struct crypto_bignum *a)
1297{
1298 return mp_isodd((mp_int *) a);
1299}
1300
1301
1302int crypto_bignum_legendre(const struct crypto_bignum *a,
1303 const struct crypto_bignum *p)
1304{
1305 mp_int t;
1306 int ret;
1307 int res = -2;
1308
1309 if (TEST_FAIL())
1310 return -2;
1311
1312 if (mp_init(&t) != MP_OKAY)
1313 return -2;
1314
1315 /* t = (p-1) / 2 */
1316 ret = mp_sub_d((mp_int *) p, 1, &t);
1317 if (ret == MP_OKAY)
1318 mp_rshb(&t, 1);
1319 if (ret == MP_OKAY)
1320 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1321 if (ret == MP_OKAY) {
1322 if (mp_isone(&t))
1323 res = 1;
1324 else if (mp_iszero(&t))
1325 res = 0;
1326 else
1327 res = -1;
1328 }
1329
1330 mp_clear(&t);
1331 return res;
1332}
1333
1334
1335#ifdef CONFIG_ECC
1336
1337int ecc_map(ecc_point *, mp_int *, mp_digit);
1338int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1339 mp_int *a, mp_int *modulus, mp_digit mp);
1340
1341struct crypto_ec {
1342 ecc_key key;
1343 mp_int a;
1344 mp_int prime;
1345 mp_int order;
1346 mp_digit mont_b;
1347 mp_int b;
1348};
1349
1350
1351struct crypto_ec * crypto_ec_init(int group)
1352{
1353 int built = 0;
1354 struct crypto_ec *e;
1355 int curve_id;
1356
1357 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1358 switch (group) {
1359 case 19:
1360 curve_id = ECC_SECP256R1;
1361 break;
1362 case 20:
1363 curve_id = ECC_SECP384R1;
1364 break;
1365 case 21:
1366 curve_id = ECC_SECP521R1;
1367 break;
1368 case 25:
1369 curve_id = ECC_SECP192R1;
1370 break;
1371 case 26:
1372 curve_id = ECC_SECP224R1;
1373 break;
1374#ifdef HAVE_ECC_BRAINPOOL
1375 case 27:
1376 curve_id = ECC_BRAINPOOLP224R1;
1377 break;
1378 case 28:
1379 curve_id = ECC_BRAINPOOLP256R1;
1380 break;
1381 case 29:
1382 curve_id = ECC_BRAINPOOLP384R1;
1383 break;
1384 case 30:
1385 curve_id = ECC_BRAINPOOLP512R1;
1386 break;
1387#endif /* HAVE_ECC_BRAINPOOL */
1388 default:
1389 return NULL;
1390 }
1391
1392 e = os_zalloc(sizeof(*e));
1393 if (!e)
1394 return NULL;
1395
1396 if (wc_ecc_init(&e->key) != 0 ||
1397 wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
1398 mp_init(&e->a) != MP_OKAY ||
1399 mp_init(&e->prime) != MP_OKAY ||
1400 mp_init(&e->order) != MP_OKAY ||
1401 mp_init(&e->b) != MP_OKAY ||
1402 mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY ||
1403 mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY ||
1404 mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY ||
1405 mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY ||
1406 mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY)
1407 goto done;
1408
1409 built = 1;
1410done:
1411 if (!built) {
1412 crypto_ec_deinit(e);
1413 e = NULL;
1414 }
1415 return e;
1416}
1417
1418
1419void crypto_ec_deinit(struct crypto_ec* e)
1420{
1421 if (!e)
1422 return;
1423
1424 mp_clear(&e->b);
1425 mp_clear(&e->order);
1426 mp_clear(&e->prime);
1427 mp_clear(&e->a);
1428 wc_ecc_free(&e->key);
1429 os_free(e);
1430}
1431
1432
Roshan Pius3a1667e2018-07-03 15:17:14 -07001433struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1434{
1435 if (TEST_FAIL())
1436 return NULL;
1437 if (!e)
1438 return NULL;
1439 return (struct crypto_ec_point *) wc_ecc_new_point();
1440}
1441
1442
1443size_t crypto_ec_prime_len(struct crypto_ec *e)
1444{
1445 return (mp_count_bits(&e->prime) + 7) / 8;
1446}
1447
1448
1449size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1450{
1451 return mp_count_bits(&e->prime);
1452}
1453
1454
1455size_t crypto_ec_order_len(struct crypto_ec *e)
1456{
1457 return (mp_count_bits(&e->order) + 7) / 8;
1458}
1459
1460
1461const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1462{
1463 return (const struct crypto_bignum *) &e->prime;
1464}
1465
1466
1467const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1468{
1469 return (const struct crypto_bignum *) &e->order;
1470}
1471
1472
Hai Shalomc3565922019-10-28 11:58:20 -07001473const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1474{
1475 return (const struct crypto_bignum *) &e->a;
1476}
1477
1478
1479const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1480{
1481 return (const struct crypto_bignum *) &e->b;
1482}
1483
1484
Roshan Pius3a1667e2018-07-03 15:17:14 -07001485void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1486{
1487 ecc_point *point = (ecc_point *) p;
1488
1489 if (!p)
1490 return;
1491
1492 if (clear) {
1493 mp_forcezero(point->x);
1494 mp_forcezero(point->y);
1495 mp_forcezero(point->z);
1496 }
1497 wc_ecc_del_point(point);
1498}
1499
1500
1501int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1502 struct crypto_bignum *x)
1503{
1504 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1505}
1506
1507
1508int crypto_ec_point_to_bin(struct crypto_ec *e,
1509 const struct crypto_ec_point *point, u8 *x, u8 *y)
1510{
1511 ecc_point *p = (ecc_point *) point;
1512
1513 if (TEST_FAIL())
1514 return -1;
1515
1516 if (!mp_isone(p->z)) {
1517 if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY)
1518 return -1;
1519 }
1520
1521 if (x) {
1522 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1523 e->key.dp->size,
1524 e->key.dp->size) <= 0)
1525 return -1;
1526 }
1527
1528 if (y) {
1529 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1530 e->key.dp->size,
1531 e->key.dp->size) <= 0)
1532 return -1;
1533 }
1534
1535 return 0;
1536}
1537
1538
1539struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1540 const u8 *val)
1541{
1542 ecc_point *point = NULL;
1543 int loaded = 0;
1544
1545 if (TEST_FAIL())
1546 return NULL;
1547
1548 point = wc_ecc_new_point();
1549 if (!point)
1550 goto done;
1551
1552 if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY)
1553 goto done;
1554 val += e->key.dp->size;
1555 if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY)
1556 goto done;
1557 mp_set(point->z, 1);
1558
1559 loaded = 1;
1560done:
1561 if (!loaded) {
1562 wc_ecc_del_point(point);
1563 point = NULL;
1564 }
1565 return (struct crypto_ec_point *) point;
1566}
1567
1568
1569int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1570 const struct crypto_ec_point *b,
1571 struct crypto_ec_point *c)
1572{
1573 mp_int mu;
1574 ecc_point *ta = NULL, *tb = NULL;
1575 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1576 mp_int *modulus = &e->prime;
1577 int ret;
1578
1579 if (TEST_FAIL())
1580 return -1;
1581
1582 ret = mp_init(&mu);
1583 if (ret != MP_OKAY)
1584 return -1;
1585
1586 ret = mp_montgomery_calc_normalization(&mu, modulus);
1587 if (ret != MP_OKAY) {
1588 mp_clear(&mu);
1589 return -1;
1590 }
1591
1592 if (!mp_isone(&mu)) {
1593 ta = wc_ecc_new_point();
1594 if (!ta) {
1595 mp_clear(&mu);
1596 return -1;
1597 }
1598 tb = wc_ecc_new_point();
1599 if (!tb) {
1600 wc_ecc_del_point(ta);
1601 mp_clear(&mu);
1602 return -1;
1603 }
1604
1605 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1606 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1607 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1608 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1609 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1610 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1611 ret = -1;
1612 goto end;
1613 }
1614 pa = ta;
1615 pb = tb;
1616 }
1617
1618 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1619 &e->prime, e->mont_b);
1620 if (ret != 0) {
1621 ret = -1;
1622 goto end;
1623 }
1624
1625 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1626 ret = -1;
1627 else
1628 ret = 0;
1629end:
1630 wc_ecc_del_point(tb);
1631 wc_ecc_del_point(ta);
1632 mp_clear(&mu);
1633 return ret;
1634}
1635
1636
1637int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1638 const struct crypto_bignum *b,
1639 struct crypto_ec_point *res)
1640{
1641 int ret;
1642
1643 if (TEST_FAIL())
1644 return -1;
1645
1646 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
1647 &e->a, &e->prime, 1);
1648 return ret == 0 ? 0 : -1;
1649}
1650
1651
1652int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1653{
1654 ecc_point *point = (ecc_point *) p;
1655
1656 if (TEST_FAIL())
1657 return -1;
1658
1659 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
1660 return -1;
1661
1662 return 0;
1663}
1664
1665
Roshan Pius3a1667e2018-07-03 15:17:14 -07001666struct crypto_bignum *
1667crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1668 const struct crypto_bignum *x)
1669{
Sunil Ravia04bd252022-05-02 22:54:18 -07001670 mp_int *y2;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001671
1672 if (TEST_FAIL())
1673 return NULL;
1674
Sunil Ravia04bd252022-05-02 22:54:18 -07001675 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
Roshan Pius3a1667e2018-07-03 15:17:14 -07001676 y2 = (mp_int *) crypto_bignum_init();
Sunil Ravia04bd252022-05-02 22:54:18 -07001677 if (!y2 ||
1678 mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
1679 mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
Roshan Pius3a1667e2018-07-03 15:17:14 -07001680 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
Sunil Ravia04bd252022-05-02 22:54:18 -07001681 mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
1682 mp_clear(y2);
1683 os_free(y2);
1684 y2 = NULL;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001685 }
1686
1687 return (struct crypto_bignum *) y2;
1688}
1689
1690
1691int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1692 const struct crypto_ec_point *p)
1693{
1694 return wc_ecc_point_is_at_infinity((ecc_point *) p);
1695}
1696
1697
1698int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1699 const struct crypto_ec_point *p)
1700{
1701 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
1702 MP_OKAY;
1703}
1704
1705
1706int crypto_ec_point_cmp(const struct crypto_ec *e,
1707 const struct crypto_ec_point *a,
1708 const struct crypto_ec_point *b)
1709{
1710 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
1711}
1712
1713
1714struct crypto_ecdh {
1715 struct crypto_ec *ec;
Sunil Ravia04bd252022-05-02 22:54:18 -07001716 WC_RNG rng;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001717};
1718
1719struct crypto_ecdh * crypto_ecdh_init(int group)
1720{
1721 struct crypto_ecdh *ecdh = NULL;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001722 int ret;
1723
Roshan Pius3a1667e2018-07-03 15:17:14 -07001724 ecdh = os_zalloc(sizeof(*ecdh));
1725 if (!ecdh)
1726 goto fail;
1727
Sunil Ravia04bd252022-05-02 22:54:18 -07001728 if (wc_InitRng(&ecdh->rng) != 0)
1729 goto fail;
1730
Roshan Pius3a1667e2018-07-03 15:17:14 -07001731 ecdh->ec = crypto_ec_init(group);
1732 if (!ecdh->ec)
1733 goto fail;
1734
Sunil Ravia04bd252022-05-02 22:54:18 -07001735 ret = wc_ecc_make_key_ex(&ecdh->rng, ecdh->ec->key.dp->size,
1736 &ecdh->ec->key, ecdh->ec->key.dp->id);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001737 if (ret < 0)
1738 goto fail;
1739
Sunil Ravia04bd252022-05-02 22:54:18 -07001740#if defined(ECC_TIMING_RESISTANT) && !defined(CONFIG_FIPS)
1741 ret = wc_ecc_set_rng(&ecdh->ec->key, &ecdh->rng);
1742 if (ret < 0)
1743 goto fail;
1744#endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
Roshan Pius3a1667e2018-07-03 15:17:14 -07001745
Sunil Ravia04bd252022-05-02 22:54:18 -07001746done:
Roshan Pius3a1667e2018-07-03 15:17:14 -07001747 return ecdh;
1748fail:
1749 crypto_ecdh_deinit(ecdh);
1750 ecdh = NULL;
1751 goto done;
1752}
1753
1754
1755void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1756{
1757 if (ecdh) {
1758 crypto_ec_deinit(ecdh->ec);
Sunil Ravia04bd252022-05-02 22:54:18 -07001759 wc_FreeRng(&ecdh->rng);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001760 os_free(ecdh);
1761 }
1762}
1763
1764
1765struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1766{
1767 struct wpabuf *buf = NULL;
1768 int ret;
1769 int len = ecdh->ec->key.dp->size;
1770
1771 buf = wpabuf_alloc(inc_y ? 2 * len : len);
1772 if (!buf)
1773 goto fail;
1774
1775 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1776 ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
1777 len, len);
1778 if (ret < 0)
1779 goto fail;
1780 if (inc_y) {
1781 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1782 ecdh->ec->key.pubkey.y,
1783 wpabuf_put(buf, len), len, len);
1784 if (ret < 0)
1785 goto fail;
1786 }
1787
1788done:
1789 return buf;
1790fail:
1791 wpabuf_free(buf);
1792 buf = NULL;
1793 goto done;
1794}
1795
1796
1797struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1798 const u8 *key, size_t len)
1799{
1800 int ret;
1801 struct wpabuf *pubkey = NULL;
1802 struct wpabuf *secret = NULL;
1803 word32 key_len = ecdh->ec->key.dp->size;
1804 ecc_point *point = NULL;
1805 size_t need_key_len = inc_y ? 2 * key_len : key_len;
1806
1807 if (len < need_key_len)
1808 goto fail;
1809 pubkey = wpabuf_alloc(1 + 2 * key_len);
1810 if (!pubkey)
1811 goto fail;
1812 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
1813 wpabuf_put_data(pubkey, key, need_key_len);
1814
1815 point = wc_ecc_new_point();
1816 if (!point)
1817 goto fail;
1818
1819 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
1820 ecdh->ec->key.idx, point);
1821 if (ret != MP_OKAY)
1822 goto fail;
1823
1824 secret = wpabuf_alloc(key_len);
1825 if (!secret)
1826 goto fail;
1827
1828 ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
1829 wpabuf_put(secret, key_len), &key_len);
1830 if (ret != MP_OKAY)
1831 goto fail;
1832
1833done:
1834 wc_ecc_del_point(point);
1835 wpabuf_free(pubkey);
1836 return secret;
1837fail:
1838 wpabuf_free(secret);
1839 secret = NULL;
1840 goto done;
1841}
1842
Hai Shalomfdcde762020-04-02 11:19:20 -07001843
1844size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
1845{
1846 return crypto_ec_prime_len(ecdh->ec);
1847}
1848
Sunil Ravia04bd252022-05-02 22:54:18 -07001849
1850struct crypto_ec_key {
1851 ecc_key *eckey;
1852 WC_RNG *rng; /* Needs to be initialized before use.
1853 * *NOT* initialized in crypto_ec_key_init */
1854};
1855
1856
1857static struct crypto_ec_key * crypto_ec_key_init(void)
1858{
1859 struct crypto_ec_key *key;
1860
1861 key = os_zalloc(sizeof(struct crypto_ec_key));
1862 if (key) {
1863#ifdef CONFIG_FIPS
1864 key->eckey = os_zalloc(sizeof(ecc_key));
1865#else /* CONFIG_FIPS */
1866 key->eckey = wc_ecc_key_new(NULL);
1867#endif /* CONFIG_FIPS */
1868 /* Omit key->rng initialization because it seeds itself and thus
1869 * consumes entropy that may never be used. Lazy initialize when
1870 * necessary. */
1871 if (!key->eckey) {
1872 wpa_printf(MSG_ERROR,
1873 "wolfSSL: crypto_ec_key_init() failed");
1874 crypto_ec_key_deinit(key);
1875 key = NULL;
1876 }
1877#ifdef CONFIG_FIPS
1878 else if (wc_ecc_init_ex(key->eckey, NULL, INVALID_DEVID) != 0) {
1879 wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_init_ex failed");
1880 crypto_ec_key_deinit(key);
1881 key = NULL;
1882 }
1883#endif /* CONFIG_FIPS */
1884 }
1885 return key;
1886}
1887
1888
1889void crypto_ec_key_deinit(struct crypto_ec_key *key)
1890{
1891 if (key) {
1892#ifdef CONFIG_FIPS
1893 os_free(key->rng);
1894 os_free(key->eckey);
1895#else /* CONFIG_FIPS */
1896 wc_rng_free(key->rng);
1897 wc_ecc_key_free(key->eckey);
1898#endif /* CONFIG_FIPS */
1899 os_free(key);
1900 }
1901}
1902
1903
1904struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
1905{
1906 struct crypto_ec_key *ret;
1907 word32 idx = 0;
1908
1909 ret = crypto_ec_key_init();
1910 if (!ret) {
1911 wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed");
1912 goto fail;
1913 }
1914
1915 if (wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len) !=
1916 0) {
1917 wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPrivateKeyDecode failed");
1918 goto fail;
1919 }
1920
1921 return ret;
1922fail:
1923 if (ret)
1924 crypto_ec_key_deinit(ret);
1925 return NULL;
1926}
1927
1928
1929int crypto_ec_key_group(struct crypto_ec_key *key)
1930{
1931
1932 if (!key || !key->eckey || !key->eckey->dp) {
1933 wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
1934 __func__);
1935 return -1;
1936 }
1937
1938 switch (key->eckey->dp->id) {
1939 case ECC_SECP256R1:
1940 return 19;
1941 case ECC_SECP384R1:
1942 return 20;
1943 case ECC_SECP521R1:
1944 return 21;
1945 case ECC_BRAINPOOLP256R1:
1946 return 28;
1947 case ECC_BRAINPOOLP384R1:
1948 return 29;
1949 case ECC_BRAINPOOLP512R1:
1950 return 30;
1951 }
1952
1953 wpa_printf(MSG_ERROR, "wolfSSL: Unsupported curve (id=%d) in EC key",
1954 key->eckey->dp->id);
1955 return -1;
1956}
1957
1958
1959struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
1960{
1961 byte *der = NULL;
1962 int der_len;
1963 struct wpabuf *ret = NULL;
1964
1965 if (!key || !key->eckey) {
1966 wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
1967 __func__);
1968 goto fail;
1969 }
1970
1971 der_len = wc_EccPublicKeyDerSize(key->eckey, 1);
1972 if (der_len <= 0) {
1973 wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDerSize failed");
1974 goto fail;
1975 }
1976
1977 der = os_malloc(der_len);
1978 if (!der)
1979 goto fail;
1980
1981 der_len = wc_EccPublicKeyToDer(key->eckey, der, der_len, 1);
1982 if (der_len <= 0) {
1983 wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyToDer failed");
1984 goto fail;
1985 }
1986
1987 ret = wpabuf_alloc_copy(der, der_len);
1988 os_free(der);
1989 return ret;
1990
1991fail:
1992 os_free(der);
1993 return NULL;
1994}
1995
1996
1997struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
1998{
1999 word32 idx = 0;
2000 struct crypto_ec_key *ret = NULL;
2001
2002 ret = crypto_ec_key_init();
2003 if (!ret) {
2004 wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed");
2005 goto fail;
2006 }
2007
2008 if (wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len) != 0)
2009 {
2010 wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDecode failed");
2011 goto fail;
2012 }
2013
2014 return ret;
2015fail:
2016 crypto_ec_key_deinit(ret);
2017 return NULL;
2018}
2019
2020
2021struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2022 size_t len)
2023{
2024 byte *der = NULL;
2025 int der_len;
2026 word32 w32_der_len;
2027 struct wpabuf *ret = NULL;
2028
2029 if (!key || !key->eckey || !data || len == 0) {
2030 wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
2031 __func__);
2032 goto fail;
2033 }
2034
2035 if (!key->rng) {
2036 /* Lazy init key->rng */
2037#ifdef CONFIG_FIPS
2038 key->rng = os_zalloc(sizeof(WC_RNG));
2039#else /* CONFIG_FIPS */
2040 key->rng = wc_rng_new(NULL, 0, NULL);
2041#endif /* CONFIG_FIPS */
2042 if (!key->rng) {
2043 wpa_printf(MSG_ERROR, "wolfSSL: wc_rng_new failed");
2044 goto fail;
2045 }
2046#ifdef CONFIG_FIPS
2047 if (wc_InitRng(key->rng) != 0) {
2048 wpa_printf(MSG_ERROR, "wolfSSL: wc_InitRng failed");
2049 goto fail;
2050 }
2051#endif /* CONFIG_FIPS */
2052 }
2053
2054 der_len = wc_ecc_sig_size(key->eckey);
2055 if (der_len <= 0) {
2056 wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sig_size failed");
2057 goto fail;
2058 }
2059
2060 der = os_malloc(der_len);
2061 if (!der)
2062 goto fail;
2063
2064 w32_der_len = (word32) der_len;
2065 if (wc_ecc_sign_hash(data, len, der, &w32_der_len, key->rng, key->eckey)
2066 != 0) {
2067 wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sign_hash failed");
2068 goto fail;
2069 }
2070
2071 ret = wpabuf_alloc_copy(der, der_len);
2072 os_free(der);
2073 if (!ret)
2074 wpa_printf(MSG_ERROR, "wolfSSL: wpabuf_alloc_copy failed");
2075 return ret;
2076fail:
2077 os_free(der);
2078 return NULL;
2079}
2080
2081
2082int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2083 size_t len, const u8 *sig, size_t sig_len)
2084{
2085 int res = 0;
2086
2087 if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2088 wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
2089 __func__);
2090 return -1;
2091 }
2092
2093 if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2094 {
2095 wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_verify_hash failed");
2096 return -1;
2097 }
2098
2099 if (res != 1)
2100 wpa_printf(MSG_DEBUG,
2101 "wolfSSL: crypto_ec_key_verify_signature failed");
2102
2103 return res;
2104}
2105
Roshan Pius3a1667e2018-07-03 15:17:14 -07002106#endif /* CONFIG_ECC */
Sunil Ravia04bd252022-05-02 22:54:18 -07002107
2108
2109void crypto_unload(void)
2110{
2111}