Coverage Report

Created: 2022-08-24 06:25

/src/wolfssl-openssl-api/wolfcrypt/src/ecc.c
Line
Count
Source (jump to first uncovered line)
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2022 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
23
24
#ifdef HAVE_CONFIG_H
25
    #include <config.h>
26
#endif
27
28
/* in case user set HAVE_ECC there */
29
#include <wolfssl/wolfcrypt/settings.h>
30
31
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
32
#undef WOLFSSL_SMALL_STACK
33
#undef WOLFSSL_SMALL_STACK_CACHE
34
#endif
35
36
/*
37
Possible ECC enable options:
38
 * HAVE_ECC:            Overall control of ECC                  default: on
39
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
40
 * HAVE_ECC_SIGN:       ECC sign                                default: on
41
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
42
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
43
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
44
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
45
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
46
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
47
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
48
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
49
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
50
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
51
 *                        Includes the curve "a" variable in calculation
52
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
53
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
54
 *                                                              default: off
55
 * FP_ECC:              ECC Fixed Point Cache                   default: off
56
 *                      FP cache is not supported for SECP160R1, SECP160R2,
57
 *                      SECP160K1 and SECP224K1. These do not work with scalars
58
 *                      that are the length of the order when the order is
59
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
60
 * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
61
 *                      (on for HAVE_COMP_KEY)
62
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
63
 *                      For the ECC curve parameters `ecc_set_type` use fixed
64
 *                      array for hex string
65
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
66
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
67
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
68
 *                      normal blocking API's
69
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
70
 *                      signing. If the value is invalid, a new random 'k' is
71
 *                      generated in the loop. (For testing)
72
 *                                                              default: off
73
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
74
 *                      Enables the setting of the 'k' value to use during ECDSA
75
 *                      signing. If the value is invalid then an error is
76
 *                      returned rather than generating a new 'k'. (For testing)
77
 *                                                              default: off
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
79
 *                      deterministic ECC signatures. The following function
80
 *                      can be used to set the deterministic signing flag in the
81
 *                      ecc key structure.
82
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
83
 *                                                              default: off
84
 *
85
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
86
 *                      hash directly instead of doing bits2octets(H(m)), when
87
 *                      the variant macro is used the bits2octets operation on
88
 *                      the hash is removed.
89
 *                                                              default: off
90
 *
91
 * WC_PROTECT_ENCRYPTED_MEM:
92
 *                      Enables implementations that protect data that is in
93
 *                      encrypted memory.
94
 *                                                              default: off
95
 */
96
97
/*
98
ECC Curve Types:
99
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
100
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
101
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
102
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
103
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
104
 */
105
106
/*
107
ECC Curve Sizes:
108
 * ECC_USER_CURVES: Allows custom combination of key sizes below
109
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
110
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
111
 * HAVE_ECC112: 112 bit key
112
 * HAVE_ECC128: 128 bit key
113
 * HAVE_ECC160: 160 bit key
114
 * HAVE_ECC192: 192 bit key
115
 * HAVE_ECC224: 224 bit key
116
 * HAVE_ECC239: 239 bit key
117
 * NO_ECC256: Disables 256 bit key (on by default)
118
 * HAVE_ECC320: 320 bit key
119
 * HAVE_ECC384: 384 bit key
120
 * HAVE_ECC512: 512 bit key
121
 * HAVE_ECC521: 521 bit key
122
 */
123
124
125
#ifdef HAVE_ECC
126
127
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
128
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
129
    !defined(WOLFSSL_CUSTOM_CURVES)
130
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
131
#endif
132
133
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
134
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
135
    #define FIPS_NO_WRAPPERS
136
137
    #ifdef USE_WINDOWS_API
138
        #pragma code_seg(".fipsA$f")
139
        #pragma const_seg(".fipsB$f")
140
    #endif
141
#endif
142
143
/* public ASN interface */
144
#include <wolfssl/wolfcrypt/asn_public.h>
145
146
#include <wolfssl/wolfcrypt/ecc.h>
147
#include <wolfssl/wolfcrypt/asn.h>
148
#include <wolfssl/wolfcrypt/error-crypt.h>
149
#include <wolfssl/wolfcrypt/logging.h>
150
#include <wolfssl/wolfcrypt/types.h>
151
152
#ifdef WOLFSSL_HAVE_SP_ECC
153
#include <wolfssl/wolfcrypt/sp.h>
154
#endif
155
156
#ifdef HAVE_ECC_ENCRYPT
157
    #include <wolfssl/wolfcrypt/kdf.h>
158
    #include <wolfssl/wolfcrypt/aes.h>
159
#endif
160
161
#ifdef HAVE_X963_KDF
162
    #include <wolfssl/wolfcrypt/hash.h>
163
#endif
164
165
#ifdef WOLF_CRYPTO_CB
166
    #include <wolfssl/wolfcrypt/cryptocb.h>
167
#endif
168
169
#ifdef NO_INLINE
170
    #include <wolfssl/wolfcrypt/misc.h>
171
#else
172
    #define WOLFSSL_MISC_INCLUDED
173
    #include <wolfcrypt/src/misc.c>
174
#endif
175
176
#if defined(FREESCALE_LTC_ECC)
177
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
178
#endif
179
180
#if defined(WOLFSSL_STM32_PKA)
181
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
182
#endif
183
184
#if defined(WOLFSSL_PSOC6_CRYPTO)
185
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
186
#endif
187
188
#if defined(WOLFSSL_CAAM)
189
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
190
#endif
191
192
#if defined(WOLFSSL_KCAPI_ECC)
193
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
194
#endif
195
196
#ifdef WOLFSSL_SE050
197
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
198
#endif
199
200
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
201
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
202
    #include <wolfssl/wolfcrypt/hmac.h>
203
#endif
204
205
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
206
0
    #define GEN_MEM_ERR MP_MEM
207
#elif defined(USE_FAST_MATH)
208
    #define GEN_MEM_ERR FP_MEM
209
#else
210
    #define GEN_MEM_ERR MP_MEM
211
#endif
212
213
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
214
    !defined(WOLFSSL_SILABS_SE_ACCEL) && !defined(WOLFSSL_KCAPI_ECC) && \
215
    !defined(WOLFSSL_CRYPTOCELL) && !defined(NO_ECC_MAKE_PUB) && \
216
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
217
    #undef  HAVE_ECC_MAKE_PUB
218
    #define HAVE_ECC_MAKE_PUB
219
#endif
220
221
/* forward declarations */
222
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
223
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
224
225
/* internal ECC states */
226
enum {
227
    ECC_STATE_NONE = 0,
228
229
    ECC_STATE_SHARED_SEC_GEN,
230
    ECC_STATE_SHARED_SEC_RES,
231
232
    ECC_STATE_SIGN_DO,
233
    ECC_STATE_SIGN_ENCODE,
234
235
    ECC_STATE_VERIFY_DECODE,
236
    ECC_STATE_VERIFY_DO,
237
    ECC_STATE_VERIFY_RES,
238
};
239
240
241
/* map
242
   ptmul -> mulmod
243
*/
244
245
/* 256-bit curve on by default whether user curves or not */
246
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
247
    #define ECC112
248
#endif
249
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
250
    #define ECC128
251
#endif
252
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
253
    #define ECC160
254
#endif
255
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
256
    #define ECC192
257
#endif
258
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
259
    #define ECC224
260
#endif
261
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
262
    #define ECC239
263
#endif
264
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
265
    #define ECC256
266
#endif
267
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
268
    #define ECC320
269
#endif
270
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
271
    #define ECC384
272
#endif
273
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
274
    #define ECC512
275
#endif
276
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
277
    #define ECC521
278
#endif
279
280
/* The encoded OID's for ECC curves */
281
#ifdef ECC112
282
    #ifndef NO_ECC_SECP
283
        #ifdef HAVE_OID_ENCODING
284
            #define CODED_SECP112R1    {1,3,132,0,6}
285
            #define CODED_SECP112R1_SZ 5
286
        #else
287
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
288
            #define CODED_SECP112R1_SZ 5
289
        #endif
290
        #ifndef WOLFSSL_ECC_CURVE_STATIC
291
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
292
        #else
293
            #define ecc_oid_secp112r1 CODED_SECP112R1
294
        #endif
295
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
296
    #endif /* !NO_ECC_SECP */
297
    #ifdef HAVE_ECC_SECPR2
298
        #ifdef HAVE_OID_ENCODING
299
            #define CODED_SECP112R2    {1,3,132,0,7}
300
            #define CODED_SECP112R2_SZ 5
301
        #else
302
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
303
            #define CODED_SECP112R2_SZ 5
304
        #endif
305
        #ifndef WOLFSSL_ECC_CURVE_STATIC
306
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
307
        #else
308
            #define ecc_oid_secp112r2 CODED_SECP112R2
309
        #endif
310
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
311
    #endif /* HAVE_ECC_SECPR2 */
312
#endif /* ECC112 */
313
#ifdef ECC128
314
    #ifndef NO_ECC_SECP
315
        #ifdef HAVE_OID_ENCODING
316
            #define CODED_SECP128R1    {1,3,132,0,28}
317
            #define CODED_SECP128R1_SZ 5
318
        #else
319
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
320
            #define CODED_SECP128R1_SZ 5
321
        #endif
322
        #ifndef WOLFSSL_ECC_CURVE_STATIC
323
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
324
        #else
325
            #define ecc_oid_secp128r1 CODED_SECP128R1
326
        #endif
327
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
328
    #endif /* !NO_ECC_SECP */
329
    #ifdef HAVE_ECC_SECPR2
330
        #ifdef HAVE_OID_ENCODING
331
            #define CODED_SECP128R2    {1,3,132,0,29}
332
            #define CODED_SECP128R2_SZ 5
333
        #else
334
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
335
            #define CODED_SECP128R2_SZ 5
336
        #endif
337
        #ifndef WOLFSSL_ECC_CURVE_STATIC
338
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
339
        #else
340
            #define ecc_oid_secp128r2 CODED_SECP128R2
341
        #endif
342
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
343
    #endif /* HAVE_ECC_SECPR2 */
344
#endif /* ECC128 */
345
#ifdef ECC160
346
#ifndef FP_ECC
347
    #ifndef NO_ECC_SECP
348
        #ifdef HAVE_OID_ENCODING
349
            #define CODED_SECP160R1    {1,3,132,0,8}
350
            #define CODED_SECP160R1_SZ 5
351
        #else
352
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
353
            #define CODED_SECP160R1_SZ 5
354
        #endif
355
        #ifndef WOLFSSL_ECC_CURVE_STATIC
356
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
357
        #else
358
            #define ecc_oid_secp160r1 CODED_SECP160R1
359
        #endif
360
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
361
    #endif /* !NO_ECC_SECP */
362
    #ifdef HAVE_ECC_SECPR2
363
        #ifdef HAVE_OID_ENCODING
364
            #define CODED_SECP160R2    {1,3,132,0,30}
365
            #define CODED_SECP160R2_SZ 5
366
        #else
367
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
368
            #define CODED_SECP160R2_SZ 5
369
        #endif
370
        #ifndef WOLFSSL_ECC_CURVE_STATIC
371
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
372
        #else
373
            #define ecc_oid_secp160r2 CODED_SECP160R2
374
        #endif
375
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
376
    #endif /* HAVE_ECC_SECPR2 */
377
    #ifdef HAVE_ECC_KOBLITZ
378
        #ifdef HAVE_OID_ENCODING
379
            #define CODED_SECP160K1    {1,3,132,0,9}
380
            #define CODED_SECP160K1_SZ 5
381
        #else
382
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
383
            #define CODED_SECP160K1_SZ 5
384
        #endif
385
        #ifndef WOLFSSL_ECC_CURVE_STATIC
386
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
387
        #else
388
            #define ecc_oid_secp160k1 CODED_SECP160K1
389
        #endif
390
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
391
    #endif /* HAVE_ECC_KOBLITZ */
392
#endif /* !FP_ECC */
393
    #ifdef HAVE_ECC_BRAINPOOL
394
        #ifdef HAVE_OID_ENCODING
395
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
396
            #define CODED_BRAINPOOLP160R1_SZ 10
397
        #else
398
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
399
            #define CODED_BRAINPOOLP160R1_SZ 9
400
        #endif
401
        #ifndef WOLFSSL_ECC_CURVE_STATIC
402
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
403
        #else
404
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
405
        #endif
406
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
407
    #endif /* HAVE_ECC_BRAINPOOL */
408
#endif /* ECC160 */
409
#ifdef ECC192
410
    #ifndef NO_ECC_SECP
411
        #ifdef HAVE_OID_ENCODING
412
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
413
            #define CODED_SECP192R1_SZ 7
414
        #else
415
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
416
            #define CODED_SECP192R1_SZ 8
417
        #endif
418
        #ifndef WOLFSSL_ECC_CURVE_STATIC
419
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
420
        #else
421
            #define ecc_oid_secp192r1 CODED_SECP192R1
422
        #endif
423
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
424
    #endif /* !NO_ECC_SECP */
425
    #ifdef HAVE_ECC_SECPR2
426
        #ifdef HAVE_OID_ENCODING
427
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
428
            #define CODED_PRIME192V2_SZ 7
429
        #else
430
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
431
            #define CODED_PRIME192V2_SZ 8
432
        #endif
433
        #ifndef WOLFSSL_ECC_CURVE_STATIC
434
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
435
        #else
436
            #define ecc_oid_prime192v2 CODED_PRIME192V2
437
        #endif
438
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
439
    #endif /* HAVE_ECC_SECPR2 */
440
    #ifdef HAVE_ECC_SECPR3
441
        #ifdef HAVE_OID_ENCODING
442
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
443
            #define CODED_PRIME192V3_SZ 7
444
        #else
445
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
446
            #define CODED_PRIME192V3_SZ 8
447
        #endif
448
        #ifndef WOLFSSL_ECC_CURVE_STATIC
449
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
450
        #else
451
            #define ecc_oid_prime192v3 CODED_PRIME192V3
452
        #endif
453
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
454
    #endif /* HAVE_ECC_SECPR3 */
455
    #ifdef HAVE_ECC_KOBLITZ
456
        #ifdef HAVE_OID_ENCODING
457
            #define CODED_SECP192K1    {1,3,132,0,31}
458
            #define CODED_SECP192K1_SZ 5
459
        #else
460
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
461
            #define CODED_SECP192K1_SZ 5
462
        #endif
463
        #ifndef WOLFSSL_ECC_CURVE_STATIC
464
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
465
        #else
466
            #define ecc_oid_secp192k1 CODED_SECP192K1
467
        #endif
468
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
469
    #endif /* HAVE_ECC_KOBLITZ */
470
    #ifdef HAVE_ECC_BRAINPOOL
471
        #ifdef HAVE_OID_ENCODING
472
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
473
            #define CODED_BRAINPOOLP192R1_SZ 10
474
        #else
475
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
476
            #define CODED_BRAINPOOLP192R1_SZ 9
477
        #endif
478
        #ifndef WOLFSSL_ECC_CURVE_STATIC
479
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
480
        #else
481
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
482
        #endif
483
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
484
    #endif /* HAVE_ECC_BRAINPOOL */
485
#endif /* ECC192 */
486
#ifdef ECC224
487
    #ifndef NO_ECC_SECP
488
        #ifdef HAVE_OID_ENCODING
489
            #define CODED_SECP224R1    {1,3,132,0,33}
490
            #define CODED_SECP224R1_SZ 5
491
        #else
492
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
493
            #define CODED_SECP224R1_SZ 5
494
        #endif
495
        #ifndef WOLFSSL_ECC_CURVE_STATIC
496
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
497
        #else
498
            #define ecc_oid_secp224r1 CODED_SECP224R1
499
        #endif
500
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
501
    #endif /* !NO_ECC_SECP */
502
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
503
        #ifdef HAVE_OID_ENCODING
504
            #define CODED_SECP224K1    {1,3,132,0,32}
505
            #define CODED_SECP224K1_SZ 5
506
        #else
507
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
508
            #define CODED_SECP224K1_SZ 5
509
        #endif
510
        #ifndef WOLFSSL_ECC_CURVE_STATIC
511
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
512
        #else
513
            #define ecc_oid_secp224k1 CODED_SECP224K1
514
        #endif
515
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
516
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
517
    #ifdef HAVE_ECC_BRAINPOOL
518
        #ifdef HAVE_OID_ENCODING
519
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
520
            #define CODED_BRAINPOOLP224R1_SZ 10
521
        #else
522
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
523
            #define CODED_BRAINPOOLP224R1_SZ 9
524
        #endif
525
        #ifndef WOLFSSL_ECC_CURVE_STATIC
526
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
527
        #else
528
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
529
        #endif
530
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
531
    #endif /* HAVE_ECC_BRAINPOOL */
532
#endif /* ECC224 */
533
#ifdef ECC239
534
    #ifndef NO_ECC_SECP
535
        #ifdef HAVE_OID_ENCODING
536
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
537
            #define CODED_PRIME239V1_SZ 7
538
        #else
539
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
540
            #define CODED_PRIME239V1_SZ 8
541
        #endif
542
        #ifndef WOLFSSL_ECC_CURVE_STATIC
543
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
544
        #else
545
            #define ecc_oid_prime239v1 CODED_PRIME239V1
546
        #endif
547
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
548
    #endif /* !NO_ECC_SECP */
549
    #ifdef HAVE_ECC_SECPR2
550
        #ifdef HAVE_OID_ENCODING
551
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
552
            #define CODED_PRIME239V2_SZ 7
553
        #else
554
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
555
            #define CODED_PRIME239V2_SZ 8
556
        #endif
557
        #ifndef WOLFSSL_ECC_CURVE_STATIC
558
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
559
        #else
560
            #define ecc_oid_prime239v2 CODED_PRIME239V2
561
        #endif
562
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
563
    #endif /* HAVE_ECC_SECPR2 */
564
    #ifdef HAVE_ECC_SECPR3
565
        #ifdef HAVE_OID_ENCODING
566
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
567
            #define CODED_PRIME239V3_SZ 7
568
        #else
569
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
570
            #define CODED_PRIME239V3_SZ 8
571
        #endif
572
        #ifndef WOLFSSL_ECC_CURVE_STATIC
573
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
574
        #else
575
            #define ecc_oid_prime239v3 CODED_PRIME239V3
576
        #endif
577
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
578
    #endif /* HAVE_ECC_SECPR3 */
579
#endif /* ECC239 */
580
#ifdef ECC256
581
    #ifndef NO_ECC_SECP
582
        #ifdef HAVE_OID_ENCODING
583
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
584
            #define CODED_SECP256R1_SZ 7
585
        #else
586
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
587
            #define CODED_SECP256R1_SZ 8
588
        #endif
589
        #ifndef WOLFSSL_ECC_CURVE_STATIC
590
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
591
        #else
592
            #define ecc_oid_secp256r1 CODED_SECP256R1
593
        #endif
594
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
595
    #endif /* !NO_ECC_SECP */
596
    #ifdef HAVE_ECC_KOBLITZ
597
        #ifdef HAVE_OID_ENCODING
598
            #define CODED_SECP256K1    {1,3,132,0,10}
599
            #define CODED_SECP256K1_SZ 5
600
        #else
601
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
602
            #define CODED_SECP256K1_SZ 5
603
        #endif
604
        #ifndef WOLFSSL_ECC_CURVE_STATIC
605
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
606
        #else
607
            #define ecc_oid_secp256k1 CODED_SECP256K1
608
        #endif
609
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
610
    #endif /* HAVE_ECC_KOBLITZ */
611
    #ifdef HAVE_ECC_BRAINPOOL
612
        #ifdef HAVE_OID_ENCODING
613
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
614
            #define CODED_BRAINPOOLP256R1_SZ 10
615
        #else
616
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
617
            #define CODED_BRAINPOOLP256R1_SZ 9
618
        #endif
619
        #ifndef WOLFSSL_ECC_CURVE_STATIC
620
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
621
        #else
622
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
623
        #endif
624
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
625
    #endif /* HAVE_ECC_BRAINPOOL */
626
#endif /* ECC256 */
627
#ifdef ECC320
628
    #ifdef HAVE_ECC_BRAINPOOL
629
        #ifdef HAVE_OID_ENCODING
630
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
631
            #define CODED_BRAINPOOLP320R1_SZ 10
632
        #else
633
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
634
            #define CODED_BRAINPOOLP320R1_SZ 9
635
        #endif
636
        #ifndef WOLFSSL_ECC_CURVE_STATIC
637
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
638
        #else
639
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
640
        #endif
641
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
642
    #endif /* HAVE_ECC_BRAINPOOL */
643
#endif /* ECC320 */
644
#ifdef ECC384
645
    #ifndef NO_ECC_SECP
646
        #ifdef HAVE_OID_ENCODING
647
            #define CODED_SECP384R1    {1,3,132,0,34}
648
            #define CODED_SECP384R1_SZ 5
649
        #else
650
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
651
            #define CODED_SECP384R1_SZ 5
652
        #endif
653
        #ifndef WOLFSSL_ECC_CURVE_STATIC
654
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
655
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
656
        #else
657
            #define ecc_oid_secp384r1 CODED_SECP384R1
658
        #endif
659
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
660
    #endif /* !NO_ECC_SECP */
661
    #ifdef HAVE_ECC_BRAINPOOL
662
        #ifdef HAVE_OID_ENCODING
663
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
664
            #define CODED_BRAINPOOLP384R1_SZ 10
665
        #else
666
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
667
            #define CODED_BRAINPOOLP384R1_SZ 9
668
        #endif
669
        #ifndef WOLFSSL_ECC_CURVE_STATIC
670
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
671
        #else
672
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
673
        #endif
674
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
675
    #endif /* HAVE_ECC_BRAINPOOL */
676
#endif /* ECC384 */
677
#ifdef ECC512
678
    #ifdef HAVE_ECC_BRAINPOOL
679
        #ifdef HAVE_OID_ENCODING
680
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
681
            #define CODED_BRAINPOOLP512R1_SZ 10
682
        #else
683
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
684
            #define CODED_BRAINPOOLP512R1_SZ 9
685
        #endif
686
        #ifndef WOLFSSL_ECC_CURVE_STATIC
687
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
688
        #else
689
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
690
        #endif
691
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
692
    #endif /* HAVE_ECC_BRAINPOOL */
693
#endif /* ECC512 */
694
#ifdef ECC521
695
    #ifndef NO_ECC_SECP
696
        #ifdef HAVE_OID_ENCODING
697
            #define CODED_SECP521R1     {1,3,132,0,35}
698
            #define CODED_SECP521R1_SZ 5
699
        #else
700
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
701
            #define CODED_SECP521R1_SZ 5
702
        #endif
703
        #ifndef WOLFSSL_ECC_CURVE_STATIC
704
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
705
        #else
706
            #define ecc_oid_secp521r1 CODED_SECP521R1
707
        #endif
708
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
709
    #endif /* !NO_ECC_SECP */
710
#endif /* ECC521 */
711
712
713
/* This holds the key settings.
714
   ***MUST*** be organized by size from smallest to largest. */
715
716
const ecc_set_type ecc_sets[] = {
717
#ifdef ECC112
718
    #ifndef NO_ECC_SECP
719
    {
720
        14,                             /* size/bytes */
721
        ECC_SECP112R1,                  /* ID         */
722
        "SECP112R1",                    /* curve name */
723
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
724
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
725
        "659EF8BA043916EEDE8911702B22", /* B          */
726
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
727
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
728
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
729
        ecc_oid_secp112r1,              /* oid/oidSz  */
730
        ecc_oid_secp112r1_sz,
731
        ECC_SECP112R1_OID,              /* oid sum    */
732
        1,                              /* cofactor   */
733
    },
734
    #endif /* !NO_ECC_SECP */
735
    #ifdef HAVE_ECC_SECPR2
736
    {
737
        14,                             /* size/bytes */
738
        ECC_SECP112R2,                  /* ID         */
739
        "SECP112R2",                    /* curve name */
740
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
741
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
742
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
743
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
744
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
745
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
746
        ecc_oid_secp112r2,              /* oid/oidSz  */
747
        ecc_oid_secp112r2_sz,
748
        ECC_SECP112R2_OID,              /* oid sum    */
749
        4,                              /* cofactor   */
750
    },
751
    #endif /* HAVE_ECC_SECPR2 */
752
#endif /* ECC112 */
753
#ifdef ECC128
754
    #ifndef NO_ECC_SECP
755
    {
756
        16,                                 /* size/bytes */
757
        ECC_SECP128R1,                      /* ID         */
758
        "SECP128R1",                        /* curve name */
759
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
760
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
761
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
762
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
763
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
764
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
765
        ecc_oid_secp128r1,                  /* oid/oidSz  */
766
        ecc_oid_secp128r1_sz,
767
        ECC_SECP128R1_OID,                  /* oid sum    */
768
        1,                                  /* cofactor   */
769
    },
770
    #endif /* !NO_ECC_SECP */
771
    #ifdef HAVE_ECC_SECPR2
772
    {
773
        16,                                 /* size/bytes */
774
        ECC_SECP128R2,                      /* ID         */
775
        "SECP128R2",                        /* curve name */
776
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
777
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
778
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
779
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
780
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
781
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
782
        ecc_oid_secp128r2,                  /* oid/oidSz  */
783
        ecc_oid_secp128r2_sz,
784
        ECC_SECP128R2_OID,                  /* oid sum    */
785
        4,                                  /* cofactor   */
786
    },
787
    #endif /* HAVE_ECC_SECPR2 */
788
#endif /* ECC128 */
789
#ifdef ECC160
790
#ifndef FP_ECC
791
    #ifndef NO_ECC_SECP
792
    {
793
        20,                                         /* size/bytes */
794
        ECC_SECP160R1,                              /* ID         */
795
        "SECP160R1",                                /* curve name */
796
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
797
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
798
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
799
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
800
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
801
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
802
        ecc_oid_secp160r1,                          /* oid/oidSz  */
803
        ecc_oid_secp160r1_sz,
804
        ECC_SECP160R1_OID,                          /* oid sum    */
805
        1,                                          /* cofactor   */
806
    },
807
    #endif /* !NO_ECC_SECP */
808
    #ifdef HAVE_ECC_SECPR2
809
    {
810
        20,                                         /* size/bytes */
811
        ECC_SECP160R2,                              /* ID         */
812
        "SECP160R2",                                /* curve name */
813
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
814
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
815
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
816
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
817
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
818
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
819
        ecc_oid_secp160r2,                          /* oid/oidSz  */
820
        ecc_oid_secp160r2_sz,
821
        ECC_SECP160R2_OID,                          /* oid sum    */
822
        1,                                          /* cofactor   */
823
    },
824
    #endif /* HAVE_ECC_SECPR2 */
825
    #ifdef HAVE_ECC_KOBLITZ
826
    {
827
        20,                                         /* size/bytes */
828
        ECC_SECP160K1,                              /* ID         */
829
        "SECP160K1",                                /* curve name */
830
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
831
        "0000000000000000000000000000000000000000", /* A          */
832
        "0000000000000000000000000000000000000007", /* B          */
833
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
834
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
835
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
836
        ecc_oid_secp160k1,                          /* oid/oidSz  */
837
        ecc_oid_secp160k1_sz,
838
        ECC_SECP160K1_OID,                          /* oid sum    */
839
        1,                                          /* cofactor   */
840
    },
841
    #endif /* HAVE_ECC_KOBLITZ */
842
#endif /* !FP_ECC */
843
    #ifdef HAVE_ECC_BRAINPOOL
844
    {
845
        20,                                         /* size/bytes */
846
        ECC_BRAINPOOLP160R1,                        /* ID         */
847
        "BRAINPOOLP160R1",                          /* curve name */
848
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
849
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
850
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
851
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
852
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
853
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
854
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
855
        ecc_oid_brainpoolp160r1_sz,
856
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
857
        1,                                          /* cofactor   */
858
    },
859
    #endif /* HAVE_ECC_BRAINPOOL */
860
#endif /* ECC160 */
861
#ifdef ECC192
862
    #ifndef NO_ECC_SECP
863
    {
864
        24,                                                 /* size/bytes */
865
        ECC_SECP192R1,                                      /* ID         */
866
        "SECP192R1",                                        /* curve name */
867
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
868
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
869
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
870
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
871
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
872
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
873
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
874
        ecc_oid_secp192r1_sz,
875
        ECC_SECP192R1_OID,                                  /* oid sum    */
876
        1,                                                  /* cofactor   */
877
    },
878
    #endif /* !NO_ECC_SECP */
879
    #ifdef HAVE_ECC_SECPR2
880
    {
881
        24,                                                 /* size/bytes */
882
        ECC_PRIME192V2,                                     /* ID         */
883
        "PRIME192V2",                                       /* curve name */
884
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
885
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
886
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
887
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
888
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
889
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
890
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
891
        ecc_oid_prime192v2_sz,
892
        ECC_PRIME192V2_OID,                                 /* oid sum    */
893
        1,                                                  /* cofactor   */
894
    },
895
    #endif /* HAVE_ECC_SECPR2 */
896
    #ifdef HAVE_ECC_SECPR3
897
    {
898
        24,                                                 /* size/bytes */
899
        ECC_PRIME192V3,                                     /* ID         */
900
        "PRIME192V3",                                       /* curve name */
901
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
902
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
903
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
904
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
905
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
906
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
907
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
908
        ecc_oid_prime192v3_sz,
909
        ECC_PRIME192V3_OID,                                 /* oid sum    */
910
        1,                                                  /* cofactor   */
911
    },
912
    #endif /* HAVE_ECC_SECPR3 */
913
    #ifdef HAVE_ECC_KOBLITZ
914
    {
915
        24,                                                 /* size/bytes */
916
        ECC_SECP192K1,                                      /* ID         */
917
        "SECP192K1",                                        /* curve name */
918
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
919
        "000000000000000000000000000000000000000000000000", /* A          */
920
        "000000000000000000000000000000000000000000000003", /* B          */
921
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
922
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
923
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
924
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
925
        ecc_oid_secp192k1_sz,
926
        ECC_SECP192K1_OID,                                  /* oid sum    */
927
        1,                                                  /* cofactor   */
928
    },
929
    #endif /* HAVE_ECC_KOBLITZ */
930
    #ifdef HAVE_ECC_BRAINPOOL
931
    {
932
        24,                                                 /* size/bytes */
933
        ECC_BRAINPOOLP192R1,                                /* ID         */
934
        "BRAINPOOLP192R1",                                  /* curve name */
935
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
936
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
937
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
938
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
939
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
940
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
941
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
942
        ecc_oid_brainpoolp192r1_sz,
943
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
944
        1,                                                  /* cofactor   */
945
    },
946
    #endif /* HAVE_ECC_BRAINPOOL */
947
#endif /* ECC192 */
948
#ifdef ECC224
949
    #ifndef NO_ECC_SECP
950
    {
951
        28,                                                         /* size/bytes */
952
        ECC_SECP224R1,                                              /* ID         */
953
        "SECP224R1",                                                /* curve name */
954
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
955
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
956
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
957
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
958
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
959
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
960
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
961
        ecc_oid_secp224r1_sz,
962
        ECC_SECP224R1_OID,                                          /* oid sum    */
963
        1,                                                          /* cofactor   */
964
    },
965
    #endif /* !NO_ECC_SECP */
966
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
967
    {
968
        28,                                                         /* size/bytes */
969
        ECC_SECP224K1,                                              /* ID         */
970
        "SECP224K1",                                                /* curve name */
971
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
972
        "00000000000000000000000000000000000000000000000000000000", /* A          */
973
        "00000000000000000000000000000000000000000000000000000005", /* B          */
974
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
975
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
976
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
977
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
978
        ecc_oid_secp224k1_sz,
979
        ECC_SECP224K1_OID,                                          /* oid sum    */
980
        1,                                                          /* cofactor   */
981
    },
982
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
983
    #ifdef HAVE_ECC_BRAINPOOL
984
    {
985
        28,                                                         /* size/bytes */
986
        ECC_BRAINPOOLP224R1,                                        /* ID         */
987
        "BRAINPOOLP224R1",                                          /* curve name */
988
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
989
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
990
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
991
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
992
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
993
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
994
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
995
        ecc_oid_brainpoolp224r1_sz,
996
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
997
        1,                                                          /* cofactor   */
998
    },
999
    #endif /* HAVE_ECC_BRAINPOOL */
1000
#endif /* ECC224 */
1001
#ifdef ECC239
1002
    #ifndef NO_ECC_SECP
1003
    {
1004
        30,                                                             /* size/bytes */
1005
        ECC_PRIME239V1,                                                 /* ID         */
1006
        "PRIME239V1",                                                   /* curve name */
1007
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1008
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1009
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1010
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1011
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1012
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1013
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1014
        ecc_oid_prime239v1_sz,
1015
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1016
        1,                                                              /* cofactor   */
1017
    },
1018
    #endif /* !NO_ECC_SECP */
1019
    #ifdef HAVE_ECC_SECPR2
1020
    {
1021
        30,                                                             /* size/bytes */
1022
        ECC_PRIME239V2,                                                 /* ID         */
1023
        "PRIME239V2",                                                   /* curve name */
1024
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1025
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1026
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1027
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1028
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1029
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1030
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1031
        ecc_oid_prime239v2_sz,
1032
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1033
        1,                                                              /* cofactor   */
1034
    },
1035
    #endif /* HAVE_ECC_SECPR2 */
1036
    #ifdef HAVE_ECC_SECPR3
1037
    {
1038
        30,                                                             /* size/bytes */
1039
        ECC_PRIME239V3,                                                 /* ID         */
1040
        "PRIME239V3",                                                   /* curve name */
1041
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1042
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1043
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1044
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1045
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1046
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1047
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1048
        ecc_oid_prime239v3_sz,
1049
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1050
        1,                                                              /* cofactor   */
1051
    },
1052
    #endif /* HAVE_ECC_SECPR3 */
1053
#endif /* ECC239 */
1054
#ifdef ECC256
1055
    #ifndef NO_ECC_SECP
1056
    {
1057
        32,                                                                 /* size/bytes */
1058
        ECC_SECP256R1,                                                      /* ID         */
1059
        "SECP256R1",                                                        /* curve name */
1060
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1061
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1062
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1063
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1064
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1065
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1066
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1067
        ecc_oid_secp256r1_sz,
1068
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1069
        1,                                                                  /* cofactor   */
1070
    },
1071
    #endif /* !NO_ECC_SECP */
1072
    #ifdef HAVE_ECC_KOBLITZ
1073
    {
1074
        32,                                                                 /* size/bytes */
1075
        ECC_SECP256K1,                                                      /* ID         */
1076
        "SECP256K1",                                                        /* curve name */
1077
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1078
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1079
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1080
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1081
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1082
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1083
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1084
        ecc_oid_secp256k1_sz,
1085
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1086
        1,                                                                  /* cofactor   */
1087
    },
1088
    #endif /* HAVE_ECC_KOBLITZ */
1089
    #ifdef HAVE_ECC_BRAINPOOL
1090
    {
1091
        32,                                                                 /* size/bytes */
1092
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1093
        "BRAINPOOLP256R1",                                                  /* curve name */
1094
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1095
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1096
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1097
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1098
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1099
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1100
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1101
        ecc_oid_brainpoolp256r1_sz,
1102
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1103
        1,                                                                  /* cofactor   */
1104
    },
1105
    #endif /* HAVE_ECC_BRAINPOOL */
1106
#endif /* ECC256 */
1107
#ifdef ECC320
1108
    #ifdef HAVE_ECC_BRAINPOOL
1109
    {
1110
        40,                                                                                 /* size/bytes */
1111
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1112
        "BRAINPOOLP320R1",                                                                  /* curve name */
1113
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1114
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1115
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1116
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1117
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1118
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1119
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1120
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1121
        1,                                                                                  /* cofactor   */
1122
    },
1123
    #endif /* HAVE_ECC_BRAINPOOL */
1124
#endif /* ECC320 */
1125
#ifdef ECC384
1126
    #ifndef NO_ECC_SECP
1127
    {
1128
        48,                                                                                                 /* size/bytes */
1129
        ECC_SECP384R1,                                                                                      /* ID         */
1130
        "SECP384R1",                                                                                        /* curve name */
1131
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1132
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1133
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1134
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1135
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1136
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1137
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1138
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1139
        1,                                                                                                  /* cofactor   */
1140
    },
1141
    #endif /* !NO_ECC_SECP */
1142
    #ifdef HAVE_ECC_BRAINPOOL
1143
    {
1144
        48,                                                                                                 /* size/bytes */
1145
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1146
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1147
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1148
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1149
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1150
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1151
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1152
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1153
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1154
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1155
        1,                                                                                                  /* cofactor   */
1156
    },
1157
    #endif /* HAVE_ECC_BRAINPOOL */
1158
#endif /* ECC384 */
1159
#ifdef ECC512
1160
    #ifdef HAVE_ECC_BRAINPOOL
1161
    {
1162
        64,                                                                                                                                 /* size/bytes */
1163
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1164
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1165
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1166
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1167
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1168
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1169
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1170
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1171
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1172
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1173
        1,                                                                                                                                  /* cofactor   */
1174
    },
1175
    #endif /* HAVE_ECC_BRAINPOOL */
1176
#endif /* ECC512 */
1177
#ifdef ECC521
1178
    #ifndef NO_ECC_SECP
1179
    {
1180
        66,                                                                                                                                    /* size/bytes */
1181
        ECC_SECP521R1,                                                                                                                         /* ID         */
1182
        "SECP521R1",                                                                                                                           /* curve name */
1183
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1184
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1185
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1186
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1187
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1188
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1189
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1190
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1191
        1,                                                                                                                                     /* cofactor   */
1192
    },
1193
    #endif /* !NO_ECC_SECP */
1194
#endif /* ECC521 */
1195
#ifdef WOLFCRYPT_HAVE_SAKKE
1196
    {
1197
        128,
1198
        ECC_SAKKE_1,
1199
        "SAKKE1",
1200
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1201
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1202
        "0",
1203
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1204
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1205
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1206
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1207
            NULL, 0,
1208
        #else
1209
            {0}, 0,
1210
        #endif
1211
        0,
1212
        4,
1213
    },
1214
#endif
1215
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1216
    /* place holder for custom curve index for cache */
1217
    {
1218
        1, /* non-zero */
1219
        ECC_CURVE_CUSTOM,
1220
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1221
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1222
        #else
1223
            {0},{0},{0},{0},{0},{0},{0},{0},
1224
        #endif
1225
        0, 0, 0
1226
    },
1227
#endif
1228
    {
1229
        0,
1230
        ECC_CURVE_INVALID,
1231
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1232
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1233
        #else
1234
            {0},{0},{0},{0},{0},{0},{0},{0},
1235
        #endif
1236
        0, 0, 0
1237
    }
1238
};
1239
0
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1240
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1241
1242
1243
#ifdef HAVE_OID_ENCODING
1244
    /* encoded OID cache */
1245
    typedef struct {
1246
        word32 oidSz;
1247
        byte oid[ECC_MAX_OID_LEN];
1248
    } oid_cache_t;
1249
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1250
#endif
1251
1252
1253
#ifdef HAVE_COMP_KEY
1254
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1255
#endif
1256
1257
1258
1259
#if !defined(WOLFSSL_SP_MATH) && \
1260
    !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1261
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
1262
    !defined(WOLFSSL_SE050) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
1263
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1264
    mp_int* prime, mp_int* order);
1265
#endif
1266
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1267
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1268
    !defined(WOLFSSL_KCAPI_ECC)
1269
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1270
#endif
1271
1272
1273
int mp_jacobi(mp_int* a, mp_int* n, int* c);
1274
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1275
1276
1277
/* Curve Specs */
1278
typedef struct ecc_curve_spec {
1279
    const ecc_set_type* dp;
1280
1281
    mp_int* prime;
1282
    mp_int* Af;
1283
    #ifdef USE_ECC_B_PARAM
1284
        mp_int* Bf;
1285
    #endif
1286
    mp_int* order;
1287
    mp_int* Gx;
1288
    mp_int* Gy;
1289
1290
#ifdef ECC_CACHE_CURVE
1291
    mp_int prime_lcl;
1292
    mp_int Af_lcl;
1293
    #ifdef USE_ECC_B_PARAM
1294
        mp_int Bf_lcl;
1295
    #endif
1296
    mp_int order_lcl;
1297
    mp_int Gx_lcl;
1298
    mp_int Gy_lcl;
1299
#else
1300
    mp_int* spec_ints;
1301
    word32 spec_count;
1302
    word32 spec_use;
1303
#endif
1304
1305
    byte load_mask;
1306
} ecc_curve_spec;
1307
1308
enum ecc_curve_load_mask {
1309
    ECC_CURVE_FIELD_NONE    = 0x00,
1310
    ECC_CURVE_FIELD_PRIME   = 0x01,
1311
    ECC_CURVE_FIELD_AF      = 0x02,
1312
#ifdef USE_ECC_B_PARAM
1313
    ECC_CURVE_FIELD_BF      = 0x04,
1314
#endif
1315
    ECC_CURVE_FIELD_ORDER   = 0x08,
1316
    ECC_CURVE_FIELD_GX      = 0x10,
1317
    ECC_CURVE_FIELD_GY      = 0x20,
1318
#ifdef USE_ECC_B_PARAM
1319
    ECC_CURVE_FIELD_ALL     = 0x3F,
1320
    ECC_CURVE_FIELD_COUNT   = 6,
1321
#else
1322
    ECC_CURVE_FIELD_ALL     = 0x3B,
1323
    ECC_CURVE_FIELD_COUNT   = 5,
1324
#endif
1325
};
1326
1327
#ifdef ECC_CACHE_CURVE
1328
    /* cache (mp_int) of the curve parameters */
1329
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1330
    #ifndef SINGLE_THREADED
1331
        static wolfSSL_Mutex ecc_curve_cache_mutex;
1332
    #endif
1333
1334
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1335
    #define ALLOC_CURVE_SPECS(intcount, err)
1336
    #define FREE_CURVE_SPECS()
1337
#elif defined(WOLFSSL_SMALL_STACK)
1338
    #define DECLARE_CURVE_SPECS(intcount)                               \
1339
0
        mp_int* spec_ints = NULL;                                       \
1340
0
        ecc_curve_spec curve_lcl;                                       \
1341
0
        ecc_curve_spec* curve = &curve_lcl;                             \
1342
0
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1343
0
        curve->spec_count = intcount
1344
1345
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1346
0
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1347
0
                            DYNAMIC_TYPE_ECC);                          \
1348
0
        if (spec_ints == NULL)                                          \
1349
0
            (err) = MEMORY_E;                                           \
1350
0
        else                                                            \
1351
0
            curve->spec_ints = spec_ints
1352
    #define FREE_CURVE_SPECS()                                          \
1353
0
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1354
#else
1355
    #define DECLARE_CURVE_SPECS(intcount) \
1356
        mp_int spec_ints[(intcount)]; \
1357
        ecc_curve_spec curve_lcl; \
1358
        ecc_curve_spec* curve = &curve_lcl; \
1359
        XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
1360
        curve->spec_ints = spec_ints; \
1361
        curve->spec_count = (intcount)
1362
    #define ALLOC_CURVE_SPECS(intcount, err)
1363
    #define FREE_CURVE_SPECS()
1364
#endif /* ECC_CACHE_CURVE */
1365
1366
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1367
    byte mask)
1368
0
{
1369
0
    if (item) {
1370
    #ifdef HAVE_WOLF_BIGINT
1371
        wc_bigint_free(&item->raw);
1372
    #endif
1373
0
        mp_clear(item);
1374
0
    }
1375
0
    curve->load_mask &= ~mask;
1376
0
}
1377
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1378
0
{
1379
0
    if (curve == NULL) {
1380
0
        return;
1381
0
    }
1382
1383
0
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1384
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1385
0
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1386
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1387
0
#ifdef USE_ECC_B_PARAM
1388
0
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1389
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1390
0
#endif
1391
0
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1392
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1393
0
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1394
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1395
0
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1396
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1397
1398
0
    curve->load_mask = 0;
1399
0
}
1400
1401
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1402
0
{
1403
0
    if (curve) {
1404
    #ifdef ECC_CACHE_CURVE
1405
        #ifdef WOLFSSL_CUSTOM_CURVES
1406
        /* only free custom curves (rest are globally cached) */
1407
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1408
            wc_ecc_curve_cache_free_spec(curve);
1409
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1410
        }
1411
        #endif
1412
    #else
1413
0
        wc_ecc_curve_cache_free_spec(curve);
1414
0
    #endif
1415
0
    }
1416
0
}
1417
1418
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1419
    mp_int** dst, byte mask)
1420
0
{
1421
0
    int err;
1422
1423
0
#ifndef ECC_CACHE_CURVE
1424
    /* get mp_int from temp */
1425
0
    if (curve->spec_use >= curve->spec_count) {
1426
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1427
0
        return ECC_BAD_ARG_E;
1428
0
    }
1429
0
    *dst = &curve->spec_ints[curve->spec_use++];
1430
0
#endif
1431
1432
0
    err = mp_init(*dst);
1433
0
    if (err == MP_OKAY) {
1434
0
        curve->load_mask |= mask;
1435
1436
0
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1437
1438
    #ifdef HAVE_WOLF_BIGINT
1439
        if (err == MP_OKAY)
1440
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1441
    #endif
1442
0
    }
1443
0
    return err;
1444
0
}
1445
1446
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1447
    byte load_mask)
1448
0
{
1449
0
    int ret = 0;
1450
0
    ecc_curve_spec* curve;
1451
0
    byte load_items = 0; /* mask of items to load */
1452
#ifdef ECC_CACHE_CURVE
1453
    int x;
1454
#endif
1455
1456
0
    if (dp == NULL || pCurve == NULL)
1457
0
        return BAD_FUNC_ARG;
1458
1459
#ifdef ECC_CACHE_CURVE
1460
    x = wc_ecc_get_curve_idx(dp->id);
1461
    if (x == ECC_CURVE_INVALID)
1462
        return ECC_BAD_ARG_E;
1463
1464
#if !defined(SINGLE_THREADED)
1465
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1466
    if (ret != 0) {
1467
        return ret;
1468
    }
1469
#endif
1470
1471
    /* make sure cache has been allocated */
1472
    if (ecc_curve_spec_cache[x] == NULL
1473
    #ifdef WOLFSSL_CUSTOM_CURVES
1474
        || dp->id == ECC_CURVE_CUSTOM
1475
    #endif
1476
    ) {
1477
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1478
        if (curve == NULL) {
1479
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1480
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1481
        #endif
1482
            return MEMORY_E;
1483
        }
1484
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1485
1486
        /* set curve pointer to cache */
1487
    #ifdef WOLFSSL_CUSTOM_CURVES
1488
        if (dp->id != ECC_CURVE_CUSTOM)
1489
    #endif
1490
        {
1491
            ecc_curve_spec_cache[x] = curve;
1492
        }
1493
    }
1494
    else {
1495
        curve = ecc_curve_spec_cache[x];
1496
    }
1497
    /* return new or cached curve */
1498
    *pCurve = curve;
1499
#else
1500
0
    curve = *pCurve;
1501
0
#endif /* ECC_CACHE_CURVE */
1502
1503
    /* make sure the curve is initialized */
1504
0
    if (curve->dp != dp) {
1505
0
        curve->load_mask = 0;
1506
1507
    #ifdef ECC_CACHE_CURVE
1508
        curve->prime = &curve->prime_lcl;
1509
        curve->Af = &curve->Af_lcl;
1510
        #ifdef USE_ECC_B_PARAM
1511
            curve->Bf = &curve->Bf_lcl;
1512
        #endif
1513
        curve->order = &curve->order_lcl;
1514
        curve->Gx = &curve->Gx_lcl;
1515
        curve->Gy = &curve->Gy_lcl;
1516
    #endif
1517
0
    }
1518
0
    curve->dp = dp; /* set dp info */
1519
1520
    /* determine items to load */
1521
0
    load_items = (((byte)~(word32)curve->load_mask) & load_mask);
1522
0
    curve->load_mask |= load_items;
1523
1524
    /* load items */
1525
0
    if (load_items & ECC_CURVE_FIELD_PRIME)
1526
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1527
0
            ECC_CURVE_FIELD_PRIME);
1528
0
    if (load_items & ECC_CURVE_FIELD_AF)
1529
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1530
0
            ECC_CURVE_FIELD_AF);
1531
0
#ifdef USE_ECC_B_PARAM
1532
0
    if (load_items & ECC_CURVE_FIELD_BF)
1533
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1534
0
            ECC_CURVE_FIELD_BF);
1535
0
#endif
1536
0
    if (load_items & ECC_CURVE_FIELD_ORDER)
1537
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1538
0
            ECC_CURVE_FIELD_ORDER);
1539
0
    if (load_items & ECC_CURVE_FIELD_GX)
1540
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1541
0
            ECC_CURVE_FIELD_GX);
1542
0
    if (load_items & ECC_CURVE_FIELD_GY)
1543
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1544
0
            ECC_CURVE_FIELD_GY);
1545
1546
    /* check for error */
1547
0
    if (ret != 0) {
1548
0
        wc_ecc_curve_free(curve);
1549
0
        ret = MP_READ_E;
1550
0
    }
1551
1552
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1553
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1554
#endif
1555
1556
0
    return ret;
1557
0
}
1558
1559
#ifdef ECC_CACHE_CURVE
1560
int wc_ecc_curve_cache_init(void)
1561
{
1562
    int ret = 0;
1563
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1564
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1565
#endif
1566
    return ret;
1567
}
1568
1569
void wc_ecc_curve_cache_free(void)
1570
{
1571
    int x;
1572
1573
    /* free all ECC curve caches */
1574
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1575
        if (ecc_curve_spec_cache[x]) {
1576
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1577
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1578
            ecc_curve_spec_cache[x] = NULL;
1579
        }
1580
    }
1581
1582
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1583
    wc_FreeMutex(&ecc_curve_cache_mutex);
1584
#endif
1585
}
1586
#endif /* ECC_CACHE_CURVE */
1587
1588
1589
/* Retrieve the curve name for the ECC curve id.
1590
 *
1591
 * curve_id  The id of the curve.
1592
 * returns the name stored from the curve if available, otherwise NULL.
1593
 */
1594
const char* wc_ecc_get_name(int curve_id)
1595
0
{
1596
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1597
0
    if (curve_idx == ECC_CURVE_INVALID)
1598
0
        return NULL;
1599
0
    return ecc_sets[curve_idx].name;
1600
0
}
1601
1602
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1603
0
{
1604
0
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1605
0
        return BAD_FUNC_ARG;
1606
0
    }
1607
1608
0
    if (keysize > ECC_MAXSIZE) {
1609
0
        return ECC_BAD_ARG_E;
1610
0
    }
1611
1612
    /* handle custom case */
1613
0
    if (key->idx != ECC_CUSTOM_IDX) {
1614
0
        int x;
1615
1616
        /* default values */
1617
0
        key->idx = 0;
1618
0
        key->dp = NULL;
1619
1620
        /* find ecc_set based on curve_id or key size */
1621
0
        for (x = 0; ecc_sets[x].size != 0; x++) {
1622
0
            if (curve_id > ECC_CURVE_DEF) {
1623
0
                if (curve_id == ecc_sets[x].id)
1624
0
                  break;
1625
0
            }
1626
0
            else if (keysize <= ecc_sets[x].size) {
1627
0
                break;
1628
0
            }
1629
0
        }
1630
0
        if (ecc_sets[x].size == 0) {
1631
0
            WOLFSSL_MSG("ECC Curve not found");
1632
0
            return ECC_CURVE_OID_E;
1633
0
        }
1634
1635
0
        key->idx = x;
1636
0
        key->dp  = &ecc_sets[x];
1637
0
    }
1638
1639
0
    return 0;
1640
0
}
1641
1642
1643
#ifdef ALT_ECC_SIZE
1644
static void alt_fp_init(mp_int* a)
1645
{
1646
    a->size = FP_SIZE_ECC;
1647
    mp_zero(a);
1648
}
1649
#endif /* ALT_ECC_SIZE */
1650
1651
1652
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1653
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
1654
1655
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
1656
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
1657
                                     mp_int* modulus, mp_digit mp);
1658
1659
/**
1660
   Add two ECC points
1661
   P        The point to add
1662
   Q        The point to add
1663
   R        [out] The destination of the double
1664
   a        ECC curve parameter a
1665
   modulus  The modulus of the field the ECC curve is in
1666
   mp       The "b" value from montgomery_setup()
1667
   return   MP_OKAY on success
1668
*/
1669
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
1670
                                     mp_int* a, mp_int* modulus, mp_digit mp)
1671
0
{
1672
0
#if !defined(WOLFSSL_SP_MATH)
1673
0
#ifdef WOLFSSL_SMALL_STACK
1674
0
   mp_int* t1 = NULL;
1675
0
   mp_int* t2 = NULL;
1676
#ifdef ALT_ECC_SIZE
1677
   mp_int* rx = NULL;
1678
   mp_int* ry = NULL;
1679
   mp_int* rz = NULL;
1680
#endif
1681
#else
1682
   mp_int  t1[1], t2[1];
1683
#ifdef ALT_ECC_SIZE
1684
   mp_int  rx[1], ry[1], rz[1];
1685
#endif
1686
#endif
1687
0
   mp_int  *x, *y, *z;
1688
0
   int     err;
1689
1690
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1691
0
   if (Q == R) {
1692
0
      ecc_point* tPt  = P;
1693
0
      P = Q;
1694
0
      Q = tPt;
1695
0
   }
1696
1697
0
#ifdef WOLFSSL_SMALL_STACK
1698
#ifdef WOLFSSL_SMALL_STACK_CACHE
1699
   if (R->key != NULL) {
1700
       t1 = R->key->t1;
1701
       t2 = R->key->t2;
1702
#ifdef ALT_ECC_SIZE
1703
       rx = R->key->x;
1704
       ry = R->key->y;
1705
       rz = R->key->z;
1706
#endif
1707
   }
1708
   else
1709
#endif /* WOLFSSL_SMALL_STACK_CACHE */
1710
0
   {
1711
0
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1712
0
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1713
0
       if (t1 == NULL || t2 == NULL) {
1714
0
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1715
0
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1716
0
           return MEMORY_E;
1717
0
       }
1718
#ifdef ALT_ECC_SIZE
1719
       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1720
       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1721
       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1722
       if (rx == NULL || ry == NULL || rz == NULL) {
1723
           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
1724
           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
1725
           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
1726
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1727
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1728
           return MEMORY_E;
1729
       }
1730
#endif
1731
0
   }
1732
0
#endif /* WOLFSSL_SMALL_STACK */
1733
1734
0
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
1735
0
#ifdef WOLFSSL_SMALL_STACK
1736
   #ifdef WOLFSSL_SMALL_STACK_CACHE
1737
       if (R->key == NULL)
1738
   #endif
1739
0
       {
1740
       #ifdef ALT_ECC_SIZE
1741
          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
1742
          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
1743
          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
1744
       #endif
1745
0
          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1746
0
          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1747
0
       }
1748
0
#endif
1749
0
      return err;
1750
0
   }
1751
1752
   /* should we dbl instead? */
1753
0
   if (err == MP_OKAY) {
1754
0
#ifdef ECC_TIMING_RESISTANT
1755
0
       err = mp_submod_ct(modulus, Q->y, modulus, t1);
1756
#else
1757
       err = mp_sub(modulus, Q->y, t1);
1758
#endif
1759
0
   }
1760
0
   if (err == MP_OKAY) {
1761
0
       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
1762
0
            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
1763
0
            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
1764
0
           mp_clear(t1);
1765
0
           mp_clear(t2);
1766
0
    #ifdef WOLFSSL_SMALL_STACK
1767
       #ifdef WOLFSSL_SMALL_STACK_CACHE
1768
           if (R->key == NULL)
1769
       #endif
1770
0
           {
1771
            #ifdef ALT_ECC_SIZE
1772
               XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
1773
               XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
1774
               XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
1775
            #endif
1776
0
               XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1777
0
               XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1778
0
           }
1779
0
        #endif
1780
0
          return _ecc_projective_dbl_point(P, R, a, modulus, mp);
1781
0
       }
1782
0
   }
1783
1784
0
   if (err != MP_OKAY) {
1785
0
      goto done;
1786
0
   }
1787
1788
/* If use ALT_ECC_SIZE we need to use local stack variable since
1789
   ecc_point x,y,z is reduced size */
1790
#ifdef ALT_ECC_SIZE
1791
   /* Use local stack variable */
1792
   x = rx;
1793
   y = ry;
1794
   z = rz;
1795
1796
   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
1797
      goto done;
1798
   }
1799
#else
1800
   /* Use destination directly */
1801
0
   x = R->x;
1802
0
   y = R->y;
1803
0
   z = R->z;
1804
0
#endif
1805
1806
0
   if (err == MP_OKAY)
1807
0
       err = mp_copy(P->x, x);
1808
0
   if (err == MP_OKAY)
1809
0
       err = mp_copy(P->y, y);
1810
0
   if (err == MP_OKAY)
1811
0
       err = mp_copy(P->z, z);
1812
1813
   /* if Z is one then these are no-operations */
1814
0
   if (err == MP_OKAY) {
1815
0
       if (!mp_iszero(Q->z)) {
1816
           /* T1 = Z' * Z' */
1817
0
           err = mp_sqr(Q->z, t1);
1818
0
           if (err == MP_OKAY)
1819
0
               err = mp_montgomery_reduce(t1, modulus, mp);
1820
1821
           /* X = X * T1 */
1822
0
           if (err == MP_OKAY)
1823
0
               err = mp_mul(t1, x, x);
1824
0
           if (err == MP_OKAY)
1825
0
               err = mp_montgomery_reduce(x, modulus, mp);
1826
1827
           /* T1 = Z' * T1 */
1828
0
           if (err == MP_OKAY)
1829
0
               err = mp_mul(Q->z, t1, t1);
1830
0
           if (err == MP_OKAY)
1831
0
               err = mp_montgomery_reduce(t1, modulus, mp);
1832
1833
           /* Y = Y * T1 */
1834
0
           if (err == MP_OKAY)
1835
0
               err = mp_mul(t1, y, y);
1836
0
           if (err == MP_OKAY)
1837
0
               err = mp_montgomery_reduce(y, modulus, mp);
1838
0
       }
1839
0
   }
1840
1841
   /* T1 = Z*Z */
1842
0
   if (err == MP_OKAY)
1843
0
       err = mp_sqr(z, t1);
1844
0
   if (err == MP_OKAY)
1845
0
       err = mp_montgomery_reduce(t1, modulus, mp);
1846
1847
   /* T2 = X' * T1 */
1848
0
   if (err == MP_OKAY)
1849
0
       err = mp_mul(Q->x, t1, t2);
1850
0
   if (err == MP_OKAY)
1851
0
       err = mp_montgomery_reduce(t2, modulus, mp);
1852
1853
   /* T1 = Z * T1 */
1854
0
   if (err == MP_OKAY)
1855
0
       err = mp_mul(z, t1, t1);
1856
0
   if (err == MP_OKAY)
1857
0
       err = mp_montgomery_reduce(t1, modulus, mp);
1858
1859
   /* T1 = Y' * T1 */
1860
0
   if (err == MP_OKAY)
1861
0
       err = mp_mul(Q->y, t1, t1);
1862
0
   if (err == MP_OKAY)
1863
0
       err = mp_montgomery_reduce(t1, modulus, mp);
1864
1865
   /* Y = Y - T1 */
1866
0
   if (err == MP_OKAY)
1867
0
       err = mp_submod_ct(y, t1, modulus, y);
1868
   /* T1 = 2T1 */
1869
0
   if (err == MP_OKAY)
1870
0
       err = mp_addmod_ct(t1, t1, modulus, t1);
1871
   /* T1 = Y + T1 */
1872
0
   if (err == MP_OKAY)
1873
0
       err = mp_addmod_ct(t1, y, modulus, t1);
1874
   /* X = X - T2 */
1875
0
   if (err == MP_OKAY)
1876
0
       err = mp_submod_ct(x, t2, modulus, x);
1877
   /* T2 = 2T2 */
1878
0
   if (err == MP_OKAY)
1879
0
       err = mp_addmod_ct(t2, t2, modulus, t2);
1880
   /* T2 = X + T2 */
1881
0
   if (err == MP_OKAY)
1882
0
       err = mp_addmod_ct(t2, x, modulus, t2);
1883
1884
0
   if (err == MP_OKAY) {
1885
0
       if (!mp_iszero(Q->z)) {
1886
           /* Z = Z * Z' */
1887
0
           err = mp_mul(z, Q->z, z);
1888
0
           if (err == MP_OKAY)
1889
0
               err = mp_montgomery_reduce(z, modulus, mp);
1890
0
       }
1891
0
   }
1892
1893
   /* Z = Z * X */
1894
0
   if (err == MP_OKAY)
1895
0
       err = mp_mul(z, x, z);
1896
0
   if (err == MP_OKAY)
1897
0
       err = mp_montgomery_reduce(z, modulus, mp);
1898
1899
   /* T1 = T1 * X  */
1900
0
   if (err == MP_OKAY)
1901
0
       err = mp_mul(t1, x, t1);
1902
0
   if (err == MP_OKAY)
1903
0
       err = mp_montgomery_reduce(t1, modulus, mp);
1904
1905
   /* X = X * X */
1906
0
   if (err == MP_OKAY)
1907
0
       err = mp_sqr(x, x);
1908
0
   if (err == MP_OKAY)
1909
0
       err = mp_montgomery_reduce(x, modulus, mp);
1910
1911
   /* T2 = T2 * x */
1912
0
   if (err == MP_OKAY)
1913
0
       err = mp_mul(t2, x, t2);
1914
0
   if (err == MP_OKAY)
1915
0
       err = mp_montgomery_reduce(t2, modulus, mp);
1916
1917
   /* T1 = T1 * X  */
1918
0
   if (err == MP_OKAY)
1919
0
       err = mp_mul(t1, x, t1);
1920
0
   if (err == MP_OKAY)
1921
0
       err = mp_montgomery_reduce(t1, modulus, mp);
1922
1923
   /* X = Y*Y */
1924
0
   if (err == MP_OKAY)
1925
0
       err = mp_sqr(y, x);
1926
0
   if (err == MP_OKAY)
1927
0
       err = mp_montgomery_reduce(x, modulus, mp);
1928
1929
   /* X = X - T2 */
1930
0
   if (err == MP_OKAY)
1931
0
       err = mp_submod_ct(x, t2, modulus, x);
1932
   /* T2 = T2 - X */
1933
0
   if (err == MP_OKAY)
1934
0
       err = mp_submod_ct(t2, x, modulus, t2);
1935
   /* T2 = T2 - X */
1936
0
   if (err == MP_OKAY)
1937
0
       err = mp_submod_ct(t2, x, modulus, t2);
1938
   /* T2 = T2 * Y */
1939
0
   if (err == MP_OKAY)
1940
0
       err = mp_mul(t2, y, t2);
1941
0
   if (err == MP_OKAY)
1942
0
       err = mp_montgomery_reduce(t2, modulus, mp);
1943
1944
   /* Y = T2 - T1 */
1945
0
   if (err == MP_OKAY)
1946
0
       err = mp_submod_ct(t2, t1, modulus, y);
1947
   /* Y = Y/2 */
1948
0
   if (err == MP_OKAY)
1949
0
       err = mp_div_2_mod_ct(y, modulus, y);
1950
1951
#ifdef ALT_ECC_SIZE
1952
   if (err == MP_OKAY)
1953
       err = mp_copy(x, R->x);
1954
   if (err == MP_OKAY)
1955
       err = mp_copy(y, R->y);
1956
   if (err == MP_OKAY)
1957
       err = mp_copy(z, R->z);
1958
#endif
1959
1960
0
done:
1961
1962
   /* clean up */
1963
0
   mp_clear(t1);
1964
0
   mp_clear(t2);
1965
0
#ifdef WOLFSSL_SMALL_STACK
1966
#ifdef WOLFSSL_SMALL_STACK_CACHE
1967
   if (R->key == NULL)
1968
#endif
1969
0
   {
1970
   #ifdef ALT_ECC_SIZE
1971
      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
1972
      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
1973
      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
1974
   #endif
1975
0
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1976
0
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1977
0
   }
1978
0
#endif
1979
1980
0
   return err;
1981
#else
1982
    int modBits = mp_count_bits(modulus);
1983
1984
    (void)a;
1985
    (void)mp;
1986
1987
#ifndef WOLFSSL_SP_NO_256
1988
    if (modBits == 256) {
1989
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
1990
                                         R->x, R->y, R->z);
1991
    }
1992
#endif
1993
#ifdef WOLFSSL_SP_384
1994
    if (modBits == 384) {
1995
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
1996
                                         R->x, R->y, R->z);
1997
    }
1998
#endif
1999
#ifdef WOLFSSL_SP_521
2000
    if (modBits == 521) {
2001
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2002
                                         R->x, R->y, R->z);
2003
    }
2004
#endif
2005
    return ECC_BAD_ARG_E;
2006
#endif
2007
0
}
2008
2009
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2010
                             mp_int* a, mp_int* modulus, mp_digit mp)
2011
0
{
2012
0
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2013
0
        return ECC_BAD_ARG_E;
2014
0
    }
2015
2016
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2017
0
        mp_cmp(P->y, modulus) != MP_LT ||
2018
0
        mp_cmp(P->z, modulus) != MP_LT ||
2019
0
        mp_cmp(Q->x, modulus) != MP_LT ||
2020
0
        mp_cmp(Q->y, modulus) != MP_LT ||
2021
0
        mp_cmp(Q->z, modulus) != MP_LT) {
2022
0
        return ECC_OUT_OF_RANGE_E;
2023
0
    }
2024
2025
0
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2026
0
}
2027
2028
/* ### Point doubling in Jacobian coordinate system ###
2029
 *
2030
 * let us have a curve:                 y^2 = x^3 + a*x + b
2031
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2032
 *
2033
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2034
 * Xr = M^2 - 2*S
2035
 * Yr = M * (S - Xr) - 8*T
2036
 * Zr = 2 * Yp * Zp
2037
 *
2038
 * M = 3 * Xp^2 + a*Zp^4
2039
 * T = Yp^4
2040
 * S = 4 * Xp * Yp^2
2041
 *
2042
 * SPECIAL CASE: when a == 3 we can compute M as
2043
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2044
 */
2045
2046
/**
2047
   Double an ECC point
2048
   P   The point to double
2049
   R   [out] The destination of the double
2050
   a   ECC curve parameter a
2051
   modulus  The modulus of the field the ECC curve is in
2052
   mp       The "b" value from montgomery_setup()
2053
   return   MP_OKAY on success
2054
*/
2055
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2056
                                     mp_int* modulus, mp_digit mp)
2057
0
{
2058
0
#if !defined(WOLFSSL_SP_MATH)
2059
0
#ifdef WOLFSSL_SMALL_STACK
2060
0
   mp_int* t1 = NULL;
2061
0
   mp_int* t2 = NULL;
2062
#ifdef ALT_ECC_SIZE
2063
   mp_int* rx = NULL;
2064
   mp_int* ry = NULL;
2065
   mp_int* rz = NULL;
2066
#endif
2067
#else
2068
   mp_int  t1[1], t2[1];
2069
#ifdef ALT_ECC_SIZE
2070
   mp_int  rx[1], ry[1], rz[1];
2071
#endif
2072
#endif
2073
0
   mp_int *x, *y, *z;
2074
0
   int    err;
2075
2076
0
#ifdef WOLFSSL_SMALL_STACK
2077
#ifdef WOLFSSL_SMALL_STACK_CACHE
2078
   if (R->key != NULL) {
2079
       t1 = R->key->t1;
2080
       t2 = R->key->t2;
2081
   #ifdef ALT_ECC_SIZE
2082
       rx = R->key->x;
2083
       ry = R->key->y;
2084
       rz = R->key->z;
2085
   #endif
2086
   }
2087
   else
2088
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2089
0
   {
2090
0
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2091
0
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2092
0
       if (t1 == NULL || t2 == NULL) {
2093
0
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2094
0
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2095
0
           return MEMORY_E;
2096
0
       }
2097
    #ifdef ALT_ECC_SIZE
2098
       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2099
       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2100
       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2101
       if (rx == NULL || ry == NULL || rz == NULL) {
2102
           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2103
           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2104
           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2105
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2106
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2107
           return MEMORY_E;
2108
       }
2109
    #endif
2110
0
    }
2111
0
#endif
2112
2113
0
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
2114
0
#ifdef WOLFSSL_SMALL_STACK
2115
#ifdef WOLFSSL_SMALL_STACK_CACHE
2116
    if (R->key == NULL)
2117
#endif
2118
0
    {
2119
    #ifdef ALT_ECC_SIZE
2120
       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2121
       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2122
       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2123
    #endif
2124
0
       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2125
0
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2126
0
     }
2127
0
#endif
2128
0
      return err;
2129
0
   }
2130
2131
/* If use ALT_ECC_SIZE we need to use local stack variable since
2132
   ecc_point x,y,z is reduced size */
2133
#ifdef ALT_ECC_SIZE
2134
   /* Use local stack variable */
2135
   x = rx;
2136
   y = ry;
2137
   z = rz;
2138
2139
   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
2140
       mp_clear(t1);
2141
       mp_clear(t2);
2142
    #ifdef WOLFSSL_SMALL_STACK
2143
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2144
       if (R->key == NULL)
2145
    #endif
2146
       {
2147
       #ifdef ALT_ECC_SIZE
2148
          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2149
          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2150
          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2151
       #endif
2152
          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2153
          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2154
       }
2155
    #endif
2156
       return err;
2157
   }
2158
#else
2159
   /* Use destination directly */
2160
0
   x = R->x;
2161
0
   y = R->y;
2162
0
   z = R->z;
2163
0
#endif
2164
2165
0
   if (err == MP_OKAY)
2166
0
       err = mp_copy(P->x, x);
2167
0
   if (err == MP_OKAY)
2168
0
       err = mp_copy(P->y, y);
2169
0
   if (err == MP_OKAY)
2170
0
       err = mp_copy(P->z, z);
2171
2172
   /* T1 = Z * Z */
2173
0
   if (err == MP_OKAY)
2174
0
       err = mp_sqr(z, t1);
2175
0
   if (err == MP_OKAY)
2176
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2177
2178
   /* Z = Y * Z */
2179
0
   if (err == MP_OKAY)
2180
0
       err = mp_mul(z, y, z);
2181
0
   if (err == MP_OKAY)
2182
0
       err = mp_montgomery_reduce(z, modulus, mp);
2183
2184
   /* Z = 2Z */
2185
0
   if (err == MP_OKAY)
2186
0
       err = mp_addmod_ct(z, z, modulus, z);
2187
2188
   /* Determine if curve "a" should be used in calc */
2189
0
#ifdef WOLFSSL_CUSTOM_CURVES
2190
0
   if (err == MP_OKAY) {
2191
      /* Use a and prime to determine if a == 3 */
2192
0
      err = mp_submod(modulus, a, modulus, t2);
2193
0
   }
2194
0
   if (err == MP_OKAY && mp_iszero(t2)) {
2195
      /* T2 = X * X */
2196
0
      if (err == MP_OKAY)
2197
0
          err = mp_sqr(x, t2);
2198
0
      if (err == MP_OKAY)
2199
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2200
      /* T1 = T2 + T1 */
2201
0
      if (err == MP_OKAY)
2202
0
          err = mp_addmod_ct(t2, t2, modulus, t1);
2203
      /* T1 = T2 + T1 */
2204
0
      if (err == MP_OKAY)
2205
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2206
0
   }
2207
0
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2208
      /* use "a" in calc */
2209
2210
      /* T2 = T1 * T1 */
2211
0
      if (err == MP_OKAY)
2212
0
          err = mp_sqr(t1, t2);
2213
0
      if (err == MP_OKAY)
2214
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2215
      /* T1 = T2 * a */
2216
0
      if (err == MP_OKAY)
2217
0
          err = mp_mulmod(t2, a, modulus, t1);
2218
      /* T2 = X * X */
2219
0
      if (err == MP_OKAY)
2220
0
          err = mp_sqr(x, t2);
2221
0
      if (err == MP_OKAY)
2222
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2223
      /* T1 = T2 + T1 */
2224
0
      if (err == MP_OKAY)
2225
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2226
      /* T1 = T2 + T1 */
2227
0
      if (err == MP_OKAY)
2228
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2229
      /* T1 = T2 + T1 */
2230
0
      if (err == MP_OKAY)
2231
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2232
0
   }
2233
0
   else
2234
0
#endif /* WOLFSSL_CUSTOM_CURVES */
2235
0
   {
2236
      /* assumes "a" == 3 */
2237
0
      (void)a;
2238
2239
      /* T2 = X - T1 */
2240
0
      if (err == MP_OKAY)
2241
0
          err = mp_submod_ct(x, t1, modulus, t2);
2242
      /* T1 = X + T1 */
2243
0
      if (err == MP_OKAY)
2244
0
          err = mp_addmod_ct(t1, x, modulus, t1);
2245
      /* T2 = T1 * T2 */
2246
0
      if (err == MP_OKAY)
2247
0
          err = mp_mul(t1, t2, t2);
2248
0
      if (err == MP_OKAY)
2249
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2250
2251
      /* T1 = 2T2 */
2252
0
      if (err == MP_OKAY)
2253
0
          err = mp_addmod_ct(t2, t2, modulus, t1);
2254
      /* T1 = T1 + T2 */
2255
0
      if (err == MP_OKAY)
2256
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2257
0
   }
2258
2259
   /* Y = 2Y */
2260
0
   if (err == MP_OKAY)
2261
0
       err = mp_addmod_ct(y, y, modulus, y);
2262
   /* Y = Y * Y */
2263
0
   if (err == MP_OKAY)
2264
0
       err = mp_sqr(y, y);
2265
0
   if (err == MP_OKAY)
2266
0
       err = mp_montgomery_reduce(y, modulus, mp);
2267
2268
   /* T2 = Y * Y */
2269
0
   if (err == MP_OKAY)
2270
0
       err = mp_sqr(y, t2);
2271
0
   if (err == MP_OKAY)
2272
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2273
2274
   /* T2 = T2/2 */
2275
0
   if (err == MP_OKAY)
2276
0
       err = mp_div_2_mod_ct(t2, modulus, t2);
2277
2278
   /* Y = Y * X */
2279
0
   if (err == MP_OKAY)
2280
0
       err = mp_mul(y, x, y);
2281
0
   if (err == MP_OKAY)
2282
0
       err = mp_montgomery_reduce(y, modulus, mp);
2283
2284
   /* X = T1 * T1 */
2285
0
   if (err == MP_OKAY)
2286
0
       err = mp_sqr(t1, x);
2287
0
   if (err == MP_OKAY)
2288
0
       err = mp_montgomery_reduce(x, modulus, mp);
2289
2290
   /* X = X - Y */
2291
0
   if (err == MP_OKAY)
2292
0
       err = mp_submod_ct(x, y, modulus, x);
2293
   /* X = X - Y */
2294
0
   if (err == MP_OKAY)
2295
0
       err = mp_submod_ct(x, y, modulus, x);
2296
2297
   /* Y = Y - X */
2298
0
   if (err == MP_OKAY)
2299
0
       err = mp_submod_ct(y, x, modulus, y);
2300
   /* Y = Y * T1 */
2301
0
   if (err == MP_OKAY)
2302
0
       err = mp_mul(y, t1, y);
2303
0
   if (err == MP_OKAY)
2304
0
       err = mp_montgomery_reduce(y, modulus, mp);
2305
2306
   /* Y = Y - T2 */
2307
0
   if (err == MP_OKAY)
2308
0
       err = mp_submod_ct(y, t2, modulus, y);
2309
2310
#ifdef ALT_ECC_SIZE
2311
   if (err == MP_OKAY)
2312
       err = mp_copy(x, R->x);
2313
   if (err == MP_OKAY)
2314
       err = mp_copy(y, R->y);
2315
   if (err == MP_OKAY)
2316
       err = mp_copy(z, R->z);
2317
#endif
2318
2319
   /* clean up */
2320
0
   mp_clear(t1);
2321
0
   mp_clear(t2);
2322
2323
0
#ifdef WOLFSSL_SMALL_STACK
2324
#ifdef WOLFSSL_SMALL_STACK_CACHE
2325
   if (R->key == NULL)
2326
#endif
2327
0
   {
2328
    #ifdef ALT_ECC_SIZE
2329
       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2330
       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2331
       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2332
    #endif
2333
0
       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2334
0
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2335
0
    }
2336
0
#endif
2337
2338
0
   return err;
2339
#else
2340
    int modBits = mp_count_bits(modulus);
2341
2342
    (void)a;
2343
    (void)mp;
2344
2345
#ifndef WOLFSSL_SP_NO_256
2346
    if (modBits == 256) {
2347
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2348
    }
2349
#endif
2350
#ifdef WOLFSSL_SP_384
2351
    if (modBits == 384) {
2352
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2353
    }
2354
#endif
2355
#ifdef WOLFSSL_SP_521
2356
    if (modBits == 521) {
2357
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2358
    }
2359
#endif
2360
    return ECC_BAD_ARG_E;
2361
#endif
2362
0
}
2363
2364
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2365
                             mp_int* modulus, mp_digit mp)
2366
0
{
2367
0
    if (P == NULL || R == NULL || modulus == NULL)
2368
0
        return ECC_BAD_ARG_E;
2369
2370
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2371
0
        mp_cmp(P->y, modulus) != MP_LT ||
2372
0
        mp_cmp(P->z, modulus) != MP_LT) {
2373
0
        return ECC_OUT_OF_RANGE_E;
2374
0
    }
2375
2376
0
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2377
0
}
2378
2379
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2380
    !defined(WOLFSSL_CRYPTOCELL)
2381
2382
2383
/**
2384
  Map a projective Jacobian point back to affine space
2385
  P        [in/out] The point to map
2386
  modulus  The modulus of the field the ECC curve is in
2387
  mp       The "b" value from montgomery_setup()
2388
  ct       Operation should be constant time.
2389
  return   MP_OKAY on success
2390
*/
2391
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2392
0
{
2393
0
#if !defined(WOLFSSL_SP_MATH)
2394
0
#ifdef WOLFSSL_SMALL_STACK
2395
0
   mp_int* t1 = NULL;
2396
0
   mp_int* t2 = NULL;
2397
#ifdef ALT_ECC_SIZE
2398
   mp_int* rx = NULL;
2399
   mp_int* ry = NULL;
2400
   mp_int* rz = NULL;
2401
#endif
2402
#else
2403
   mp_int  t1[1], t2[1];
2404
#ifdef ALT_ECC_SIZE
2405
   mp_int  rx[1], ry[1], rz[1];
2406
#endif
2407
#endif /* WOLFSSL_SMALL_STACK */
2408
0
   mp_int *x, *y, *z;
2409
0
   int    err;
2410
2411
0
   (void)ct;
2412
2413
0
   if (P == NULL || modulus == NULL)
2414
0
       return ECC_BAD_ARG_E;
2415
2416
   /* special case for point at infinity */
2417
0
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2418
0
       err = mp_set(P->x, 0);
2419
0
       if (err == MP_OKAY)
2420
0
           err = mp_set(P->y, 0);
2421
0
       if (err == MP_OKAY)
2422
0
           err = mp_set(P->z, 1);
2423
0
       return err;
2424
0
   }
2425
2426
0
#ifdef WOLFSSL_SMALL_STACK
2427
#ifdef WOLFSSL_SMALL_STACK_CACHE
2428
   if (P->key != NULL) {
2429
       t1 = P->key->t1;
2430
       t2 = P->key->t2;
2431
   #ifdef ALT_ECC_SIZE
2432
       rx = P->key->x;
2433
       ry = P->key->y;
2434
       rz = P->key->z;
2435
   #endif
2436
   }
2437
   else
2438
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2439
0
   {
2440
0
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2441
0
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2442
0
       if (t1 == NULL || t2 == NULL) {
2443
0
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2444
0
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2445
0
           return MEMORY_E;
2446
0
       }
2447
#ifdef ALT_ECC_SIZE
2448
       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2449
       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2450
       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2451
       if (rx == NULL || ry == NULL || rz == NULL) {
2452
           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2453
           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2454
           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2455
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2456
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2457
           return MEMORY_E;
2458
       }
2459
#endif
2460
0
   }
2461
0
#endif /* WOLFSSL_SMALL_STACK */
2462
2463
0
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
2464
0
#ifdef WOLFSSL_SMALL_STACK
2465
#ifdef WOLFSSL_SMALL_STACK_CACHE
2466
      if (P->key == NULL)
2467
#endif
2468
0
      {
2469
      #ifdef ALT_ECC_SIZE
2470
         XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2471
         XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2472
         XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2473
      #endif
2474
0
         XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2475
0
         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2476
0
      }
2477
0
#endif
2478
0
      return MEMORY_E;
2479
0
   }
2480
2481
#ifdef ALT_ECC_SIZE
2482
   /* Use local stack variable */
2483
   x = rx;
2484
   y = ry;
2485
   z = rz;
2486
2487
   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
2488
       goto done;
2489
   }
2490
2491
   if (err == MP_OKAY)
2492
       err = mp_copy(P->x, x);
2493
   if (err == MP_OKAY)
2494
       err = mp_copy(P->y, y);
2495
   if (err == MP_OKAY)
2496
       err = mp_copy(P->z, z);
2497
2498
   if (err != MP_OKAY) {
2499
      goto done;
2500
   }
2501
#else
2502
   /* Use destination directly */
2503
0
   x = P->x;
2504
0
   y = P->y;
2505
0
   z = P->z;
2506
0
#endif
2507
2508
   /* get 1/z */
2509
0
   if (err == MP_OKAY) {
2510
0
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2511
0
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2512
0
       if (ct) {
2513
0
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2514
0
           if (err == MP_OKAY)
2515
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2516
0
       }
2517
0
       else
2518
0
#endif
2519
0
       {
2520
           /* first map z back to normal */
2521
0
           err = mp_montgomery_reduce(z, modulus, mp);
2522
0
           if (err == MP_OKAY)
2523
0
               err = mp_invmod(z, modulus, t1);
2524
0
       }
2525
0
   }
2526
2527
   /* get 1/z^2 and 1/z^3 */
2528
0
   if (err == MP_OKAY)
2529
0
       err = mp_sqr(t1, t2);
2530
0
   if (err == MP_OKAY)
2531
0
       err = mp_mod(t2, modulus, t2);
2532
0
   if (err == MP_OKAY)
2533
0
       err = mp_mul(t1, t2, t1);
2534
0
   if (err == MP_OKAY)
2535
0
       err = mp_mod(t1, modulus, t1);
2536
2537
   /* multiply against x/y */
2538
0
   if (err == MP_OKAY)
2539
0
       err = mp_mul(x, t2, x);
2540
0
   if (err == MP_OKAY)
2541
0
       err = mp_montgomery_reduce(x, modulus, mp);
2542
0
   if (err == MP_OKAY)
2543
0
       err = mp_mul(y, t1, y);
2544
0
   if (err == MP_OKAY)
2545
0
       err = mp_montgomery_reduce(y, modulus, mp);
2546
2547
0
   if (err == MP_OKAY)
2548
0
       err = mp_set(z, 1);
2549
2550
#ifdef ALT_ECC_SIZE
2551
   /* return result */
2552
   if (err == MP_OKAY)
2553
      err = mp_copy(x, P->x);
2554
   if (err == MP_OKAY)
2555
      err = mp_copy(y, P->y);
2556
   if (err == MP_OKAY)
2557
      err = mp_copy(z, P->z);
2558
2559
done:
2560
#endif
2561
2562
   /* clean up */
2563
0
   mp_clear(t1);
2564
0
   mp_clear(t2);
2565
2566
0
#ifdef WOLFSSL_SMALL_STACK
2567
#ifdef WOLFSSL_SMALL_STACK_CACHE
2568
   if (P->key == NULL)
2569
#endif
2570
0
   {
2571
   #ifdef ALT_ECC_SIZE
2572
      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
2573
      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
2574
      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
2575
   #endif
2576
0
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2577
0
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2578
0
   }
2579
0
#endif
2580
2581
0
   return err;
2582
#else
2583
   if (P == NULL || modulus == NULL)
2584
       return ECC_BAD_ARG_E;
2585
2586
   (void)mp;
2587
   (void)ct;
2588
2589
#ifndef WOLFSSL_SP_NO_256
2590
   if (mp_count_bits(modulus) == 256) {
2591
       return sp_ecc_map_256(P->x, P->y, P->z);
2592
   }
2593
#endif
2594
#ifdef WOLFSSL_SP_384
2595
   if (mp_count_bits(modulus) == 384) {
2596
       return sp_ecc_map_384(P->x, P->y, P->z);
2597
   }
2598
#endif
2599
#ifdef WOLFSSL_SP_521
2600
   if (mp_count_bits(modulus) == 521) {
2601
       return sp_ecc_map_521(P->x, P->y, P->z);
2602
   }
2603
#endif
2604
   return ECC_BAD_ARG_E;
2605
#endif
2606
0
}
2607
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2608
2609
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2610
0
{
2611
0
    return ecc_map_ex(P, modulus, mp, 0);
2612
0
}
2613
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2614
2615
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2616
    !defined(WOLFSSL_CRYPTOCELL)
2617
#if !defined(WOLFSSL_SP_MATH)
2618
2619
#ifndef ECC_TIMING_RESISTANT
2620
2621
/* size of sliding window, don't change this! */
2622
#define WINSIZE  4
2623
#define M_POINTS 8
2624
2625
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2626
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2627
{
2628
   int      err = MP_OKAY;
2629
   int      i;
2630
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2631
   int      bitcnt = 0, mode = 0, digidx = 0;
2632
   mp_digit buf;
2633
   int      infinity;
2634
2635
   (void)rng;
2636
2637
   /* calc the M tab, which holds kG for k==8..15 */
2638
   /* M[0] == 8G */
2639
   if (err == MP_OKAY)
2640
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2641
   if (err == MP_OKAY)
2642
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2643
   if (err == MP_OKAY)
2644
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2645
2646
   /* now find (8+k)G for k=1..7 */
2647
   if (err == MP_OKAY)
2648
       for (j = 9; j < 16; j++) {
2649
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2650
                                                        modulus, mp, &infinity);
2651
           if (err != MP_OKAY) break;
2652
       }
2653
2654
   /* setup sliding window */
2655
   if (err == MP_OKAY) {
2656
       mode   = 0;
2657
       bitcnt = 1;
2658
       buf    = 0;
2659
       digidx = get_digit_count(k) - 1;
2660
       bitcpy = bitbuf = 0;
2661
       first  = 1;
2662
2663
       /* perform ops */
2664
       for (;;) {
2665
           /* grab next digit as required */
2666
           if (--bitcnt == 0) {
2667
               if (digidx == -1) {
2668
                   break;
2669
               }
2670
               buf    = get_digit(k, digidx);
2671
               bitcnt = (int) DIGIT_BIT;
2672
               --digidx;
2673
           }
2674
2675
           /* grab the next msb from the ltiplicand */
2676
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
2677
           buf <<= 1;
2678
2679
           /* skip leading zero bits */
2680
           if (mode == 0 && i == 0)
2681
               continue;
2682
2683
           /* if the bit is zero and mode == 1 then we double */
2684
           if (mode == 1 && i == 0) {
2685
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
2686
               if (err != MP_OKAY) break;
2687
               continue;
2688
           }
2689
2690
           /* else we add it to the window */
2691
           bitbuf |= (i << (WINSIZE - ++bitcpy));
2692
           mode = 2;
2693
2694
           if (bitcpy == WINSIZE) {
2695
               /* if this is the first window we do a simple copy */
2696
               if (first == 1) {
2697
                   /* R = kG [k = first window] */
2698
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
2699
                   if (err != MP_OKAY) break;
2700
2701
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
2702
                   if (err != MP_OKAY) break;
2703
2704
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
2705
                   first = 0;
2706
               } else {
2707
                   /* normal window */
2708
                   /* ok window is filled so double as required and add  */
2709
                   /* double first */
2710
                   for (j = 0; j < WINSIZE; j++) {
2711
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
2712
                                                                            mp);
2713
                       if (err != MP_OKAY) break;
2714
                   }
2715
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
2716
2717
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
2718
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
2719
                                                     a, modulus, mp, &infinity);
2720
               }
2721
               if (err != MP_OKAY) break;
2722
               /* empty window and reset */
2723
               bitcpy = bitbuf = 0;
2724
               mode = 1;
2725
           }
2726
       }
2727
   }
2728
2729
   /* if bits remain then double/add */
2730
   if (err == MP_OKAY) {
2731
       if (mode == 2 && bitcpy > 0) {
2732
           /* double then add */
2733
           for (j = 0; j < bitcpy; j++) {
2734
               /* only double if we have had at least one add first */
2735
               if (first == 0) {
2736
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
2737
                   if (err != MP_OKAY) break;
2738
               }
2739
2740
               bitbuf <<= 1;
2741
               if ((bitbuf & (1 << WINSIZE)) != 0) {
2742
                   if (first == 1) {
2743
                       /* first add, so copy */
2744
                       err = mp_copy(tG->x, R->x);
2745
                       if (err != MP_OKAY) break;
2746
2747
                       err = mp_copy(tG->y, R->y);
2748
                       if (err != MP_OKAY) break;
2749
2750
                       err = mp_copy(tG->z, R->z);
2751
                       if (err != MP_OKAY) break;
2752
                       first = 0;
2753
                   } else {
2754
                       /* then add */
2755
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
2756
                                                                 mp, &infinity);
2757
                       if (err != MP_OKAY) break;
2758
                   }
2759
               }
2760
           }
2761
       }
2762
   }
2763
2764
   #undef WINSIZE
2765
2766
   return err;
2767
}
2768
2769
#else
2770
2771
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p,
2772
        mp_int* modulus, mp_digit mp, mp_int* tx, mp_int* ty)
2773
0
{
2774
0
    int err = MP_OKAY;
2775
0
#ifdef WOLFSSL_SMALL_STACK
2776
0
    mp_int*       mu = NULL;
2777
#else
2778
    mp_int        mu[1];
2779
#endif
2780
2781
0
#ifdef WOLFSSL_SMALL_STACK
2782
0
    mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2783
0
    if (mu == NULL)
2784
0
        err = MEMORY_E;
2785
0
#endif
2786
2787
0
    if (err == MP_OKAY)
2788
0
        err = mp_init(mu);
2789
0
    if (err == MP_OKAY)
2790
0
        err = mp_montgomery_calc_normalization(mu, modulus);
2791
    /* Generate random value to multiply into p->z. */
2792
0
    if (err == MP_OKAY)
2793
0
        err = wc_ecc_gen_k(rng, size, ty, modulus);
2794
    /* Convert to montogmery form. */
2795
0
    if (err == MP_OKAY)
2796
0
        err = mp_mulmod(ty, mu, modulus, ty);
2797
    /* Multiply random value into p->z. */
2798
0
    if (err == MP_OKAY)
2799
0
        err = mp_mul(p->z, ty, p->z);
2800
0
    if (err == MP_OKAY)
2801
0
        err = mp_montgomery_reduce(p->z, modulus, mp);
2802
    /* Square random value for X (X' = X / Z^2). */
2803
0
    if (err == MP_OKAY)
2804
0
        err = mp_sqr(ty, tx);
2805
0
    if (err == MP_OKAY)
2806
0
        err = mp_montgomery_reduce(tx, modulus, mp);
2807
    /* Multiply square of random by random value for Y. */
2808
0
    if (err == MP_OKAY)
2809
0
        err = mp_mul(ty, tx, ty);
2810
0
    if (err == MP_OKAY)
2811
0
        err = mp_montgomery_reduce(ty, modulus, mp);
2812
    /* Multiply square into X. */
2813
0
    if (err == MP_OKAY)
2814
0
        err = mp_mul(p->x, tx, p->x);
2815
0
    if (err == MP_OKAY)
2816
0
        err = mp_montgomery_reduce(p->x, modulus, mp);
2817
    /* Multiply cube into Y (Y' = Y / Z^3). */
2818
0
    if (err == MP_OKAY)
2819
0
        err = mp_mul(p->y, ty, p->y);
2820
0
    if (err == MP_OKAY)
2821
0
        err = mp_montgomery_reduce(p->y, modulus, mp);
2822
2823
0
#ifdef WOLFSSL_SMALL_STACK
2824
0
    if (mu != NULL) {
2825
0
        mp_clear(mu);
2826
0
        XFREE(mu, NULL, DYNAMIC_TYPE_ECC);
2827
0
    }
2828
#else
2829
    mp_clear(mu);
2830
#endif
2831
2832
0
    return err;
2833
0
}
2834
2835
#ifndef WC_PROTECT_ENCRYPTED_MEM
2836
0
#define M_POINTS 3
2837
2838
/* Joye double-add ladder.
2839
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
2840
 * by Marc Joye (2007)
2841
 *
2842
 * Algorithm 1':
2843
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
2844
 *   Output: Q = kP
2845
 *   1: R[0] = P; R[1] = P
2846
 *   2: for j = 1 to t-1 do
2847
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
2848
 *   4: end for
2849
 *   5: b = k[0]; R[b] = R[b] - P
2850
 *   6: return R[0]
2851
 *
2852
 * Assumes: k < order.
2853
 */
2854
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
2855
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2856
0
{
2857
0
    int      err = MP_OKAY;
2858
0
    int      bytes = (mp_count_bits(modulus) + 7) / 8;
2859
0
    int      i;
2860
0
    int      j = 1;
2861
0
    int      cnt = DIGIT_BIT;
2862
0
    int      t = 0;
2863
0
    mp_digit b;
2864
0
    mp_digit v = 0;
2865
0
    mp_int*  kt = R[2]->x;
2866
0
#ifndef WC_NO_CACHE_RESISTANT
2867
    /* First bit always 1 (fix at end) and swap equals first bit */
2868
0
    int      swap = 1;
2869
0
#endif
2870
0
    int      infinity;
2871
2872
    /* Step 1: R[0] = P; R[1] = P */
2873
    /* R[0] = P */
2874
0
    if (err == MP_OKAY)
2875
0
        err = mp_copy(P->x, R[0]->x);
2876
0
    if (err == MP_OKAY)
2877
0
        err = mp_copy(P->y, R[0]->y);
2878
0
    if (err == MP_OKAY)
2879
0
        err = mp_copy(P->z, R[0]->z);
2880
2881
    /* R[1] = P */
2882
0
    if (err == MP_OKAY)
2883
0
        err = mp_copy(P->x, R[1]->x);
2884
0
    if (err == MP_OKAY)
2885
0
        err = mp_copy(P->y, R[1]->y);
2886
0
    if (err == MP_OKAY)
2887
0
        err = mp_copy(P->z, R[1]->z);
2888
2889
    /* Randomize z ordinates to obfuscate timing. */
2890
0
    if ((err == MP_OKAY) && (rng != NULL))
2891
0
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y);
2892
0
    if ((err == MP_OKAY) && (rng != NULL))
2893
0
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y);
2894
2895
0
    if (err == MP_OKAY) {
2896
        /* Order could be one greater than the size of the modulus. */
2897
0
        t = mp_count_bits(modulus) + 1;
2898
0
        v = k->dp[0] >> 1;
2899
0
        if (cnt > t) {
2900
0
            cnt = t;
2901
0
        }
2902
0
        err = mp_copy(k, kt);
2903
0
    }
2904
0
    if (err == MP_OKAY) {
2905
0
        err = mp_grow(kt, modulus->used + 1);
2906
0
    }
2907
    /* Step 2: for j = 1 to t-1 do */
2908
0
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
2909
0
        if (--cnt == 0) {
2910
0
            v = kt->dp[j++];
2911
0
            cnt = DIGIT_BIT;
2912
0
        }
2913
2914
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
2915
0
        b = v & 1;
2916
0
        v >>= 1;
2917
#ifdef WC_NO_CACHE_RESISTANT
2918
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
2919
        if (err == MP_OKAY) {
2920
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
2921
                                                        modulus, mp, &infinity);
2922
        }
2923
#else
2924
        /* Swap R[0] and R[1] if other index is needed. */
2925
0
        swap ^= b;
2926
0
        if (err == MP_OKAY)
2927
0
            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
2928
0
        if (err == MP_OKAY)
2929
0
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
2930
0
        if (err == MP_OKAY)
2931
0
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
2932
0
        swap = (int)b;
2933
2934
0
        if (err == MP_OKAY)
2935
0
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
2936
0
        if (err == MP_OKAY) {
2937
0
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
2938
0
                                                                 mp, &infinity);
2939
0
        }
2940
0
#endif /* WC_NO_CACHE_RESISTANT */
2941
0
    }
2942
    /* Step 4: end for */
2943
0
#ifndef WC_NO_CACHE_RESISTANT
2944
    /* Swap back if last bit is 0. */
2945
0
    swap ^= 1;
2946
0
    if (err == MP_OKAY)
2947
0
        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
2948
0
    if (err == MP_OKAY)
2949
0
        err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
2950
0
    if (err == MP_OKAY)
2951
0
        err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
2952
0
#endif
2953
2954
    /* Step 5: b = k[0]; R[b] = R[b] - P */
2955
    /* R[2] = -P */
2956
0
    if (err == MP_OKAY)
2957
0
        err = mp_copy(P->x, R[2]->x);
2958
0
    if (err == MP_OKAY)
2959
0
        err = mp_sub(modulus, P->y, R[2]->y);
2960
0
    if (err == MP_OKAY)
2961
0
        err = mp_copy(P->z, R[2]->z);
2962
    /* Subtract point by adding negative. */
2963
0
    if (err == MP_OKAY) {
2964
0
        b = k->dp[0] & 1;
2965
#ifdef WC_NO_CACHE_RESISTANT
2966
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
2967
                                                                     &infinity);
2968
#else
2969
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
2970
0
        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
2971
0
        if (err == MP_OKAY)
2972
0
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
2973
0
        if (err == MP_OKAY)
2974
0
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
2975
0
        if (err == MP_OKAY)
2976
0
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
2977
0
                                                                 mp, &infinity);
2978
        /* Swap back if necessary. */
2979
0
        if (err == MP_OKAY)
2980
0
            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
2981
0
        if (err == MP_OKAY)
2982
0
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
2983
0
        if (err == MP_OKAY)
2984
0
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
2985
0
#endif
2986
0
    }
2987
2988
    /* Step 6: return R[0] */
2989
0
    if (err == MP_OKAY)
2990
0
        err = mp_copy(R[0]->x, Q->x);
2991
0
    if (err == MP_OKAY)
2992
0
        err = mp_copy(R[0]->y, Q->y);
2993
0
    if (err == MP_OKAY)
2994
0
        err = mp_copy(R[0]->z, Q->z);
2995
2996
0
    return err;
2997
0
}
2998
2999
#else
3000
/* Number of points to allocate for use during scalar multiplication. */
3001
#define M_POINTS        5
3002
/* Last of the points is used as a temporary during calculations. */
3003
#define TMP_IDX         M_POINTS - 1
3004
3005
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3006
    int digits, int m)
3007
{
3008
    int i;
3009
3010
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3011
    /* Only using positive numbers in ECC operations. */
3012
    ra->sign = 0;
3013
    rb->sign = 0;
3014
#endif
3015
    /* Don't store 0 when mask is 0, it will be in a register. */
3016
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3017
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3018
    for (i = 0; i < digits; i++) {
3019
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3020
                    a->dp[i];
3021
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3022
                    b->dp[i];
3023
    }
3024
}
3025
3026
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3027
    ecc_point* b, int digits, int m)
3028
{
3029
    /* Conditionally swap each ordinate. */
3030
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3031
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3032
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3033
}
3034
3035
/* Joye double-add ladder.
3036
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3037
 * by Marc Joye (2007)
3038
 *
3039
 * Algorithm 1':
3040
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3041
 *   Output: Q = kP
3042
 *   1: R[0] = P; R[1] = P
3043
 *   2: for j = 1 to t-1 do
3044
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3045
 *   4: end for
3046
 *   5: b = k[0]; R[b] = R[b] - P
3047
 *   6: return R[0]
3048
 *
3049
 * Assumes: k < order.
3050
 */
3051
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3052
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3053
{
3054
    int          err = MP_OKAY;
3055
    int          bytes = (mp_count_bits(modulus) + 7) / 8;
3056
    int          i;
3057
    int          j = 1;
3058
    int          cnt;
3059
    int          t = 0;
3060
    mp_int*      kt = R[TMP_IDX]->x;
3061
    /* First bit always 1 (fix at end) and swap equals first bit */
3062
    register int swap = 1;
3063
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3064
    int          set = 0;
3065
    int          infinity;
3066
3067
    /* Step 1: R[0] = P; R[1] = P */
3068
    /* R[0] = P */
3069
    if (err == MP_OKAY)
3070
        err = mp_copy(P->x, R[0]->x);
3071
    if (err == MP_OKAY)
3072
        err = mp_copy(P->y, R[0]->y);
3073
    if (err == MP_OKAY)
3074
        err = mp_copy(P->z, R[0]->z);
3075
3076
    /* R[1] = P */
3077
    if (err == MP_OKAY)
3078
        err = mp_copy(P->x, R[1]->x);
3079
    if (err == MP_OKAY)
3080
        err = mp_copy(P->y, R[1]->y);
3081
    if (err == MP_OKAY)
3082
        err = mp_copy(P->z, R[1]->z);
3083
3084
    /* Randomize z ordinates to obfuscate timing. */
3085
    if ((err == MP_OKAY) && (rng != NULL))
3086
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3087
                           R[TMP_IDX]->y);
3088
    if ((err == MP_OKAY) && (rng != NULL))
3089
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3090
                           R[TMP_IDX]->y);
3091
3092
    if (err == MP_OKAY) {
3093
        /* Order could be one greater than the size of the modulus. */
3094
        t = mp_count_bits(modulus) + 1;
3095
        err = mp_copy(k, kt);
3096
    }
3097
    if (err == MP_OKAY) {
3098
        err = mp_grow(kt, modulus->used + 1);
3099
    }
3100
    /* Step 2: for j = 1 to t-1 do */
3101
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3102
        if (++cnt == DIGIT_BIT) {
3103
            j++;
3104
            cnt = 0;
3105
        }
3106
3107
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3108
        /* Swap R[0] and R[1] if other index is needed. */
3109
        /* Ensure 'swap' changes when shifted word is 0. */
3110
        swap += (kt->dp[j] >> cnt) + 2;
3111
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3112
                              R[set + 0], R[set + 1], modulus->used, swap);
3113
        /* Change to operate on set copied into. */
3114
        set = 2 - set;
3115
        /* Ensure 'swap' changes to a previously unseen value. */
3116
        swap += (kt->dp[j] >> cnt) + swap;
3117
3118
        /* R[0] = 2*R[0] */
3119
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3120
                                            mp);
3121
        if (err == MP_OKAY) {
3122
            /* R[0] = R[1] + R[0] */
3123
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3124
                                         R[set + 0], a, modulus, mp, &infinity);
3125
        }
3126
        /*  R[1]->z * 2 - same point. */
3127
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3128
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3129
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3130
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3131
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3132
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3133
    }
3134
    /* Step 4: end for */
3135
    /* Swap back if last bit is 0. */
3136
    /* Ensure 'swap' changes. */
3137
    swap += 1;
3138
    if (err == MP_OKAY) {
3139
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3140
                              R[set + 0], R[set + 1], modulus->used, swap);
3141
        set = 2 - set;
3142
    }
3143
3144
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3145
    /* R[TMP_IDX] = -P */
3146
    if (err == MP_OKAY)
3147
        err = mp_copy(P->x, R[TMP_IDX]->x);
3148
    if (err == MP_OKAY)
3149
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3150
    if (err == MP_OKAY)
3151
        err = mp_copy(P->z, R[TMP_IDX]->z);
3152
    /* Subtract point by adding negative. */
3153
    if (err == MP_OKAY) {
3154
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3155
         * Last bit of k->dp[0] is being used to make decision to swap.
3156
         */
3157
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3158
                              R[set + 0], R[set + 1], modulus->used,
3159
                              (int)k->dp[0]);
3160
        set = 2 - set;
3161
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3162
                                            a, modulus, mp, &infinity);
3163
        /* Swap back if necessary. */
3164
        if (err == MP_OKAY) {
3165
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3166
                                  R[set + 0], R[set + 1], modulus->used,
3167
                                  (int)k->dp[0]);
3168
            set = 2 - set;
3169
        }
3170
    }
3171
3172
    /* Step 6: return R[0] */
3173
    if (err == MP_OKAY)
3174
        err = mp_copy(R[set + 0]->x, Q->x);
3175
    if (err == MP_OKAY)
3176
        err = mp_copy(R[set + 0]->y, Q->y);
3177
    if (err == MP_OKAY)
3178
        err = mp_copy(R[set + 0]->z, Q->z);
3179
3180
    return err;
3181
}
3182
3183
#endif
3184
3185
#endif
3186
3187
/* Convert the point to montgomery form.
3188
 *
3189
 * @param  [in]   p        Point to convert.
3190
 * @param  [out]  r        Point in montgomery form.
3191
 * @param  [in]   modulus  Modulus of ordinates.
3192
 * @return  0 on success.
3193
 * @return  -ve on failure.
3194
 */
3195
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3196
                             void* heap)
3197
0
{
3198
0
   int err = MP_OKAY;
3199
0
#ifdef WOLFSSL_SMALL_STACK
3200
0
   mp_int*       mu = NULL;
3201
#else
3202
   mp_int        mu[1];
3203
#endif
3204
3205
0
   (void)heap;
3206
3207
0
#ifdef WOLFSSL_SMALL_STACK
3208
0
   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3209
0
   if (mu == NULL)
3210
0
       err = MEMORY_E;
3211
0
#endif
3212
0
   if (err == MP_OKAY)
3213
0
       err = mp_init(mu);
3214
0
   if (err == MP_OKAY) {
3215
0
       err = mp_montgomery_calc_normalization(mu, modulus);
3216
3217
0
       if (err == MP_OKAY) {
3218
0
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3219
0
               err = mp_copy(p->x, r->x);
3220
0
               if (err == MP_OKAY)
3221
0
                   err = mp_copy(p->y, r->y);
3222
0
               if (err == MP_OKAY)
3223
0
                   err = mp_copy(p->z, r->z);
3224
0
           }
3225
0
           else {
3226
0
               err = mp_mulmod(p->x, mu, modulus, r->x);
3227
0
               if (err == MP_OKAY)
3228
0
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3229
0
               if (err == MP_OKAY)
3230
0
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3231
0
           }
3232
0
       }
3233
3234
0
       mp_clear(mu);
3235
0
   }
3236
0
#ifdef WOLFSSL_SMALL_STACK
3237
0
   if (mu != NULL)
3238
0
      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
3239
0
#endif
3240
0
   return err;
3241
0
}
3242
3243
#ifdef WOLFSSL_SMALL_STACK_CACHE
3244
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3245
{
3246
   int err = MP_OKAY;
3247
3248
   XMEMSET(key, 0, sizeof(*key));
3249
3250
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3251
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3252
#ifdef ALT_ECC_SIZE
3253
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3254
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3255
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3256
#endif
3257
   if (key->t1 == NULL || key->t2 == NULL
3258
#ifdef ALT_ECC_SIZE
3259
      || key->x == NULL || key->y == NULL || key->z == NULL
3260
#endif
3261
   ) {
3262
       err = MEMORY_E;
3263
   }
3264
3265
   return err;
3266
}
3267
3268
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3269
{
3270
    (void)heap;
3271
#ifdef ALT_ECC_SIZE
3272
   if (key->z != NULL)
3273
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3274
   if (key->y != NULL)
3275
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3276
   if (key->x != NULL)
3277
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3278
#endif
3279
   if (key->t2 != NULL)
3280
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3281
   if (key->t1 != NULL)
3282
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3283
}
3284
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3285
#endif /* !WOLFSSL_SP_MATH */
3286
3287
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3288
/**
3289
   Perform a point multiplication
3290
   k    The scalar to multiply by
3291
   G    The base point
3292
   R    [out] Destination for kG
3293
   a    ECC curve parameter a
3294
   modulus  The modulus of the field the ECC curve is in
3295
   map      Boolean whether to map back to affine or not
3296
                (1==map, 0 == leave in projective)
3297
   return MP_OKAY on success
3298
*/
3299
#ifdef FP_ECC
3300
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3301
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3302
                             void* heap)
3303
#else
3304
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3305
                     mp_int* modulus, int map, void* heap)
3306
#endif
3307
#if !defined(WOLFSSL_SP_MATH)
3308
0
{
3309
0
   ecc_point     *tG, *M[M_POINTS];
3310
#ifdef WOLFSSL_NO_MALLOC
3311
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3312
#endif
3313
0
   int           i, err;
3314
#ifdef WOLFSSL_SMALL_STACK_CACHE
3315
   ecc_key       *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3316
#endif
3317
0
   mp_digit      mp;
3318
3319
   /* init variables */
3320
0
   tG = NULL;
3321
0
   XMEMSET(M, 0, sizeof(M));
3322
3323
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3324
0
       err = ECC_BAD_ARG_E;
3325
0
       goto exit;
3326
0
   }
3327
3328
   /* k can't have more bits than modulus count plus 1 */
3329
0
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3330
0
       err = ECC_OUT_OF_RANGE_E;
3331
0
       goto exit;
3332
0
   }
3333
3334
#ifdef WOLFSSL_SMALL_STACK_CACHE
3335
   if (key == NULL) {
3336
       err = MP_MEM;
3337
       goto exit;
3338
   }
3339
   err = ecc_key_tmp_init(key, heap);
3340
   if (err != MP_OKAY)
3341
      goto exit;
3342
   R->key = key;
3343
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3344
3345
  /* alloc ram for window temps */
3346
0
  for (i = 0; i < M_POINTS; i++) {
3347
  #ifdef WOLFSSL_NO_MALLOC
3348
      M[i] = &lcl_M[i];
3349
  #endif
3350
0
      err = wc_ecc_new_point_ex(&M[i], heap);
3351
0
      if (err != MP_OKAY) {
3352
0
         goto exit;
3353
0
      }
3354
#ifdef WOLFSSL_SMALL_STACK_CACHE
3355
      M[i]->key = key;
3356
#endif
3357
0
  }
3358
3359
   /* make a copy of G in case R==G */
3360
#ifdef WOLFSSL_NO_MALLOC
3361
   tG = &lcl_tG;
3362
#endif
3363
0
   err = wc_ecc_new_point_ex(&tG, heap);
3364
0
   if (err != MP_OKAY) {
3365
0
       goto exit;
3366
0
   }
3367
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3368
0
       goto exit;
3369
0
   }
3370
3371
   /* init montgomery reduction */
3372
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3373
0
       goto exit;
3374
0
   }
3375
3376
#ifdef FP_ECC
3377
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3378
#else
3379
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3380
0
#endif
3381
   /* map R back from projective space */
3382
0
   if (err == MP_OKAY && map)
3383
0
       err = ecc_map(R, modulus, mp);
3384
3385
0
exit:
3386
3387
   /* done */
3388
0
   wc_ecc_del_point_ex(tG, heap);
3389
0
   for (i = 0; i < M_POINTS; i++) {
3390
0
       wc_ecc_del_point_ex(M[i], heap);
3391
0
   }
3392
3393
#ifdef WOLFSSL_SMALL_STACK_CACHE
3394
   if (key) {
3395
       if (R)
3396
           R->key = NULL;
3397
       if (err == MP_OKAY)
3398
           ecc_key_tmp_final(key, heap);
3399
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3400
   }
3401
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3402
3403
0
   return err;
3404
0
}
3405
#else
3406
{
3407
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3408
       return ECC_BAD_ARG_E;
3409
   }
3410
3411
   (void)a;
3412
3413
   /* k can't have more bits than modulus count plus 1 */
3414
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3415
       return ECC_OUT_OF_RANGE_E;
3416
   }
3417
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3418
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3419
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3420
       return IS_POINT_E;
3421
   }
3422
3423
#ifdef WOLFSSL_HAVE_SP_ECC
3424
#ifndef WOLFSSL_SP_NO_256
3425
   if (mp_count_bits(modulus) == 256) {
3426
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3427
   }
3428
#endif
3429
#ifdef WOLFSSL_SP_384
3430
   if (mp_count_bits(modulus) == 384) {
3431
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3432
   }
3433
#endif
3434
#ifdef WOLFSSL_SP_521
3435
   if (mp_count_bits(modulus) == 521) {
3436
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3437
   }
3438
#endif
3439
#else
3440
   (void)map;
3441
   (void)map;
3442
   (void)heap;
3443
#endif
3444
   return ECC_BAD_ARG_E;
3445
}
3446
#endif
3447
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3448
3449
#ifndef FP_ECC
3450
/**
3451
   Perform a point multiplication
3452
   k    The scalar to multiply by
3453
   G    The base point
3454
   R    [out] Destination for kG
3455
   a    ECC curve parameter a
3456
   modulus  The modulus of the field the ECC curve is in
3457
   map      Boolean whether to map back to affine or not
3458
                (1==map, 0 == leave in projective)
3459
   return MP_OKAY on success
3460
*/
3461
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3462
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3463
                      void* heap)
3464
#if !defined(WOLFSSL_SP_MATH)
3465
0
{
3466
0
   ecc_point     *tG, *M[M_POINTS];
3467
#ifdef WOLFSSL_NO_MALLOC
3468
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3469
#endif
3470
0
   int           i, err;
3471
#ifdef WOLFSSL_SMALL_STACK_CACHE
3472
   ecc_key       key;
3473
#endif
3474
0
   mp_digit      mp;
3475
0
#ifdef ECC_TIMING_RESISTANT
3476
0
   mp_int t;
3477
0
#endif
3478
3479
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3480
0
      return ECC_BAD_ARG_E;
3481
0
   }
3482
3483
   /* k can't have more bits than order */
3484
0
   if (mp_count_bits(k) > mp_count_bits(order)) {
3485
0
      return ECC_OUT_OF_RANGE_E;
3486
0
   }
3487
3488
   /* init variables */
3489
0
   tG = NULL;
3490
0
   XMEMSET(M, 0, sizeof(M));
3491
3492
#ifdef WOLFSSL_SMALL_STACK_CACHE
3493
   err = ecc_key_tmp_init(&key, heap);
3494
   if (err != MP_OKAY)
3495
      goto exit;
3496
   R->key = &key;
3497
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3498
3499
   /* alloc ram for window temps */
3500
0
   for (i = 0; i < M_POINTS; i++) {
3501
   #ifdef WOLFSSL_NO_MALLOC
3502
      M[i] = &lcl_M[i];
3503
   #endif
3504
0
      err = wc_ecc_new_point_ex(&M[i], heap);
3505
0
      if (err != MP_OKAY) {
3506
0
         goto exit;
3507
0
      }
3508
#ifdef WOLFSSL_SMALL_STACK_CACHE
3509
      M[i]->key = &key;
3510
#endif
3511
0
  }
3512
3513
   /* make a copy of G in case R==G */
3514
#ifdef WOLFSSL_NO_MALLOC
3515
   tG = &lcl_tG;
3516
#endif
3517
0
   err = wc_ecc_new_point_ex(&tG, heap);
3518
0
   if (err != MP_OKAY) {
3519
0
       goto exit;
3520
0
   }
3521
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3522
0
       goto exit;
3523
0
   }
3524
3525
   /* init montgomery reduction */
3526
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3527
0
      goto exit;
3528
0
   }
3529
3530
   /* k can't have more bits than order */
3531
0
   if (mp_count_bits(k) > mp_count_bits(order)) {
3532
0
      err = ECC_OUT_OF_RANGE_E;
3533
0
      goto exit;
3534
0
   }
3535
3536
3537
0
#ifdef ECC_TIMING_RESISTANT
3538
0
   if ((err = mp_init(&t)) != MP_OKAY)
3539
0
      goto exit;
3540
3541
0
   if (err == MP_OKAY)
3542
0
      err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3543
3544
    /* Check for k == order - 1. Result will be 0 point which is not correct
3545
     * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3546
     * (with constant time implementation)
3547
     */
3548
0
   if (err == MP_OKAY)
3549
0
      err = mp_sub_d(order, 1, &t);
3550
0
   if (err == MP_OKAY) {
3551
0
      int kIsMinusOne = (mp_cmp((mp_int*)k, &t) == MP_EQ);
3552
0
      err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3553
0
      if (err == MP_OKAY) {
3554
0
          err = mp_sub(modulus, tG->y, &t);
3555
0
      }
3556
0
      if (err == MP_OKAY) {
3557
0
          err = mp_cond_copy(&t, kIsMinusOne, R->y);
3558
0
      }
3559
0
      if (err == MP_OKAY) {
3560
0
          err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3561
0
      }
3562
0
   }
3563
3564
0
   mp_free(&t);
3565
#else
3566
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3567
3568
   (void)order;
3569
#endif
3570
   /* map R back from projective space */
3571
0
   if (err == MP_OKAY && map)
3572
0
      err = ecc_map(R, modulus, mp);
3573
3574
0
exit:
3575
3576
   /* done */
3577
0
   wc_ecc_del_point_ex(tG, heap);
3578
0
   for (i = 0; i < M_POINTS; i++) {
3579
0
      wc_ecc_del_point_ex(M[i], heap);
3580
0
   }
3581
#ifdef WOLFSSL_SMALL_STACK_CACHE
3582
   R->key = NULL;
3583
   ecc_key_tmp_final(&key, heap);
3584
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3585
3586
0
   return err;
3587
0
}
3588
#else
3589
{
3590
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3591
       return ECC_BAD_ARG_E;
3592
   }
3593
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3594
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3595
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3596
       return IS_POINT_E;
3597
   }
3598
3599
   (void)a;
3600
   (void)order;
3601
   (void)rng;
3602
3603
#ifdef WOLFSSL_HAVE_SP_ECC
3604
#ifndef WOLFSSL_SP_NO_256
3605
   if (mp_count_bits(modulus) == 256) {
3606
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3607
   }
3608
#endif
3609
#ifdef WOLFSSL_SP_384
3610
   if (mp_count_bits(modulus) == 384) {
3611
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3612
   }
3613
#endif
3614
#ifdef WOLFSSL_SP_521
3615
   if (mp_count_bits(modulus) == 521) {
3616
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3617
   }
3618
#endif
3619
#else
3620
   (void)map;
3621
   (void)heap;
3622
#endif
3623
   return ECC_BAD_ARG_E;
3624
}
3625
#endif /* !WOLFSSL_SP_MATH */
3626
#endif /* !FP_ECC */
3627
3628
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
3629
3630
/** ECC Fixed Point mulmod global
3631
    k        The multiplicand
3632
    G        Base point to multiply
3633
    R        [out] Destination of product
3634
    a        ECC curve parameter a
3635
    modulus  The modulus for the curve
3636
    map      [boolean] If non-zero maps the point back to affine coordinates,
3637
             otherwise it's left in jacobian-montgomery form
3638
    return MP_OKAY if successful
3639
*/
3640
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3641
                  mp_int* modulus, int map)
3642
0
{
3643
0
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
3644
0
}
3645
3646
#endif /* !WOLFSSL_ATECC508A */
3647
3648
/**
3649
 * Allocate a new ECC point (if one not provided)
3650
 * use a heap hint when creating new ecc_point
3651
 * return an allocated point on success or NULL on failure
3652
*/
3653
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
3654
0
{
3655
0
   int err = MP_OKAY;
3656
0
   ecc_point* p;
3657
3658
0
   if (point == NULL) {
3659
0
       return BAD_FUNC_ARG;
3660
0
   }
3661
3662
0
   p = *point;
3663
0
#ifndef WOLFSSL_NO_MALLOC
3664
0
   if (p == NULL) {
3665
0
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
3666
0
   }
3667
0
#endif
3668
0
   if (p == NULL) {
3669
0
      return MEMORY_E;
3670
0
   }
3671
0
   XMEMSET(p, 0, sizeof(ecc_point));
3672
3673
0
#ifndef ALT_ECC_SIZE
3674
0
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
3675
0
   if (err != MP_OKAY) {
3676
0
   #ifndef WOLFSSL_NO_MALLOC
3677
0
      XFREE(p, heap, DYNAMIC_TYPE_ECC);
3678
0
   #endif
3679
0
      return err;
3680
0
   }
3681
#else
3682
   p->x = (mp_int*)&p->xyz[0];
3683
   p->y = (mp_int*)&p->xyz[1];
3684
   p->z = (mp_int*)&p->xyz[2];
3685
   alt_fp_init(p->x);
3686
   alt_fp_init(p->y);
3687
   alt_fp_init(p->z);
3688
#endif
3689
3690
0
   *point = p;
3691
0
   (void)heap;
3692
0
   return err;
3693
0
}
3694
ecc_point* wc_ecc_new_point_h(void* heap)
3695
0
{
3696
0
    ecc_point* p = NULL;
3697
0
    (void)wc_ecc_new_point_ex(&p, heap);
3698
0
    return p;
3699
0
}
3700
ecc_point* wc_ecc_new_point(void)
3701
0
{
3702
0
   ecc_point* p = NULL;
3703
0
   (void)wc_ecc_new_point_ex(&p, NULL);
3704
0
   return p;
3705
0
}
3706
3707
/** Free an ECC point from memory
3708
  p   The point to free
3709
*/
3710
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
3711
0
{
3712
0
   if (p != NULL) {
3713
0
      mp_clear(p->x);
3714
0
      mp_clear(p->y);
3715
0
      mp_clear(p->z);
3716
0
   #ifndef WOLFSSL_NO_MALLOC
3717
0
      XFREE(p, heap, DYNAMIC_TYPE_ECC);
3718
0
   #endif
3719
0
   }
3720
0
   (void)heap;
3721
0
}
3722
void wc_ecc_del_point_h(ecc_point* p, void* heap)
3723
0
{
3724
0
   wc_ecc_del_point_ex(p, heap);
3725
0
}
3726
void wc_ecc_del_point(ecc_point* p)
3727
0
{
3728
0
    wc_ecc_del_point_ex(p, NULL);
3729
0
}
3730
3731
void wc_ecc_forcezero_point(ecc_point* p)
3732
0
{
3733
0
    if (p != NULL) {
3734
0
        mp_forcezero(p->x);
3735
0
        mp_forcezero(p->y);
3736
0
        mp_forcezero(p->z);
3737
0
    }
3738
0
}
3739
3740
3741
/** Copy the value of a point to an other one
3742
  p    The point to copy
3743
  r    The created point
3744
*/
3745
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
3746
0
{
3747
0
    int ret;
3748
3749
    /* prevents null arguments */
3750
0
    if (p == NULL || r == NULL)
3751
0
        return ECC_BAD_ARG_E;
3752
3753
0
    ret = mp_copy(p->x, r->x);
3754
0
    if (ret != MP_OKAY)
3755
0
        return ret;
3756
0
    ret = mp_copy(p->y, r->y);
3757
0
    if (ret != MP_OKAY)
3758
0
        return ret;
3759
0
    ret = mp_copy(p->z, r->z);
3760
0
    if (ret != MP_OKAY)
3761
0
        return ret;
3762
3763
0
    return MP_OKAY;
3764
0
}
3765
3766
/** Compare the value of a point with an other one
3767
 a    The point to compare
3768
 b    The other point to compare
3769
3770
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
3771
 */
3772
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
3773
0
{
3774
0
    int ret;
3775
3776
    /* prevents null arguments */
3777
0
    if (a == NULL || b == NULL)
3778
0
        return BAD_FUNC_ARG;
3779
3780
0
    ret = mp_cmp(a->x, b->x);
3781
0
    if (ret != MP_EQ)
3782
0
        return ret;
3783
0
    ret = mp_cmp(a->y, b->y);
3784
0
    if (ret != MP_EQ)
3785
0
        return ret;
3786
0
    ret = mp_cmp(a->z, b->z);
3787
0
    if (ret != MP_EQ)
3788
0
        return ret;
3789
3790
0
    return MP_EQ;
3791
0
}
3792
3793
3794
/** Returns whether an ECC idx is valid or not
3795
  n      The idx number to check
3796
  return 1 if valid, 0 if not
3797
*/
3798
int wc_ecc_is_valid_idx(int n)
3799
0
{
3800
0
   int x;
3801
3802
0
   if (n >= (int)ECC_SET_COUNT)
3803
0
       return 0;
3804
3805
0
   for (x = 0; ecc_sets[x].size != 0; x++)
3806
0
       ;
3807
   /* -1 is a valid index --- indicating that the domain params
3808
      were supplied by the user */
3809
0
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
3810
0
      return 1;
3811
0
   }
3812
3813
0
   return 0;
3814
0
}
3815
3816
int wc_ecc_get_curve_idx(int curve_id)
3817
0
{
3818
0
    int curve_idx;
3819
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
3820
0
        if (curve_id == ecc_sets[curve_idx].id)
3821
0
            break;
3822
0
    }
3823
0
    if (ecc_sets[curve_idx].size == 0) {
3824
0
        return ECC_CURVE_INVALID;
3825
0
    }
3826
0
    return curve_idx;
3827
0
}
3828
3829
int wc_ecc_get_curve_id(int curve_idx)
3830
0
{
3831
0
    if (wc_ecc_is_valid_idx(curve_idx)) {
3832
0
        return ecc_sets[curve_idx].id;
3833
0
    }
3834
0
    return ECC_CURVE_INVALID;
3835
0
}
3836
3837
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
3838
 *
3839
 * id      curve id, from ecc_curve_id enum in ecc.h
3840
 * return  curve size, from ecc_sets[] on success, negative on error
3841
 */
3842
int wc_ecc_get_curve_size_from_id(int curve_id)
3843
0
{
3844
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
3845
0
    if (curve_idx == ECC_CURVE_INVALID)
3846
0
        return ECC_BAD_ARG_E;
3847
0
    return ecc_sets[curve_idx].size;
3848
0
}
3849
3850
/* Returns the curve index that corresponds to a given curve name in
3851
 * ecc_sets[] of ecc.c
3852
 *
3853
 * name    curve name, from ecc_sets[].name in ecc.c
3854
 * return  curve index in ecc_sets[] on success, negative on error
3855
 */
3856
int wc_ecc_get_curve_idx_from_name(const char* curveName)
3857
0
{
3858
0
    int curve_idx;
3859
3860
0
    if (curveName == NULL)
3861
0
        return BAD_FUNC_ARG;
3862
3863
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
3864
0
        if (
3865
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
3866
0
            ecc_sets[curve_idx].name &&
3867
0
        #endif
3868
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
3869
0
            break;
3870
0
        }
3871
0
    }
3872
0
    if (ecc_sets[curve_idx].size == 0) {
3873
0
        WOLFSSL_MSG("ecc_set curve name not found");
3874
0
        return ECC_CURVE_INVALID;
3875
0
    }
3876
0
    return curve_idx;
3877
0
}
3878
3879
/* Returns the curve size that corresponds to a given curve name,
3880
 * as listed in ecc_sets[] of ecc.c.
3881
 *
3882
 * name    curve name, from ecc_sets[].name in ecc.c
3883
 * return  curve size, from ecc_sets[] on success, negative on error
3884
 */
3885
int wc_ecc_get_curve_size_from_name(const char* curveName)
3886
0
{
3887
0
    int curve_idx;
3888
3889
0
    if (curveName == NULL)
3890
0
        return BAD_FUNC_ARG;
3891
3892
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
3893
0
    if (curve_idx < 0)
3894
0
        return curve_idx;
3895
3896
0
    return ecc_sets[curve_idx].size;
3897
0
}
3898
3899
/* Returns the curve id that corresponds to a given curve name,
3900
 * as listed in ecc_sets[] of ecc.c.
3901
 *
3902
 * name   curve name, from ecc_sets[].name in ecc.c
3903
 * return curve id, from ecc_sets[] on success, negative on error
3904
 */
3905
int wc_ecc_get_curve_id_from_name(const char* curveName)
3906
0
{
3907
0
    int curve_idx;
3908
3909
0
    if (curveName == NULL)
3910
0
        return BAD_FUNC_ARG;
3911
3912
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
3913
0
    if (curve_idx < 0)
3914
0
        return curve_idx;
3915
3916
0
    return ecc_sets[curve_idx].id;
3917
0
}
3918
3919
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
3920
 * parameter for equality.
3921
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
3922
 * Returns MP_EQ on success, negative on error */
3923
static int wc_ecc_cmp_param(const char* curveParam,
3924
                            const byte* param, word32 paramSz, int encType)
3925
0
{
3926
0
    int err = MP_OKAY;
3927
0
#ifdef WOLFSSL_SMALL_STACK
3928
0
    mp_int* a = NULL;
3929
0
    mp_int* b = NULL;
3930
#else
3931
    mp_int  a[1], b[1];
3932
#endif
3933
3934
0
    if (param == NULL || curveParam == NULL)
3935
0
        return BAD_FUNC_ARG;
3936
3937
0
    if (encType == WC_TYPE_HEX_STR)
3938
0
        return XSTRNCMP(curveParam, (char*) param, paramSz);
3939
3940
0
#ifdef WOLFSSL_SMALL_STACK
3941
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
3942
0
    if (a == NULL)
3943
0
        return MEMORY_E;
3944
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
3945
0
    if (b == NULL) {
3946
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
3947
0
        return MEMORY_E;
3948
0
    }
3949
0
#endif
3950
3951
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
3952
0
    #ifdef WOLFSSL_SMALL_STACK
3953
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
3954
0
        XFREE(b, NULL, DYNAMIC_TYPE_ECC);
3955
0
    #endif
3956
0
        return err;
3957
0
    }
3958
3959
0
    if (err == MP_OKAY) {
3960
0
        err = mp_read_unsigned_bin(a, param, paramSz);
3961
0
    }
3962
0
    if (err == MP_OKAY)
3963
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
3964
3965
0
    if (err == MP_OKAY) {
3966
0
        if (mp_cmp(a, b) != MP_EQ) {
3967
0
            err = -1;
3968
0
        } else {
3969
0
            err = MP_EQ;
3970
0
        }
3971
0
    }
3972
3973
0
    mp_clear(a);
3974
0
    mp_clear(b);
3975
0
#ifdef WOLFSSL_SMALL_STACK
3976
0
    XFREE(b, NULL, DYNAMIC_TYPE_ECC);
3977
0
    XFREE(a, NULL, DYNAMIC_TYPE_ECC);
3978
0
#endif
3979
3980
0
    return err;
3981
0
}
3982
3983
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
3984
 * curve parameters.
3985
 *
3986
 * fieldSize  the field size in bits
3987
 * prime      prime of the finite field
3988
 * primeSz    size of prime in octets
3989
 * Af         first coefficient a of the curve
3990
 * AfSz       size of Af in octets
3991
 * Bf         second coefficient b of the curve
3992
 * BfSz       size of Bf in octets
3993
 * order      curve order
3994
 * orderSz    size of curve in octets
3995
 * Gx         affine x coordinate of base point
3996
 * GxSz       size of Gx in octets
3997
 * Gy         affine y coordinate of base point
3998
 * GySz       size of Gy in octets
3999
 * cofactor   curve cofactor
4000
 *
4001
 * return curve id, from ecc_sets[] on success, negative on error
4002
 */
4003
int wc_ecc_get_curve_id_from_params(int fieldSize,
4004
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4005
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4006
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4007
0
{
4008
0
    int idx;
4009
0
    int curveSz;
4010
4011
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4012
0
        Gx == NULL || Gy == NULL)
4013
0
        return BAD_FUNC_ARG;
4014
4015
0
    curveSz = (fieldSize + 1) / 8;    /* round up */
4016
4017
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4018
0
        if (curveSz == ecc_sets[idx].size) {
4019
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4020
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4021
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4022
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4023
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4024
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4025
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4026
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4027
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4028
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4029
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4030
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4031
0
                (cofactor == ecc_sets[idx].cofactor)) {
4032
0
                    break;
4033
0
            }
4034
0
        }
4035
0
    }
4036
4037
0
    if (ecc_sets[idx].size == 0)
4038
0
        return ECC_CURVE_INVALID;
4039
4040
0
    return ecc_sets[idx].id;
4041
0
}
4042
4043
/* Returns the curve id in ecc_sets[] that corresponds
4044
 * to a given domain parameters pointer.
4045
 *
4046
 * dp   domain parameters pointer
4047
 *
4048
 * return curve id, from ecc_sets[] on success, negative on error
4049
 */
4050
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4051
0
{
4052
0
    int idx;
4053
4054
0
    if (dp == NULL
4055
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4056
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4057
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4058
0
    #endif
4059
0
    ) {
4060
0
        return BAD_FUNC_ARG;
4061
0
    }
4062
4063
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4064
0
        if (dp->size == ecc_sets[idx].size) {
4065
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4066
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4067
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4068
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4069
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4070
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4071
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4072
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4073
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4074
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4075
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4076
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4077
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4078
0
                    break;
4079
0
            }
4080
0
        }
4081
0
    }
4082
4083
0
    if (ecc_sets[idx].size == 0)
4084
0
        return ECC_CURVE_INVALID;
4085
4086
0
    return ecc_sets[idx].id;
4087
0
}
4088
4089
/* Returns the curve id that corresponds to a given OID,
4090
 * as listed in ecc_sets[] of ecc.c.
4091
 *
4092
 * oid   OID, from ecc_sets[].name in ecc.c
4093
 * len   OID len, from ecc_sets[].name in ecc.c
4094
 * return curve id, from ecc_sets[] on success, negative on error
4095
 */
4096
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4097
0
{
4098
0
    int curve_idx;
4099
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4100
    int ret;
4101
    #ifdef HAVE_OID_DECODING
4102
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4103
    #else
4104
    byte  decOid[MAX_OID_SZ];
4105
    #endif
4106
    word32 decOidSz;
4107
#endif
4108
4109
0
    if (oid == NULL)
4110
0
        return BAD_FUNC_ARG;
4111
4112
#ifdef HAVE_OID_DECODING
4113
    decOidSz = (word32)sizeof(decOid);
4114
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4115
    if (ret != 0) {
4116
        return ret;
4117
    }
4118
#endif
4119
4120
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4121
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4122
        decOidSz = (word32)sizeof(decOid);
4123
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4124
            decOid, &decOidSz);
4125
        if (ret != 0) {
4126
            continue;
4127
        }
4128
    #endif
4129
4130
0
        if (
4131
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4132
0
            ecc_sets[curve_idx].oid &&
4133
0
        #endif
4134
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4135
            decOidSz == len &&
4136
                XMEMCMP(decOid, oid, len) == 0
4137
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4138
            /* We double because decOidSz is a count of word16 elements. */
4139
            ecc_sets[curve_idx].oidSz == decOidSz &&
4140
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4141
        #else
4142
0
            ecc_sets[curve_idx].oidSz == len &&
4143
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4144
0
        #endif
4145
0
        ) {
4146
0
            break;
4147
0
        }
4148
0
    }
4149
0
    if (ecc_sets[curve_idx].size == 0) {
4150
0
        WOLFSSL_MSG("ecc_set curve name not found");
4151
0
        return ECC_CURVE_INVALID;
4152
0
    }
4153
4154
0
    return ecc_sets[curve_idx].id;
4155
0
}
4156
4157
/* Get curve parameters using curve index */
4158
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4159
0
{
4160
0
    const ecc_set_type* ecc_set = NULL;
4161
4162
0
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4163
0
        ecc_set = &ecc_sets[curve_idx];
4164
0
    }
4165
0
    return ecc_set;
4166
0
}
4167
4168
4169
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4170
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4171
{
4172
   if (key == NULL || mp == NULL)
4173
      return BAD_FUNC_ARG;
4174
   if (*mp == NULL) {
4175
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4176
      if (*mp == NULL) {
4177
         return MEMORY_E;
4178
      }
4179
      XMEMSET(*mp, 0, sizeof(mp_int));
4180
   }
4181
   return 0;
4182
}
4183
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4184
{
4185
   if (key && mp && *mp) {
4186
      mp_clear(*mp);
4187
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4188
      *mp = NULL;
4189
   }
4190
}
4191
4192
static int wc_ecc_alloc_async(ecc_key* key)
4193
{
4194
    int err = wc_ecc_alloc_mpint(key, &key->r);
4195
    if (err == 0)
4196
        err = wc_ecc_alloc_mpint(key, &key->s);
4197
    return err;
4198
}
4199
4200
static void wc_ecc_free_async(ecc_key* key)
4201
{
4202
    wc_ecc_free_mpint(key, &key->r);
4203
    wc_ecc_free_mpint(key, &key->s);
4204
#ifdef HAVE_CAVIUM_V
4205
    wc_ecc_free_mpint(key, &key->e);
4206
    wc_ecc_free_mpint(key, &key->signK);
4207
#endif /* HAVE_CAVIUM_V */
4208
}
4209
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4210
4211
4212
#ifdef HAVE_ECC_DHE
4213
/**
4214
  Create an ECC shared secret between two keys
4215
  private_key      The private ECC key (heap hint based off of private key)
4216
  public_key       The public key
4217
  out              [out] Destination of the shared secret
4218
                         Conforms to EC-DH from ANSI X9.63
4219
  outlen           [in/out] The max size and resulting size of the shared secret
4220
  return           MP_OKAY if successful
4221
*/
4222
WOLFSSL_ABI
4223
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4224
                      word32* outlen)
4225
0
{
4226
0
   int err = 0;
4227
4228
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4229
   !defined(WOLFSSL_ATECC608A)
4230
   CRYS_ECDH_TempData_t tempBuff;
4231
#endif
4232
4233
0
   (void)err;
4234
4235
0
   if (private_key == NULL || public_key == NULL || out == NULL ||
4236
0
                                                            outlen == NULL) {
4237
0
       return BAD_FUNC_ARG;
4238
0
   }
4239
4240
0
#ifdef WOLF_CRYPTO_CB
4241
0
    if (private_key->devId != INVALID_DEVID) {
4242
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4243
0
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
4244
0
        if (err != CRYPTOCB_UNAVAILABLE)
4245
0
            return err;
4246
        /* fall-through when unavailable */
4247
0
    #endif
4248
0
    }
4249
    #ifdef WOLF_CRYPTO_CB_ONLY_ECC
4250
    else {
4251
        err = NO_VALID_DEVID;
4252
    }
4253
    #endif
4254
0
#endif
4255
4256
0
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
4257
   /* type valid? */
4258
0
   if (private_key->type != ECC_PRIVATEKEY &&
4259
0
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4260
0
      return ECC_BAD_ARG_E;
4261
0
   }
4262
4263
   /* Verify domain params supplied */
4264
0
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4265
0
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4266
0
      return ECC_BAD_ARG_E;
4267
0
   }
4268
4269
   /* Verify curve id matches */
4270
0
   if (private_key->dp->id != public_key->dp->id) {
4271
0
      return ECC_BAD_ARG_E;
4272
0
   }
4273
4274
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4275
   /* For SECP256R1 use hardware */
4276
   if (private_key->dp->id == ECC_SECP256R1) {
4277
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4278
       *outlen = private_key->dp->size;
4279
   }
4280
   else {
4281
      err = NOT_COMPILED_IN;
4282
   }
4283
#elif defined(WOLFSSL_CRYPTOCELL)
4284
4285
    /* generate a secret*/
4286
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4287
                            &private_key->ctx.privKey,
4288
                            out,
4289
                            (uint32_t*)outlen,
4290
                            &tempBuff);
4291
4292
    if (err != SA_SILIB_RET_OK){
4293
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4294
        return err;
4295
    }
4296
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4297
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4298
#elif defined(WOLFSSL_KCAPI_ECC)
4299
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4300
#elif defined(WOLFSSL_SE050)
4301
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4302
#else
4303
0
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4304
0
#endif /* WOLFSSL_ATECC508A */
4305
0
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
4306
4307
0
   return err;
4308
0
}
4309
4310
4311
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4312
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4313
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4314
4315
static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4316
                               byte* out, word32* outlen)
4317
0
{
4318
0
    int err = MP_OKAY;
4319
0
    mp_int* k = &private_key->k;
4320
#ifdef HAVE_ECC_CDH
4321
#ifdef WOLFSSL_SMALL_STACK
4322
    mp_int *k_lcl = NULL;
4323
#else
4324
    mp_int k_lcl[1];
4325
#endif
4326
#endif
4327
4328
#ifdef HAVE_ECC_CDH
4329
    /* if cofactor flag has been set */
4330
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4331
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4332
        /* only perform cofactor calc if not equal to 1 */
4333
        if (cofactor != 1) {
4334
#ifdef WOLFSSL_SMALL_STACK
4335
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4336
                return MEMORY_E;
4337
#endif
4338
            k = k_lcl;
4339
            if (mp_init(k) != MP_OKAY) {
4340
                err = MEMORY_E;
4341
                goto errout;
4342
            }
4343
            /* multiply cofactor times private key "k" */
4344
            err = mp_mul_d(&private_key->k, cofactor, k);
4345
            if (err != MP_OKAY)
4346
                goto errout;
4347
        }
4348
    }
4349
#endif
4350
4351
#ifdef WOLFSSL_HAVE_SP_ECC
4352
#ifndef WOLFSSL_SP_NO_256
4353
    if (private_key->idx != ECC_CUSTOM_IDX &&
4354
                               ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4355
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4356
    }
4357
    else
4358
#endif
4359
#ifdef WOLFSSL_SP_384
4360
    if (private_key->idx != ECC_CUSTOM_IDX &&
4361
                               ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4362
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4363
    }
4364
    else
4365
#endif
4366
#ifdef WOLFSSL_SP_521
4367
    if (private_key->idx != ECC_CUSTOM_IDX &&
4368
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4369
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4370
    }
4371
    else
4372
#endif
4373
#else
4374
0
    (void)point;
4375
0
    (void)out;
4376
0
    (void)outlen;
4377
0
    (void)k;
4378
0
#endif
4379
#if defined(WOLFSSL_SP_MATH)
4380
    {
4381
        err = WC_KEY_SIZE_E;
4382
        goto errout;
4383
    }
4384
#else
4385
0
    {
4386
0
        ecc_point* result = NULL;
4387
        #ifdef WOLFSSL_NO_MALLOC
4388
        ecc_point  lcl_result;
4389
        #endif
4390
0
        word32 x = 0;
4391
0
        mp_digit mp = 0;
4392
0
        DECLARE_CURVE_SPECS(3);
4393
4394
        /* load curve info */
4395
0
        ALLOC_CURVE_SPECS(3, err);
4396
0
        if (err == MP_OKAY) {
4397
0
            err = wc_ecc_curve_load(private_key->dp, &curve,
4398
0
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4399
0
                 ECC_CURVE_FIELD_ORDER));
4400
0
        }
4401
4402
0
        if (err != MP_OKAY) {
4403
0
            FREE_CURVE_SPECS();
4404
0
            goto errout;
4405
0
        }
4406
4407
        /* make new point */
4408
    #ifdef WOLFSSL_NO_MALLOC
4409
        result = &lcl_result;
4410
    #endif
4411
0
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4412
0
        if (err != MP_OKAY) {
4413
0
            wc_ecc_curve_free(curve);
4414
0
            FREE_CURVE_SPECS();
4415
0
            goto errout;
4416
0
        }
4417
4418
0
#ifdef ECC_TIMING_RESISTANT
4419
0
        if (private_key->rng == NULL) {
4420
0
            err = MISSING_RNG_E;
4421
0
        }
4422
0
#endif
4423
4424
0
        if (err == MP_OKAY) {
4425
            /* Map in a separate call as this should be constant time */
4426
0
#ifdef ECC_TIMING_RESISTANT
4427
0
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4428
0
                                              curve->order, private_key->rng, 0,
4429
0
                                              private_key->heap);
4430
#else
4431
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4432
                                      curve->order, NULL, 0, private_key->heap);
4433
#endif
4434
0
        }
4435
0
        if (err == MP_OKAY) {
4436
        #ifdef WOLFSSL_CHECK_MEM_ZERO
4437
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
4438
                result->x);
4439
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
4440
                result->y);
4441
        #endif
4442
0
            err = mp_montgomery_setup(curve->prime, &mp);
4443
0
        }
4444
0
        if (err == MP_OKAY) {
4445
            /* Use constant time map if compiled in */
4446
0
            err = ecc_map_ex(result, curve->prime, mp, 1);
4447
0
        }
4448
0
        if (err == MP_OKAY) {
4449
0
            x = mp_unsigned_bin_size(curve->prime);
4450
0
            if (*outlen < x || (int)x < mp_unsigned_bin_size(result->x)) {
4451
0
                err = BUFFER_E;
4452
0
            }
4453
0
        }
4454
4455
0
        if (err == MP_OKAY) {
4456
0
            XMEMSET(out, 0, x);
4457
0
            err = mp_to_unsigned_bin(result->x,out +
4458
0
                                     (x - mp_unsigned_bin_size(result->x)));
4459
0
        }
4460
0
        *outlen = x;
4461
4462
0
        mp_forcezero(result->x);
4463
0
        mp_forcezero(result->y);
4464
0
        wc_ecc_del_point_ex(result, private_key->heap);
4465
4466
0
        wc_ecc_curve_free(curve);
4467
0
        FREE_CURVE_SPECS();
4468
0
    }
4469
0
#endif
4470
4471
0
  errout:
4472
4473
#ifdef HAVE_ECC_CDH
4474
    if (k == k_lcl)
4475
        mp_clear(k);
4476
#ifdef WOLFSSL_SMALL_STACK
4477
    if (k_lcl != NULL)
4478
        XFREE(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
4479
#endif
4480
#endif
4481
4482
0
    return err;
4483
0
}
4484
4485
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4486
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
4487
            ecc_point* point, byte* out, word32 *outlen)
4488
{
4489
    int err = 0;
4490
    DECLARE_CURVE_SPECS(3);
4491
4492
    /* load curve info */
4493
    ALLOC_CURVE_SPECS(3, err);
4494
    if (err == MP_OKAY) {
4495
        err = wc_ecc_curve_load(private_key->dp, &curve,
4496
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4497
             ECC_CURVE_FIELD_ORDER));
4498
    }
4499
4500
    if (err != MP_OKAY) {
4501
        FREE_CURVE_SPECS();
4502
        return err;
4503
    }
4504
4505
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
4506
    if (private_key->dp
4507
    #ifdef WOLFSSL_CUSTOM_CURVES
4508
        && private_key->dp->id != ECC_CURVE_CUSTOM
4509
    #endif
4510
    #ifdef HAVE_CAVIUM_V
4511
        /* verify the curve is supported by hardware */
4512
        && NitroxEccIsCurveSupported(private_key)
4513
    #endif
4514
    ) {
4515
        word32 keySz = private_key->dp->size;
4516
4517
        /* sync public key x/y */
4518
        err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);
4519
        if (err == MP_OKAY)
4520
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
4521
        if (err == MP_OKAY)
4522
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
4523
    #ifdef HAVE_CAVIUM_V
4524
        /* allocate buffer for output */
4525
        if (err == MP_OKAY)
4526
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
4527
        if (err == MP_OKAY)
4528
            err = wc_bigint_alloc(&private_key->e->raw,
4529
                NitroxEccGetSize(private_key)*2);
4530
        if (err == MP_OKAY)
4531
            err = NitroxEcdh(private_key,
4532
                &private_key->k.raw, &point->x->raw, &point->y->raw,
4533
                private_key->e->raw.buf, &private_key->e->raw.len,
4534
                &curve->prime->raw);
4535
    #else
4536
        if (err == MP_OKAY)
4537
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
4538
        if (err == MP_OKAY)
4539
            err = IntelQaEcdh(&private_key->asyncDev,
4540
                &private_key->k.raw, &point->x->raw, &point->y->raw,
4541
                out, outlen,
4542
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
4543
                private_key->dp->cofactor);
4544
    #endif
4545
        wc_ecc_curve_free(curve);
4546
        FREE_CURVE_SPECS();
4547
        return err;
4548
    }
4549
#elif defined(WOLFSSL_ASYNC_CRYPT_TEST)
4550
    if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {
4551
        WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;
4552
        testDev->eccSharedSec.private_key = private_key;
4553
        testDev->eccSharedSec.public_point = point;
4554
        testDev->eccSharedSec.out = out;
4555
        testDev->eccSharedSec.outLen = outlen;
4556
        wc_ecc_curve_free(curve);
4557
        FREE_CURVE_SPECS();
4558
        return WC_PENDING_E;
4559
    }
4560
#endif
4561
4562
    /* use sync in other cases */
4563
    err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
4564
4565
    wc_ecc_curve_free(curve);
4566
    FREE_CURVE_SPECS();
4567
4568
    return err;
4569
}
4570
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4571
4572
int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,
4573
                                                    byte* out, word32 *outlen)
4574
0
{
4575
0
    int err = MP_OKAY;
4576
4577
0
    if (private_key == NULL || point == NULL || out == NULL ||
4578
0
                                                            outlen == NULL) {
4579
0
        return BAD_FUNC_ARG;
4580
0
    }
4581
4582
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4583
    if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
4584
        err = wc_ecc_shared_secret_gen_async(private_key, point,
4585
            out, outlen);
4586
    }
4587
    else
4588
#endif
4589
0
    {
4590
0
        err = wc_ecc_shared_secret_gen_sync(private_key, point,
4591
0
            out, outlen);
4592
0
    }
4593
4594
0
    return err;
4595
0
}
4596
4597
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
4598
/**
4599
 Create an ECC shared secret between private key and public point
4600
 private_key      The private ECC key (heap hint based on private key)
4601
 point            The point to use (public key)
4602
 out              [out] Destination of the shared secret
4603
                        Conforms to EC-DH from ANSI X9.63
4604
 outlen           [in/out] The max size and resulting size of the shared secret
4605
 return           MP_OKAY if successful
4606
*/
4607
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
4608
                            byte* out, word32 *outlen)
4609
0
{
4610
0
    int err;
4611
4612
0
    if (private_key == NULL || point == NULL || out == NULL ||
4613
0
                                                            outlen == NULL) {
4614
0
        return BAD_FUNC_ARG;
4615
0
    }
4616
4617
    /* type valid? */
4618
0
    if (private_key->type != ECC_PRIVATEKEY &&
4619
0
            private_key->type != ECC_PRIVATEKEY_ONLY) {
4620
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
4621
0
        return ECC_BAD_ARG_E;
4622
0
    }
4623
4624
    /* Verify domain params supplied */
4625
0
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
4626
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
4627
0
        return ECC_BAD_ARG_E;
4628
0
    }
4629
4630
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4631
4632
0
    switch (private_key->state) {
4633
0
        case ECC_STATE_NONE:
4634
0
        case ECC_STATE_SHARED_SEC_GEN:
4635
0
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
4636
4637
0
            err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
4638
0
            if (err < 0) {
4639
0
                break;
4640
0
            }
4641
0
            FALL_THROUGH;
4642
4643
0
        case ECC_STATE_SHARED_SEC_RES:
4644
0
            private_key->state = ECC_STATE_SHARED_SEC_RES;
4645
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4646
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
4647
            #ifdef HAVE_CAVIUM_V
4648
                /* verify the curve is supported by hardware */
4649
                if (NitroxEccIsCurveSupported(private_key)) {
4650
                    /* copy output */
4651
                    *outlen = private_key->dp->size;
4652
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
4653
                }
4654
            #endif /* HAVE_CAVIUM_V */
4655
            }
4656
        #endif /* WOLFSSL_ASYNC_CRYPT */
4657
0
            err = 0;
4658
0
            break;
4659
4660
0
        default:
4661
0
            err = BAD_STATE_E;
4662
0
    } /* switch */
4663
4664
0
    RESTORE_VECTOR_REGISTERS();
4665
4666
    /* if async pending then return and skip done cleanup below */
4667
0
    if (err == WC_PENDING_E) {
4668
0
        private_key->state++;
4669
0
        return err;
4670
0
    }
4671
4672
    /* cleanup */
4673
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4674
    wc_ecc_free_async(private_key);
4675
#endif
4676
0
    private_key->state = ECC_STATE_NONE;
4677
4678
0
    return err;
4679
0
}
4680
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
4681
#elif defined(WOLFSSL_KCAPI_ECC)
4682
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
4683
                            byte* out, word32 *outlen)
4684
{
4685
    int err;
4686
    ecc_key public_key;
4687
4688
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
4689
    if (err == MP_OKAY) {
4690
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
4691
                               private_key->dp->id);
4692
        if (err == MP_OKAY) {
4693
            err = mp_copy(point->x, public_key.pubkey.x);
4694
        }
4695
        if (err == MP_OKAY) {
4696
            err = mp_copy(point->y, public_key.pubkey.y);
4697
        }
4698
        if (err == MP_OKAY) {
4699
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
4700
        }
4701
4702
        wc_ecc_free(&public_key);
4703
    }
4704
4705
    return err;
4706
}
4707
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
4708
#endif /* HAVE_ECC_DHE */
4709
4710
#ifdef USE_ECC_B_PARAM
4711
/* Checks if a point p lies on the curve with index curve_idx */
4712
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
4713
0
{
4714
0
    int err = MP_OKAY;
4715
0
    DECLARE_CURVE_SPECS(3);
4716
4717
0
    if (p == NULL)
4718
0
        return BAD_FUNC_ARG;
4719
4720
    /* is the IDX valid ?  */
4721
0
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
4722
0
       return ECC_BAD_ARG_E;
4723
0
    }
4724
4725
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4726
4727
0
    ALLOC_CURVE_SPECS(3, err);
4728
0
    if (err == MP_OKAY) {
4729
0
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
4730
0
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4731
0
                                ECC_CURVE_FIELD_BF);
4732
0
    }
4733
4734
    /* x must be in the range [0, p-1] */
4735
0
    if (err == MP_OKAY) {
4736
0
        if (mp_cmp(p->x, curve->prime) != MP_LT)
4737
0
            err = ECC_OUT_OF_RANGE_E;
4738
0
    }
4739
    /* y must be in the range [0, p-1] */
4740
0
    if (err == MP_OKAY) {
4741
0
        if (mp_cmp(p->y, curve->prime) != MP_LT)
4742
0
            err = ECC_OUT_OF_RANGE_E;
4743
0
    }
4744
    /* z must be 1 */
4745
0
    if (err == MP_OKAY) {
4746
0
        if (!mp_isone(p->z))
4747
0
            err = ECC_BAD_ARG_E;
4748
0
    }
4749
4750
0
    if (err == MP_OKAY) {
4751
0
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
4752
0
    }
4753
4754
0
    wc_ecc_curve_free(curve);
4755
0
    FREE_CURVE_SPECS();
4756
4757
0
    RESTORE_VECTOR_REGISTERS();
4758
4759
0
    return err;
4760
0
}
4761
#endif /* USE_ECC_B_PARAM */
4762
4763
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4764
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4765
/* return 1 if point is at infinity, 0 if not, < 0 on error */
4766
int wc_ecc_point_is_at_infinity(ecc_point* p)
4767
0
{
4768
0
    if (p == NULL)
4769
0
        return BAD_FUNC_ARG;
4770
0
    if (mp_iszero(p->x) && mp_iszero(p->y))
4771
0
        return 1;
4772
4773
0
    return 0;
4774
0
}
4775
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
4776
4777
/* generate random and ensure its greater than 0 and less than order */
4778
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
4779
0
{
4780
0
#ifndef WC_NO_RNG
4781
0
    int err;
4782
0
    byte buf[ECC_MAXSIZE_GEN];
4783
4784
0
    if (rng == NULL || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
4785
0
                                                                order == NULL) {
4786
0
        return BAD_FUNC_ARG;
4787
0
    }
4788
4789
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
4790
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
4791
0
    size += 8;
4792
4793
    /* make up random string */
4794
0
    err = wc_RNG_GenerateBlock(rng, buf, size);
4795
#ifdef WOLFSSL_CHECK_MEM_ZERO
4796
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
4797
#endif
4798
4799
    /* load random buffer data into k */
4800
0
    if (err == 0)
4801
0
        err = mp_read_unsigned_bin(k, buf, size);
4802
4803
    /* the key should be smaller than the order of base point */
4804
0
    if (err == MP_OKAY) {
4805
0
        if (mp_cmp(k, order) != MP_LT) {
4806
0
            err = mp_mod(k, order, k);
4807
0
        }
4808
0
    }
4809
4810
    /* quick sanity check to make sure we're not dealing with a 0 key */
4811
0
    if (err == MP_OKAY) {
4812
0
        if (mp_iszero(k) == MP_YES)
4813
0
          err = MP_ZERO_E;
4814
0
    }
4815
4816
0
    ForceZero(buf, ECC_MAXSIZE_GEN);
4817
#ifdef WOLFSSL_CHECK_MEM_ZERO
4818
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
4819
#endif
4820
4821
0
    return err;
4822
#else
4823
    (void)rng;
4824
    (void)size;
4825
    (void)k;
4826
    (void)order;
4827
    return NOT_COMPILED_IN;
4828
#endif /* !WC_NO_RNG */
4829
0
}
4830
4831
static WC_INLINE void wc_ecc_reset(ecc_key* key)
4832
0
{
4833
    /* make sure required key variables are reset */
4834
0
    key->state = ECC_STATE_NONE;
4835
0
}
4836
4837
/* create the public ECC key from a private key
4838
 *
4839
 * key     an initialized private key to generate public part from
4840
 * curveIn [in]curve for key, can be NULL
4841
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
4842
 *         is cached in key instead.
4843
 *
4844
 * Note this function is local to the file because of the argument type
4845
 *      ecc_curve_spec. Having this argument allows for not having to load the
4846
 *      curve type multiple times when generating a key with wc_ecc_make_key().
4847
 * For async the results are placed directly into pubOut, so this function
4848
 *      does not need to be called again
4849
 *
4850
 * returns MP_OKAY on success
4851
 */
4852
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
4853
        ecc_point* pubOut, WC_RNG* rng)
4854
0
{
4855
0
    int err = MP_OKAY;
4856
0
#ifdef HAVE_ECC_MAKE_PUB
4857
0
    ecc_point* pub;
4858
0
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
4859
0
#endif /* HAVE_ECC_MAKE_PUB */
4860
4861
0
    (void)rng;
4862
4863
0
    if (key == NULL) {
4864
0
        return BAD_FUNC_ARG;
4865
0
    }
4866
4867
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4868
4869
0
#ifdef HAVE_ECC_MAKE_PUB
4870
    /* if ecc_point passed in then use it as output for public key point */
4871
0
    if (pubOut != NULL) {
4872
0
        pub = pubOut;
4873
0
    }
4874
0
    else {
4875
        /* caching public key making it a ECC_PRIVATEKEY instead of
4876
           ECC_PRIVATEKEY_ONLY */
4877
0
        pub = &key->pubkey;
4878
0
        key->type = ECC_PRIVATEKEY_ONLY;
4879
0
    }
4880
4881
    /* avoid loading the curve unless it is not passed in */
4882
0
    if (curveIn != NULL) {
4883
0
        curve = curveIn;
4884
0
    }
4885
0
    else {
4886
        /* load curve info */
4887
0
        if (err == MP_OKAY) {
4888
0
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
4889
0
        }
4890
0
        if (err == MP_OKAY) {
4891
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
4892
0
        }
4893
0
    }
4894
4895
0
    if ((err == MP_OKAY) && (mp_iszero(&key->k) || mp_isneg(&key->k) ||
4896
0
                                      (mp_cmp(&key->k, curve->order) != MP_LT)))
4897
0
    {
4898
0
        err = ECC_PRIV_KEY_E;
4899
0
    }
4900
4901
0
    if (err == MP_OKAY) {
4902
0
    #ifndef ALT_ECC_SIZE
4903
0
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
4904
    #else
4905
        pub->x = (mp_int*)&pub->xyz[0];
4906
        pub->y = (mp_int*)&pub->xyz[1];
4907
        pub->z = (mp_int*)&pub->xyz[2];
4908
        alt_fp_init(pub->x);
4909
        alt_fp_init(pub->y);
4910
        alt_fp_init(pub->z);
4911
    #endif
4912
0
    }
4913
4914
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
4915
    defined(HAVE_INTEL_QA)
4916
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
4917
        word32 keySz = key->dp->size;
4918
        /* sync private key to raw */
4919
        err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
4920
        if (err == MP_OKAY) {
4921
            err = IntelQaEccPointMul(&key->asyncDev,
4922
                &key->k.raw, pub->x, pub->y, pub->z,
4923
                &curve->Gx->raw, &curve->Gy->raw,
4924
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
4925
                key->dp->cofactor);
4926
        }
4927
    }
4928
    else
4929
#endif
4930
0
    { /* BEGIN: Software Crypto */
4931
#ifdef WOLFSSL_HAVE_SP_ECC
4932
    /* Single-Precision Math (optimized for specific curves) */
4933
    if (err != MP_OKAY) {
4934
    }
4935
    else
4936
#ifndef WOLFSSL_SP_NO_256
4937
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
4938
        err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);
4939
    }
4940
    else
4941
#endif
4942
#ifdef WOLFSSL_SP_384
4943
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
4944
        err = sp_ecc_mulmod_base_384(&key->k, pub, 1, key->heap);
4945
    }
4946
    else
4947
#endif
4948
#ifdef WOLFSSL_SP_521
4949
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
4950
        err = sp_ecc_mulmod_base_521(&key->k, pub, 1, key->heap);
4951
    }
4952
    else
4953
#endif
4954
#endif /* WOLFSSL_HAVE_SP_ECC */
4955
4956
#if defined(WOLFSSL_SP_MATH)
4957
        err = WC_KEY_SIZE_E;
4958
#else
4959
0
    if (err == MP_OKAY) {
4960
        /* Multi-Precision Math: compute public curve */
4961
0
        mp_digit mp = 0;
4962
0
        ecc_point* base = NULL;
4963
    #ifdef WOLFSSL_NO_MALLOC
4964
        ecc_point  lcl_base;
4965
        base = &lcl_base;
4966
    #endif
4967
0
        err = wc_ecc_new_point_ex(&base, key->heap);
4968
4969
        /* read in the x/y for this key */
4970
0
        if (err == MP_OKAY)
4971
0
            err = mp_copy(curve->Gx, base->x);
4972
0
        if (err == MP_OKAY)
4973
0
            err = mp_copy(curve->Gy, base->y);
4974
0
        if (err == MP_OKAY)
4975
0
            err = mp_montgomery_setup(curve->prime, &mp);
4976
0
        if (err == MP_OKAY)
4977
0
            err = mp_set(base->z, 1);
4978
4979
        /* make the public key */
4980
0
        if (err == MP_OKAY) {
4981
            /* Map in a separate call as this should be constant time */
4982
0
            err = wc_ecc_mulmod_ex2(&key->k, base, pub, curve->Af, curve->prime,
4983
0
                                               curve->order, rng, 0, key->heap);
4984
0
            if (err == MP_MEM) {
4985
0
               err = MEMORY_E;
4986
0
            }
4987
0
        }
4988
0
        if (err == MP_OKAY) {
4989
            /* Use constant time map if compiled in */
4990
0
            err = ecc_map_ex(pub, curve->prime, mp, 1);
4991
0
        }
4992
4993
0
        wc_ecc_del_point_ex(base, key->heap);
4994
0
    }
4995
0
#endif /* WOLFSSL_SP_MATH */
4996
0
    } /* END: Software Crypto */
4997
4998
0
    if (err != MP_OKAY
4999
    #ifdef WOLFSSL_ASYNC_CRYPT
5000
        && err != WC_PENDING_E
5001
    #endif
5002
0
    ) {
5003
        /* clean up if failed */
5004
0
    #ifndef ALT_ECC_SIZE
5005
0
        mp_clear(pub->x);
5006
0
        mp_clear(pub->y);
5007
0
        mp_clear(pub->z);
5008
0
    #endif
5009
0
    }
5010
5011
    /* free up local curve */
5012
0
    if (curveIn == NULL) {
5013
0
        wc_ecc_curve_free(curve);
5014
0
        FREE_CURVE_SPECS();
5015
0
    }
5016
5017
#else
5018
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5019
    (void)curveIn;
5020
    err = NOT_COMPILED_IN;
5021
#endif /* HAVE_ECC_MAKE_PUB */
5022
5023
    /* change key state if public part is cached */
5024
0
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5025
0
        key->type = ECC_PRIVATEKEY;
5026
0
    }
5027
5028
0
    RESTORE_VECTOR_REGISTERS();
5029
5030
0
    return err;
5031
0
}
5032
5033
5034
/* create the public ECC key from a private key
5035
 *
5036
 * key     an initialized private key to generate public part from
5037
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5038
 *         is cached in key instead.
5039
 *
5040
 *
5041
 * returns MP_OKAY on success
5042
 */
5043
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5044
0
{
5045
0
    WOLFSSL_ENTER("wc_ecc_make_pub");
5046
5047
0
    return ecc_make_pub_ex(key, NULL, pubOut, NULL);
5048
0
}
5049
5050
/* create the public ECC key from a private key - mask timing use random z
5051
 *
5052
 * key     an initialized private key to generate public part from
5053
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5054
 *         is cached in key instead.
5055
 *
5056
 *
5057
 * returns MP_OKAY on success
5058
 */
5059
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5060
0
{
5061
0
    WOLFSSL_ENTER("wc_ecc_make_pub");
5062
5063
0
    return ecc_make_pub_ex(key, NULL, pubOut, rng);
5064
0
}
5065
5066
5067
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5068
        int curve_id, int flags)
5069
0
{
5070
0
    int err = 0;
5071
0
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLFSSL_SP_MATH)
5072
0
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5073
0
#endif
5074
5075
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5076
    !defined(WOLFSSL_ATECC608A)
5077
    const CRYS_ECPKI_Domain_t*  pDomain;
5078
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5079
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5080
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5081
    word32 raw_size = 0;
5082
#endif
5083
0
    if (key == NULL || rng == NULL) {
5084
0
        return BAD_FUNC_ARG;
5085
0
    }
5086
5087
    /* make sure required variables are reset */
5088
0
    wc_ecc_reset(key);
5089
5090
0
    err = wc_ecc_set_curve(key, keysize, curve_id);
5091
0
    if (err != 0) {
5092
0
        return err;
5093
0
    }
5094
5095
0
    key->flags = flags;
5096
5097
0
#ifdef WOLF_CRYPTO_CB
5098
0
    if (key->devId != INVALID_DEVID) {
5099
0
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5100
0
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
5101
0
        if (err != CRYPTOCB_UNAVAILABLE)
5102
0
            return err;
5103
        /* fall-through when unavailable */
5104
    #else
5105
        return err;
5106
    #endif
5107
0
    }
5108
    #ifdef WOLF_CRYPTO_CB_ONLY_ECC
5109
    else {
5110
        return NO_VALID_DEVID;
5111
    }
5112
    #endif
5113
0
#endif
5114
5115
0
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5116
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5117
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5118
    #ifdef HAVE_CAVIUM
5119
        /* TODO: Not implemented */
5120
    #elif defined(HAVE_INTEL_QA)
5121
        /* Implemented in ecc_make_pub_ex for the pub calc */
5122
    #else
5123
        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) {
5124
            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
5125
            testDev->eccMake.rng = rng;
5126
            testDev->eccMake.key = key;
5127
            testDev->eccMake.size = keysize;
5128
            testDev->eccMake.curve_id = curve_id;
5129
            return WC_PENDING_E;
5130
        }
5131
    #endif
5132
    }
5133
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5134
5135
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5136
   if (key->dp->id == ECC_SECP256R1) {
5137
       key->type = ECC_PRIVATEKEY;
5138
       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5139
       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
5140
5141
       /* populate key->pubkey */
5142
       if (err == 0
5143
       #ifdef ALT_ECC_SIZE
5144
          && key->pubkey.x
5145
       #endif
5146
       ) {
5147
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5148
                                      ECC_MAX_CRYPTO_HW_SIZE);
5149
       }
5150
       if (err == 0
5151
       #ifdef ALT_ECC_SIZE
5152
          && key->pubkey.y
5153
       #endif
5154
       ) {
5155
           err = mp_read_unsigned_bin(key->pubkey.y,
5156
                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
5157
                                      ECC_MAX_CRYPTO_HW_SIZE);
5158
       }
5159
   }
5160
   else {
5161
      err = NOT_COMPILED_IN;
5162
   }
5163
#elif defined(WOLFSSL_SE050)
5164
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5165
    key->type = ECC_PRIVATEKEY;
5166
#elif defined(WOLFSSL_CRYPTOCELL)
5167
5168
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5169
    raw_size = (word32)(key->dp->size)*2 + 1;
5170
5171
    /* generate first key pair */
5172
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5173
                                wc_rndGenVectFunc,
5174
                                pDomain,
5175
                                &key->ctx.privKey,
5176
                                &key->ctx.pubKey,
5177
                                &tempBuff,
5178
                                &fipsCtx);
5179
5180
    if (err != SA_SILIB_RET_OK){
5181
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5182
        return err;
5183
    }
5184
    key->type = ECC_PRIVATEKEY;
5185
5186
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5187
                                   CRYS_EC_PointUncompressed,
5188
                                   &ucompressed_key[0],
5189
                                   (uint32_t*)&raw_size);
5190
5191
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5192
        err = mp_read_unsigned_bin(key->pubkey.x,
5193
                                   &ucompressed_key[1], key->dp->size);
5194
        if (err == MP_OKAY) {
5195
            err = mp_read_unsigned_bin(key->pubkey.y,
5196
                            &ucompressed_key[1+key->dp->size],key->dp->size);
5197
        }
5198
    }
5199
    raw_size = key->dp->size;
5200
    if (err == MP_OKAY) {
5201
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
5202
                                       ucompressed_key,
5203
                                       (uint32_t*)&raw_size);
5204
    }
5205
5206
    if (err == SA_SILIB_RET_OK) {
5207
        err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size);
5208
    }
5209
5210
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5211
    return silabs_ecc_make_key(key, keysize);
5212
#elif defined(WOLFSSL_KCAPI_ECC)
5213
5214
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
5215
    (void)rng;
5216
5217
#else
5218
5219
#ifdef WOLFSSL_HAVE_SP_ECC
5220
#ifndef WOLFSSL_SP_NO_256
5221
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5222
        err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
5223
        if (err == MP_OKAY) {
5224
            key->type = ECC_PRIVATEKEY;
5225
        }
5226
    }
5227
    else
5228
#endif
5229
#ifdef WOLFSSL_SP_384
5230
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5231
        err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap);
5232
        if (err == MP_OKAY) {
5233
            key->type = ECC_PRIVATEKEY;
5234
        }
5235
    }
5236
    else
5237
#endif
5238
#ifdef WOLFSSL_SP_521
5239
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5240
        err = sp_ecc_make_key_521(rng, &key->k, &key->pubkey, key->heap);
5241
        if (err == MP_OKAY) {
5242
            key->type = ECC_PRIVATEKEY;
5243
        }
5244
    }
5245
    else
5246
#endif
5247
#endif /* WOLFSSL_HAVE_SP_ECC */
5248
5249
0
   { /* software key gen */
5250
#if defined(WOLFSSL_SP_MATH)
5251
        err = WC_KEY_SIZE_E;
5252
#else
5253
5254
        /* setup the key variables */
5255
0
        err = mp_init(&key->k);
5256
5257
        /* load curve info */
5258
0
        if (err == MP_OKAY) {
5259
0
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5260
0
        }
5261
0
        if (err == MP_OKAY) {
5262
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5263
0
        }
5264
5265
        /* generate k */
5266
0
        if (err == MP_OKAY) {
5267
0
            err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
5268
0
        }
5269
5270
        /* generate public key from k */
5271
0
        if (err == MP_OKAY) {
5272
0
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5273
0
        }
5274
5275
0
        if (err == MP_OKAY
5276
        #ifdef WOLFSSL_ASYNC_CRYPT
5277
            || err == WC_PENDING_E
5278
        #endif
5279
0
        ) {
5280
0
            key->type = ECC_PRIVATEKEY;
5281
0
        }
5282
0
        else {
5283
            /* cleanup these on failure case only */
5284
0
            mp_forcezero(&key->k);
5285
0
        }
5286
5287
        /* cleanup allocations */
5288
0
        wc_ecc_curve_free(curve);
5289
0
        FREE_CURVE_SPECS();
5290
0
#endif /* WOLFSSL_SP_MATH */
5291
0
    }
5292
5293
#ifdef HAVE_WOLF_BIGINT
5294
    if (err == MP_OKAY)
5295
         err = wc_mp_to_bigint(&key->k, &key->k.raw);
5296
    if (err == MP_OKAY)
5297
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
5298
    if (err == MP_OKAY)
5299
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
5300
    if (err == MP_OKAY)
5301
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
5302
#endif
5303
5304
0
#endif /* HAVE_ECC_MAKE_PUB */
5305
5306
0
    return err;
5307
0
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5308
0
}
5309
5310
5311
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
5312
                        int flags)
5313
0
{
5314
0
    int err;
5315
5316
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5317
5318
0
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
5319
5320
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
5321
    !defined(WOLFSSL_KCAPI_ECC)
5322
    if (err == MP_OKAY) {
5323
        err = _ecc_validate_public_key(key, 0, 0);
5324
    }
5325
    if (err == MP_OKAY) {
5326
        err = _ecc_pairwise_consistency_test(key, rng);
5327
    }
5328
#endif
5329
5330
0
    RESTORE_VECTOR_REGISTERS();
5331
5332
0
    return err;
5333
0
}
5334
5335
WOLFSSL_ABI
5336
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
5337
0
{
5338
0
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
5339
0
}
5340
5341
#ifdef ECC_DUMP_OID
5342
/* Optional dump of encoded OID for adding new curves */
5343
static int mOidDumpDone;
5344
static void wc_ecc_dump_oids(void)
5345
{
5346
    int x;
5347
5348
    if (mOidDumpDone) {
5349
        return;
5350
    }
5351
5352
    /* find matching OID sum (based on encoded value) */
5353
    for (x = 0; ecc_sets[x].size != 0; x++) {
5354
        int i;
5355
        byte* oid;
5356
        word32 oidSz, sum = 0;
5357
5358
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
5359
5360
    #ifdef HAVE_OID_ENCODING
5361
        byte oidEnc[ECC_MAX_OID_LEN];
5362
5363
        oid = oidEnc;
5364
        oidSz = ECC_MAX_OID_LEN;
5365
5366
        printf("OID: ");
5367
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
5368
            printf("%d.", ecc_sets[x].oid[i]);
5369
        }
5370
        printf("\n");
5371
5372
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
5373
    #else
5374
        oid = (byte*)ecc_sets[x].oid;
5375
        oidSz = ecc_sets[x].oidSz;
5376
    #endif
5377
5378
        printf("OID Encoded: ");
5379
        for (i = 0; i < (int)oidSz; i++) {
5380
            printf("0x%02X,", oid[i]);
5381
        }
5382
        printf("\n");
5383
5384
        for (i = 0; i < (int)oidSz; i++) {
5385
            sum += oid[i];
5386
        }
5387
        printf("Sum: %u\n", sum);
5388
5389
        /* validate sum */
5390
        if (ecc_sets[x].oidSum != sum) {
5391
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
5392
        }
5393
    }
5394
    mOidDumpDone = 1;
5395
}
5396
#endif /* ECC_DUMP_OID */
5397
5398
5399
WOLFSSL_ABI
5400
ecc_key* wc_ecc_key_new(void* heap)
5401
0
{
5402
0
    int devId = INVALID_DEVID;
5403
0
    ecc_key* key;
5404
5405
#ifdef WOLFSSL_QNX_CAAM
5406
    devId = WOLFSSL_CAAM_DEVID;
5407
#endif
5408
0
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
5409
0
    if (key) {
5410
0
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
5411
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
5412
0
            key = NULL;
5413
0
        }
5414
0
    }
5415
5416
0
    return key;
5417
0
}
5418
5419
5420
WOLFSSL_ABI
5421
void wc_ecc_key_free(ecc_key* key)
5422
0
{
5423
0
    if (key) {
5424
0
        void* heap = key->heap;
5425
5426
0
        wc_ecc_free(key);
5427
0
        ForceZero(key, sizeof(ecc_key));
5428
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
5429
0
        (void)heap;
5430
0
    }
5431
0
}
5432
5433
5434
/**
5435
 Make a new ECC key
5436
 rng          An active RNG state
5437
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
5438
 key          [out] Destination of the newly created key
5439
 return       MP_OKAY if successful,
5440
 upon error all allocated memory will be freed
5441
 */
5442
WOLFSSL_ABI
5443
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
5444
0
{
5445
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
5446
0
}
5447
5448
/* Setup dynamic pointers if using normal math for proper freeing */
5449
WOLFSSL_ABI
5450
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
5451
0
{
5452
0
    int ret = 0;
5453
5454
0
    if (key == NULL) {
5455
0
        return BAD_FUNC_ARG;
5456
0
    }
5457
5458
#ifdef ECC_DUMP_OID
5459
    wc_ecc_dump_oids();
5460
#endif
5461
5462
0
    XMEMSET(key, 0, sizeof(ecc_key));
5463
0
    key->state = ECC_STATE_NONE;
5464
5465
0
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
5466
0
    key->devId = devId;
5467
#else
5468
    (void)devId;
5469
#endif
5470
5471
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5472
    key->slot = ATECC_INVALID_SLOT;
5473
#elif defined(WOLFSSL_KCAPI_ECC)
5474
    key->handle = NULL;
5475
#else
5476
#ifdef ALT_ECC_SIZE
5477
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
5478
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
5479
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
5480
    alt_fp_init(key->pubkey.x);
5481
    alt_fp_init(key->pubkey.y);
5482
    alt_fp_init(key->pubkey.z);
5483
    ret = mp_init(&key->k);
5484
    if (ret != MP_OKAY) {
5485
        return MEMORY_E;
5486
    }
5487
#else
5488
0
    ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
5489
0
                                                                    NULL, NULL);
5490
0
    if (ret != MP_OKAY) {
5491
0
        return MEMORY_E;
5492
0
    }
5493
0
#endif /* ALT_ECC_SIZE */
5494
0
#endif /* WOLFSSL_ATECC508A */
5495
5496
#ifdef WOLFSSL_HEAP_TEST
5497
    key->heap = (void*)WOLFSSL_HEAP_TEST;
5498
#else
5499
0
    key->heap = heap;
5500
0
#endif
5501
5502
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5503
    /* handle as async */
5504
    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
5505
                                                            key->heap, devId);
5506
#endif
5507
5508
#if defined(WOLFSSL_DSP)
5509
    key->handle = -1;
5510
#endif
5511
5512
#ifdef WOLFSSL_SE050
5513
    key->keyId = -1;
5514
#endif
5515
5516
#ifdef WOLFSSL_CHECK_MEM_ZERO
5517
    mp_memzero_add("ECC k", &key->k);
5518
#endif
5519
5520
0
    return ret;
5521
0
}
5522
5523
WOLFSSL_ABI
5524
int wc_ecc_init(ecc_key* key)
5525
0
{
5526
#ifdef WOLFSSL_QNX_CAAM
5527
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
5528
#else
5529
0
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
5530
0
#endif
5531
0
}
5532
5533
#ifdef WOLF_PRIVATE_KEY_ID
5534
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
5535
                   int devId)
5536
0
{
5537
0
    int ret = 0;
5538
5539
0
    if (key == NULL)
5540
0
        ret = BAD_FUNC_ARG;
5541
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
5542
0
        ret = BUFFER_E;
5543
5544
0
    if (ret == 0)
5545
0
        ret = wc_ecc_init_ex(key, heap, devId);
5546
0
    if (ret == 0 && id != NULL && len != 0) {
5547
0
        XMEMCPY(key->id, id, len);
5548
0
        key->idLen = len;
5549
0
    }
5550
5551
0
    return ret;
5552
0
}
5553
5554
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
5555
0
{
5556
0
    int ret = 0;
5557
0
    int labelLen = 0;
5558
5559
0
    if (key == NULL || label == NULL)
5560
0
        ret = BAD_FUNC_ARG;
5561
0
    if (ret == 0) {
5562
0
        labelLen = (int)XSTRLEN(label);
5563
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
5564
0
            ret = BUFFER_E;
5565
0
    }
5566
5567
0
    if (ret == 0)
5568
0
        ret = wc_ecc_init_ex(key, heap, devId);
5569
0
    if (ret == 0) {
5570
0
        XMEMCPY(key->label, label, labelLen);
5571
0
        key->labelLen = labelLen;
5572
0
    }
5573
5574
0
    return ret;
5575
0
}
5576
#endif /* WOLF_PRIVATE_KEY_ID */
5577
5578
int wc_ecc_set_flags(ecc_key* key, word32 flags)
5579
0
{
5580
0
    if (key == NULL) {
5581
0
        return BAD_FUNC_ARG;
5582
0
    }
5583
0
    key->flags |= flags;
5584
0
    return 0;
5585
0
}
5586
5587
5588
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
5589
0
{
5590
0
    int err = MP_OKAY;
5591
0
    word32 orderBits;
5592
0
    DECLARE_CURVE_SPECS(1);
5593
5594
0
    ALLOC_CURVE_SPECS(1, err);
5595
0
    if (err == MP_OKAY) {
5596
0
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
5597
0
    }
5598
5599
0
    if (err != 0) {
5600
0
       FREE_CURVE_SPECS();
5601
0
       return err;
5602
0
    }
5603
0
    orderBits = mp_count_bits(curve->order);
5604
5605
0
    wc_ecc_curve_free(curve);
5606
0
    FREE_CURVE_SPECS();
5607
0
    return (int)orderBits;
5608
0
}
5609
5610
#ifdef HAVE_ECC_SIGN
5611
5612
#ifndef NO_ASN
5613
5614
5615
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
5616
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
5617
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
5618
    defined(WOLFSSL_SE050)
5619
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
5620
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
5621
    ecc_key* key)
5622
{
5623
    int err;
5624
#ifdef PLUTON_CRYPTO_ECC
5625
    if (key->devId != INVALID_DEVID) /* use hardware */
5626
#endif
5627
    {
5628
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5629
        !defined(WOLFSSL_ATECC608A)
5630
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
5631
        word32 raw_sig_size = *outlen;
5632
        word32 msgLenInBytes = inlen;
5633
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
5634
    #endif
5635
        word32 keysize = (word32)key->dp->size;
5636
    #ifdef PLUTON_CRYPTO_ECC
5637
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
5638
    #endif
5639
5640
    #ifndef WOLFSSL_KCAPI_ECC
5641
        /* Check args */
5642
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
5643
            return ECC_BAD_ARG_E;
5644
        }
5645
    #endif
5646
5647
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5648
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
5649
        err = atmel_ecc_sign(key->slot, in, out);
5650
        if (err != 0) {
5651
           return err;
5652
        }
5653
    #elif defined(PLUTON_CRYPTO_ECC)
5654
        {
5655
            /* if the input is larger than curve order, we must truncate */
5656
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
5657
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
5658
            }
5659
5660
            /* perform ECC sign */
5661
            word32 raw_sig_size = *outlen;
5662
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
5663
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
5664
               return BAD_COND_E;
5665
            }
5666
        }
5667
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
5668
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
5669
        if (err != 0) {
5670
               return WC_HW_E;
5671
        }
5672
    #elif defined(WOLFSSL_CRYPTOCELL)
5673
        /* truncate if hash is longer than key size */
5674
        if (msgLenInBytes > keysize) {
5675
            msgLenInBytes = keysize;
5676
        }
5677
        hash_mode = cc310_hashModeECC(msgLenInBytes);
5678
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
5679
            (void)cc310_hashModeECC(keysize);
5680
            /* Ignoring returned value */
5681
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
5682
5683
        }
5684
5685
        /* create signature from an input buffer using a private key*/
5686
        err = CRYS_ECDSA_Sign(&wc_rndState,
5687
                               wc_rndGenVectFunc,
5688
                               &sigCtxTemp,
5689
                               &key->ctx.privKey,
5690
                               hash_mode,
5691
                               (byte*)in,
5692
                               msgLenInBytes,
5693
                               out,
5694
                               (uint32_t*)&raw_sig_size);
5695
5696
        if (err != SA_SILIB_RET_OK){
5697
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
5698
            return err;
5699
        }
5700
    #elif defined(WOLFSSL_KCAPI_ECC)
5701
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
5702
        if (err != MP_OKAY) {
5703
            return err;
5704
        }
5705
        (void)rng;
5706
    #elif defined(WOLFSSL_SE050)
5707
        err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key);
5708
        if (err != MP_OKAY) {
5709
            return err;
5710
        }
5711
        (void)rng;
5712
    #endif
5713
5714
        /* Load R and S */
5715
        err = mp_read_unsigned_bin(r, &out[0], keysize);
5716
        if (err != MP_OKAY) {
5717
            return err;
5718
        }
5719
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
5720
        if (err != MP_OKAY) {
5721
            return err;
5722
        }
5723
5724
        /* Check for zeros */
5725
        if (mp_iszero(r) || mp_iszero(s)) {
5726
            return MP_ZERO_E;
5727
        }
5728
    }
5729
#ifdef PLUTON_CRYPTO_ECC
5730
    else {
5731
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
5732
    }
5733
#endif
5734
    (void)rng;
5735
5736
    return err;
5737
}
5738
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
5739
5740
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5741
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
5742
    word32 *outlen, WC_RNG* rng, ecc_key* key)
5743
{
5744
    int err;
5745
    mp_int *r = NULL, *s = NULL;
5746
5747
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
5748
                                                                rng == NULL) {
5749
        return ECC_BAD_ARG_E;
5750
    }
5751
5752
    err = wc_ecc_alloc_async(key);
5753
    if (err != 0) {
5754
        return err;
5755
    }
5756
    r = key->r;
5757
    s = key->s;
5758
5759
    switch (key->state) {
5760
        case ECC_STATE_NONE:
5761
        case ECC_STATE_SIGN_DO:
5762
            key->state = ECC_STATE_SIGN_DO;
5763
5764
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
5765
                break;
5766
            }
5767
5768
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
5769
            if (err < 0) {
5770
                break;
5771
            }
5772
5773
            FALL_THROUGH;
5774
5775
        case ECC_STATE_SIGN_ENCODE:
5776
            key->state = ECC_STATE_SIGN_ENCODE;
5777
5778
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5779
                #ifdef HAVE_CAVIUM_V
5780
                    /* Nitrox requires r and s in sep buffer, so split it */
5781
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
5782
                #endif
5783
                #ifndef WOLFSSL_ASYNC_CRYPT_TEST
5784
                    /* only do this if not simulator, since it overwrites result */
5785
                    wc_bigint_to_mp(&r->raw, r);
5786
                    wc_bigint_to_mp(&s->raw, s);
5787
                #endif
5788
            }
5789
5790
            /* encoded with DSA header */
5791
            err = StoreECC_DSA_Sig(out, outlen, r, s);
5792
5793
            /* done with R/S */
5794
            mp_clear(r);
5795
            mp_clear(s);
5796
            break;
5797
5798
        default:
5799
            err = BAD_STATE_E;
5800
            break;
5801
    }
5802
5803
    /* if async pending then return and skip done cleanup below */
5804
    if (err == WC_PENDING_E) {
5805
        key->state++;
5806
        return err;
5807
    }
5808
5809
    /* cleanup */
5810
    wc_ecc_free_async(key);
5811
    key->state = ECC_STATE_NONE;
5812
5813
    return err;
5814
}
5815
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5816
5817
/**
5818
 Sign a message digest
5819
 in        The message digest to sign
5820
 inlen     The length of the digest
5821
 out       [out] The destination for the signature
5822
 outlen    [in/out] The max size and resulting size of the signature
5823
 key       A private ECC key
5824
 return    MP_OKAY if successful
5825
 */
5826
WOLFSSL_ABI
5827
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
5828
                     WC_RNG* rng, ecc_key* key)
5829
0
{
5830
0
    int err;
5831
5832
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
5833
0
#ifdef WOLFSSL_SMALL_STACK
5834
0
    mp_int *r = NULL, *s = NULL;
5835
#else
5836
    mp_int r[1], s[1];
5837
#endif
5838
0
#endif
5839
5840
0
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
5841
0
        return ECC_BAD_ARG_E;
5842
0
    }
5843
5844
0
#ifdef WOLF_CRYPTO_CB
5845
0
    if (key->devId != INVALID_DEVID) {
5846
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
5847
0
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
5848
0
        if (err != CRYPTOCB_UNAVAILABLE)
5849
0
            return err;
5850
        /* fall-through when unavailable */
5851
0
    #endif
5852
0
    }
5853
    #ifdef WOLF_CRYPTO_CB_ONLY_ECC
5854
    else {
5855
        err = NO_VALID_DEVID;
5856
    }
5857
    #endif
5858
0
#endif
5859
5860
0
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5861
0
    if (rng == NULL) {
5862
0
        WOLFSSL_MSG("ECC sign RNG missing");
5863
0
        return ECC_BAD_ARG_E;
5864
0
    }
5865
5866
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5867
    /* handle async cases */
5868
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
5869
#else
5870
5871
0
#ifdef WOLFSSL_SMALL_STACK
5872
0
    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
5873
0
    if (r == NULL)
5874
0
        return MEMORY_E;
5875
0
    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
5876
0
    if (s == NULL) {
5877
0
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5878
0
        return MEMORY_E;
5879
0
    }
5880
0
#endif
5881
0
    XMEMSET(r, 0, sizeof(mp_int));
5882
0
    XMEMSET(s, 0, sizeof(mp_int));
5883
5884
0
    if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
5885
0
    #ifdef WOLFSSL_SMALL_STACK
5886
0
        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
5887
0
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5888
0
    #endif
5889
0
        return err;
5890
0
    }
5891
5892
/* hardware crypto */
5893
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5894
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
5895
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
5896
    defined(WOLFSSL_SE050)
5897
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
5898
#else
5899
0
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
5900
0
#endif
5901
0
    if (err < 0) {
5902
0
        mp_clear(r);
5903
0
        mp_clear(s);
5904
0
    #ifdef WOLFSSL_SMALL_STACK
5905
0
        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
5906
0
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5907
0
    #endif
5908
0
        return err;
5909
0
    }
5910
5911
    /* encoded with DSA header */
5912
0
    err = StoreECC_DSA_Sig(out, outlen, r, s);
5913
5914
    /* cleanup */
5915
0
    mp_clear(r);
5916
0
    mp_clear(s);
5917
5918
0
#ifdef WOLFSSL_SMALL_STACK
5919
0
    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
5920
0
    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5921
0
#endif
5922
0
#endif /* WOLFSSL_ASYNC_CRYPT */
5923
#else
5924
    (void)rng;
5925
    (void)inlen;
5926
    (void)s;
5927
    (void)r;
5928
    (void)err;
5929
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5930
5931
0
    return err;
5932
0
}
5933
#endif /* !NO_ASN */
5934
5935
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
5936
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
5937
/* returns MP_OKAY on success */
5938
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
5939
{
5940
    int err = MP_OKAY;
5941
    DECLARE_CURVE_SPECS(1);
5942
    ALLOC_CURVE_SPECS(1, err);
5943
5944
    /* get curve order */
5945
    if (err == MP_OKAY) {
5946
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
5947
    }
5948
5949
    if (err == MP_OKAY) {
5950
        /* if key->sign_k is NULL then create a buffer for the mp_int
5951
         * if not NULL then assume the user correctly set deterministic flag and
5952
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
5953
        if (key->sign_k == NULL) {
5954
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
5955
                                                            DYNAMIC_TYPE_ECC);
5956
        }
5957
5958
        if (key->sign_k != NULL) {
5959
            /* currently limiting to SHA256 for auto create */
5960
            if (mp_init(key->sign_k) != MP_OKAY ||
5961
                wc_ecc_gen_deterministic_k(in, inlen,
5962
                        WC_HASH_TYPE_SHA256, &key->k, key->sign_k,
5963
                        curve->order, key->heap) != 0) {
5964
                mp_free(key->sign_k);
5965
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
5966
                key->sign_k = NULL;
5967
                err = ECC_PRIV_KEY_E;
5968
            }
5969
        #ifdef WOLFSSL_CHECK_MEM_ZERO
5970
            else {
5971
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
5972
            }
5973
        #endif
5974
        }
5975
        else {
5976
            err = MEMORY_E;
5977
        }
5978
    }
5979
5980
    wc_ecc_curve_free(curve);
5981
    FREE_CURVE_SPECS();
5982
    return err;
5983
}
5984
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
5985
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
5986
5987
#if defined(WOLFSSL_STM32_PKA)
5988
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
5989
                     ecc_key* key, mp_int *r, mp_int *s)
5990
{
5991
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
5992
}
5993
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5994
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
5995
#ifndef WOLFSSL_SP_MATH
5996
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
5997
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
5998
                            mp_int* s)
5999
0
{
6000
0
    int err = MP_OKAY;
6001
0
    int loop_check = 0;
6002
0
#ifdef WOLFSSL_SMALL_STACK
6003
0
    mp_int* b = NULL;
6004
#else
6005
    mp_int  b[1];
6006
#endif
6007
6008
0
#ifdef WOLFSSL_SMALL_STACK
6009
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
6010
0
    if (b == NULL)
6011
0
        err = MEMORY_E;
6012
0
#endif
6013
6014
0
    if (err == MP_OKAY) {
6015
0
        err = mp_init(b);
6016
0
    }
6017
6018
0
#ifdef WOLFSSL_CUSTOM_CURVES
6019
    /* if custom curve, apply params to pubkey */
6020
0
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6021
0
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6022
0
    }
6023
0
#endif
6024
6025
0
    if (err == MP_OKAY) {
6026
        /* Generate blinding value - non-zero value. */
6027
0
        do {
6028
0
            if (++loop_check > 64) {
6029
0
                 err = RNG_FAILURE_E;
6030
0
                 break;
6031
0
            }
6032
6033
0
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6034
0
        }
6035
0
        while (err == MP_ZERO_E);
6036
0
        loop_check = 0;
6037
0
    }
6038
#ifdef WOLFSSL_CHECK_MEM_ZERO
6039
    if (err == MP_OKAY) {
6040
        mp_memzero_add("ecc_sign_hash_sw b", b);
6041
    }
6042
#endif
6043
6044
0
    for (; err == MP_OKAY;) {
6045
0
        if (++loop_check > 64) {
6046
0
             err = RNG_FAILURE_E;
6047
0
             break;
6048
0
        }
6049
0
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6050
0
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6051
0
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6052
0
        if (key->sign_k != NULL) {
6053
0
            if (loop_check > 1) {
6054
0
               err = RNG_FAILURE_E;
6055
0
               break;
6056
0
            }
6057
6058
            /* use provided sign_k */
6059
0
            err = mp_copy(key->sign_k, &pubkey->k);
6060
0
            if (err != MP_OKAY) break;
6061
6062
            /* free sign_k, so only used once */
6063
0
            mp_forcezero(key->sign_k);
6064
0
            mp_free(key->sign_k);
6065
0
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6066
0
            key->sign_k = NULL;
6067
0
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6068
0
            loop_check = 64;
6069
0
    #endif
6070
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6071
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6072
            if (key->deterministic == 1) {
6073
                /* sign_k generated earlier in function for SP calls.
6074
                 * Only go through the loop once and fail if error */
6075
                loop_check = 64;
6076
            }
6077
    #endif
6078
6079
            /* compute public key based on provided "k" */
6080
0
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6081
0
        }
6082
0
        else
6083
0
#endif
6084
0
        {
6085
0
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6086
0
                    WC_ECC_FLAG_NONE);
6087
0
        }
6088
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6089
        if (err == MP_OKAY) {
6090
            mp_memzero_add("ecc_sign_hash_sw k", &pubkey->k);
6091
        }
6092
    #endif
6093
    #ifdef WOLFSSL_ASYNC_CRYPT
6094
        /* for async do blocking wait here */
6095
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
6096
    #endif
6097
0
        if (err != MP_OKAY) break;
6098
6099
        /* find r = x1 mod n */
6100
0
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
6101
0
        if (err != MP_OKAY) break;
6102
6103
0
        if (mp_iszero(r) == MP_NO) {
6104
0
            mp_int* ep = &pubkey->k;
6105
0
            mp_int* kp = &pubkey->k;
6106
0
            mp_int* x  = &key->k;
6107
6108
            /* find s = (e + xr)/k
6109
                      = b.(e/k.b + x.r/k.b) */
6110
6111
            /* k' = k.b */
6112
0
            err = mp_mulmod(&pubkey->k, b, curve->order, kp);
6113
0
            if (err != MP_OKAY) break;
6114
6115
            /* k' = 1/k.b
6116
                  = 1/k' */
6117
0
            err = mp_invmod(kp, curve->order, kp);
6118
0
            if (err != MP_OKAY) break;
6119
6120
            /* s = x.r */
6121
0
            err = mp_mulmod(x, r, curve->order, s);
6122
0
            if (err != MP_OKAY) break;
6123
6124
            /* s = x.r/k.b
6125
                 = k'.s */
6126
0
            err = mp_mulmod(kp, s, curve->order, s);
6127
0
            if (err != MP_OKAY) break;
6128
6129
            /* e' = e/k.b
6130
                  = e.k' */
6131
0
            err = mp_mulmod(kp, e, curve->order, ep);
6132
0
            if (err != MP_OKAY) break;
6133
6134
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
6135
                 = e' + s */
6136
0
            err = mp_addmod_ct(ep, s, curve->order, s);
6137
0
            if (err != MP_OKAY) break;
6138
6139
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
6140
                 = b.s */
6141
0
            err = mp_mulmod(s, b, curve->order, s);
6142
0
            if (err != MP_OKAY) break;
6143
6144
0
            if (mp_iszero(s) == MP_NO) {
6145
                /* sign successful */
6146
0
                break;
6147
0
            }
6148
0
         }
6149
0
     #ifndef ALT_ECC_SIZE
6150
0
         mp_clear(pubkey->pubkey.x);
6151
0
         mp_clear(pubkey->pubkey.y);
6152
0
         mp_clear(pubkey->pubkey.z);
6153
0
     #endif
6154
0
         mp_forcezero(&pubkey->k);
6155
0
    }
6156
0
    mp_forcezero(b);
6157
0
#ifdef WOLFSSL_SMALL_STACK
6158
0
    XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
6159
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
6160
    mp_memzero_check(b);
6161
#endif
6162
6163
0
    return err;
6164
0
}
6165
#endif
6166
6167
/**
6168
  Sign a message digest
6169
  in        The message digest to sign
6170
  inlen     The length of the digest
6171
  key       A private ECC key
6172
  r         [out] The destination for r component of the signature
6173
  s         [out] The destination for s component of the signature
6174
  return    MP_OKAY if successful
6175
*/
6176
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6177
                     ecc_key* key, mp_int *r, mp_int *s)
6178
0
{
6179
0
   int    err = 0;
6180
0
#if !defined(WOLFSSL_SP_MATH)
6181
0
   mp_int* e;
6182
#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
6183
                                                   !defined(WOLFSSL_SMALL_STACK)
6184
   mp_int  e_lcl;
6185
#endif
6186
6187
0
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6188
0
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6189
0
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
6190
0
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
6191
0
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
6192
0
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6193
#else
6194
   DECLARE_CURVE_SPECS(1);
6195
#endif
6196
0
#endif /* !WOLFSSL_SP_MATH */
6197
6198
0
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
6199
0
       return ECC_BAD_ARG_E;
6200
0
   }
6201
6202
   /* is this a private key? */
6203
0
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
6204
0
      return ECC_BAD_ARG_E;
6205
0
   }
6206
6207
   /* is the IDX valid ?  */
6208
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
6209
0
      return ECC_BAD_ARG_E;
6210
0
   }
6211
6212
#if defined(WOLFSSL_SP_MATH)
6213
    if (key->idx == ECC_CUSTOM_IDX || (1
6214
    #ifndef WOLFSSL_SP_NO_256
6215
         && ecc_sets[key->idx].id != ECC_SECP256R1
6216
    #endif
6217
    #ifdef WOLFSSL_SP_384
6218
         && ecc_sets[key->idx].id != ECC_SECP384R1
6219
    #endif
6220
    #ifdef WOLFSSL_SP_521
6221
         && ecc_sets[key->idx].id != ECC_SECP521R1
6222
    #endif
6223
        )) {
6224
        return WC_KEY_SIZE_E;
6225
    }
6226
#endif
6227
6228
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6229
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6230
    /* generate deterministic 'k' value to be used either with SP or normal */
6231
    if (key->deterministic == 1) {
6232
        if (deterministic_sign_helper(in, inlen, key)) {
6233
            WOLFSSL_MSG("Error generating deterministic k to sign");
6234
            return ECC_PRIV_KEY_E;
6235
        }
6236
    }
6237
#endif
6238
6239
#if defined(WOLFSSL_HAVE_SP_ECC)
6240
    if (key->idx != ECC_CUSTOM_IDX
6241
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6242
        && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC
6243
    #endif
6244
    ) {
6245
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
6246
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6247
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6248
        mp_int* sign_k = key->sign_k;
6249
    #else
6250
        mp_int* sign_k = NULL;
6251
    #endif
6252
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
6253
        /* perform blocking call to non-blocking function */
6254
        ecc_nb_ctx_t nb_ctx;
6255
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
6256
    #endif
6257
    #ifndef WOLFSSL_SP_NO_256
6258
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
6259
        #ifdef WC_ECC_NONBLOCK
6260
            if (key->nb_ctx) {
6261
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
6262
                    &key->k, r, s, sign_k, key->heap);
6263
            }
6264
            #ifdef WC_ECC_NONBLOCK_ONLY
6265
            do { /* perform blocking call to non-blocking function */
6266
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
6267
                    &key->k, r, s, sign_k, key->heap);
6268
            } while (err == FP_WOULDBLOCK);
6269
            return err;
6270
            #endif
6271
        #endif /* WC_ECC_NONBLOCK */
6272
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6273
            {
6274
                int ret;
6275
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6276
                ret = sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, sign_k,
6277
                                      key->heap);
6278
                RESTORE_VECTOR_REGISTERS();
6279
                return ret;
6280
            }
6281
        #endif
6282
        }
6283
    #endif
6284
    #ifdef WOLFSSL_SP_384
6285
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
6286
        #ifdef WC_ECC_NONBLOCK
6287
            if (key->nb_ctx) {
6288
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
6289
                    &key->k, r, s, sign_k, key->heap);
6290
            }
6291
            #ifdef WC_ECC_NONBLOCK_ONLY
6292
            do { /* perform blocking call to non-blocking function */
6293
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
6294
                    &key->k, r, s, sign_k, key->heap);
6295
            } while (err == FP_WOULDBLOCK);
6296
            return err;
6297
            #endif
6298
        #endif /* WC_ECC_NONBLOCK */
6299
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6300
            {
6301
                int ret;
6302
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6303
                ret = sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, sign_k,
6304
                                      key->heap);
6305
                RESTORE_VECTOR_REGISTERS();
6306
                return ret;
6307
            }
6308
        #endif
6309
        }
6310
    #endif
6311
    #ifdef WOLFSSL_SP_521
6312
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
6313
        #ifdef WC_ECC_NONBLOCK
6314
            if (key->nb_ctx) {
6315
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
6316
                    &key->k, r, s, sign_k, key->heap);
6317
            }
6318
            #ifdef WC_ECC_NONBLOCK_ONLY
6319
            do { /* perform blocking call to non-blocking function */
6320
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
6321
                    &key->k, r, s, sign_k, key->heap);
6322
            } while (err == FP_WOULDBLOCK);
6323
            return err;
6324
            #endif
6325
        #endif /* WC_ECC_NONBLOCK */
6326
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6327
            {
6328
                int ret;
6329
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6330
                ret = sp_ecc_sign_521(in, inlen, rng, &key->k, r, s, sign_k,
6331
                                      key->heap);
6332
                RESTORE_VECTOR_REGISTERS();
6333
                return ret;
6334
            }
6335
        #endif
6336
        }
6337
    #endif
6338
        (void)sign_k;
6339
    }
6340
#else
6341
0
   (void)inlen;
6342
0
#endif
6343
6344
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
6345
       defined(WOLFSSL_ASYNC_CRYPT_TEST)
6346
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6347
        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) {
6348
            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
6349
            testDev->eccSign.in = in;
6350
            testDev->eccSign.inSz = inlen;
6351
            testDev->eccSign.rng = rng;
6352
            testDev->eccSign.key = key;
6353
            testDev->eccSign.r = r;
6354
            testDev->eccSign.s = s;
6355
            return WC_PENDING_E;
6356
        }
6357
    }
6358
#endif
6359
6360
6361
0
#if !defined(WOLFSSL_SP_MATH)
6362
6363
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
6364
   err = wc_ecc_alloc_mpint(key, &key->e);
6365
   if (err != 0) {
6366
      return err;
6367
   }
6368
   e = key->e;
6369
#elif !defined(WOLFSSL_SMALL_STACK)
6370
   e = &e_lcl;
6371
#else
6372
0
   e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
6373
0
   if (e == NULL) {
6374
0
      return MEMORY_E;
6375
0
   }
6376
0
#endif
6377
6378
   /* get the hash and load it as a bignum into 'e' */
6379
   /* init the bignums */
6380
0
   if ((err = mp_init(e)) != MP_OKAY) {
6381
0
   #ifdef WOLFSSL_SMALL_STACK
6382
0
      XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
6383
0
   #endif
6384
0
      return err;
6385
0
   }
6386
6387
   /* load curve info */
6388
0
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6389
0
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6390
0
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6391
0
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6392
0
    if (err == MP_OKAY)
6393
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6394
#else
6395
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
6396
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
6397
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6398
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6399
        if (err == MP_OKAY)
6400
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6401
    }
6402
    else
6403
    #endif
6404
    {
6405
        ALLOC_CURVE_SPECS(1, err);
6406
        if (err == MP_OKAY)
6407
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6408
    }
6409
#endif
6410
6411
   /* load digest into e */
6412
0
   if (err == MP_OKAY) {
6413
       /* we may need to truncate if hash is longer than key size */
6414
0
       word32 orderBits = mp_count_bits(curve->order);
6415
6416
       /* truncate down to byte size, may be all that's needed */
6417
0
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
6418
0
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6419
0
       err = mp_read_unsigned_bin(e, in, inlen);
6420
6421
       /* may still need bit truncation too */
6422
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
6423
0
           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
6424
0
   }
6425
6426
   /* make up a key and export the public copy */
6427
0
   if (err == MP_OKAY) {
6428
0
   #ifdef WOLFSSL_SMALL_STACK
6429
0
       ecc_key* pubkey;
6430
   #else
6431
       ecc_key  pubkey[1];
6432
   #endif
6433
6434
   #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6435
        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6436
        #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
6437
        #ifdef HAVE_CAVIUM_V
6438
            if (NitroxEccIsCurveSupported(key))
6439
        #endif
6440
            {
6441
               word32 keySz = key->dp->size;
6442
               mp_int* k;
6443
            #ifdef HAVE_CAVIUM_V
6444
               err = wc_ecc_alloc_mpint(key, &key->signK);
6445
               if (err != 0)
6446
                  return err;
6447
               k = key->signK;
6448
            #else
6449
               mp_int k_lcl;
6450
               k = &k_lcl;
6451
            #endif
6452
6453
               err = mp_init(k);
6454
6455
                /* make sure r and s are allocated */
6456
           #ifdef HAVE_CAVIUM_V
6457
               /* Nitrox V needs single buffer for R and S */
6458
               if (err == MP_OKAY)
6459
                   err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
6460
               /* Nitrox V only needs Prime and Order */
6461
               if (err == MP_OKAY)
6462
                   err = wc_ecc_curve_load(key->dp, &curve,
6463
                        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
6464
           #else
6465
               if (err == MP_OKAY)
6466
                   err = wc_bigint_alloc(&key->r->raw, key->dp->size);
6467
               if (err == MP_OKAY)
6468
                   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6469
           #endif
6470
               if (err == MP_OKAY)
6471
                   err = wc_bigint_alloc(&key->s->raw, key->dp->size);
6472
6473
               /* load e and k */
6474
               if (err == MP_OKAY)
6475
                   err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
6476
               if (err == MP_OKAY)
6477
                   err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
6478
               if (err == MP_OKAY)
6479
                   err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
6480
               if (err == MP_OKAY)
6481
                   err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
6482
6483
           #ifdef HAVE_CAVIUM_V
6484
               if (err == MP_OKAY)
6485
                   err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,
6486
                    &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
6487
           #else
6488
               if (err == MP_OKAY)
6489
                   err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,
6490
                      &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
6491
                      &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
6492
                      &curve->Gy->raw);
6493
           #endif
6494
6495
           #ifndef HAVE_CAVIUM_V
6496
               mp_clear(e);
6497
               mp_clear(k);
6498
           #endif
6499
               wc_ecc_curve_free(curve);
6500
               FREE_CURVE_SPECS();
6501
6502
               return err;
6503
           }
6504
       #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
6505
       }
6506
   #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6507
6508
0
   #ifdef WOLFSSL_SMALL_STACK
6509
0
       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
6510
0
       if (pubkey == NULL)
6511
0
           err = MEMORY_E;
6512
0
   #endif
6513
6514
       /* don't use async for key, since we don't support async return here */
6515
0
       if (err == MP_OKAY) {
6516
0
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
6517
0
           if (err == MP_OKAY) {
6518
0
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
6519
0
              wc_ecc_free(pubkey);
6520
0
           #ifdef WOLFSSL_SMALL_STACK
6521
0
              XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
6522
0
           #endif
6523
0
           }
6524
0
       }
6525
0
   }
6526
6527
0
   mp_clear(e);
6528
0
   wc_ecc_curve_free(curve);
6529
0
#ifdef WOLFSSL_SMALL_STACK
6530
0
   XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
6531
0
#endif
6532
0
   FREE_CURVE_SPECS();
6533
0
#endif /* !WOLFSSL_SP_MATH */
6534
6535
0
   return err;
6536
0
}
6537
6538
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6539
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6540
/* helper function to do HMAC operations
6541
 * returns 0 on success and updates "out" buffer
6542
 */
6543
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
6544
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
6545
        byte* out, enum wc_HashType hashType, void* heap)
6546
{
6547
    Hmac hmac;
6548
    int  ret, init;
6549
6550
    ret = init = wc_HmacInit(&hmac, heap, 0);
6551
    if (ret == 0)
6552
        ret = wc_HmacSetKey(&hmac, hashType, K, KSz);
6553
6554
    if (ret == 0)
6555
        ret = wc_HmacUpdate(&hmac, V, VSz);
6556
6557
    if (ret == 0 && oct != NULL)
6558
        ret = wc_HmacUpdate(&hmac, oct, 1);
6559
6560
    if (ret == 0)
6561
        ret = wc_HmacUpdate(&hmac, x, xSz);
6562
6563
    if (ret == 0)
6564
        ret = wc_HmacUpdate(&hmac, h1, h1Sz);
6565
6566
    if (ret == 0)
6567
        ret = wc_HmacFinal(&hmac, out);
6568
6569
    if (init == 0)
6570
        wc_HmacFree(&hmac);
6571
6572
    return ret;
6573
}
6574
6575
6576
/* Generates a deterministic key based of the message using RFC6979
6577
 * @param  [in]   hash     Hash value to sign
6578
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
6579
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
6580
 *                WC_HASH_TYPE_SHA256
6581
 * @param  [in]   priv     Current ECC private key set
6582
 * @param  [out]  k        An initialized mp_int to set the k value generated in
6583
 * @param  [in]   order    ECC order parameter to use with generation
6584
 * @return  0 on success.
6585
 */
6586
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
6587
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
6588
        void* heap)
6589
{
6590
    int ret = 0, qbits = 0;
6591
#ifndef WOLFSSL_SMALL_STACK
6592
    byte h1[MAX_ECC_BYTES];
6593
    byte V[WC_MAX_DIGEST_SIZE];
6594
    byte K[WC_MAX_DIGEST_SIZE];
6595
    byte x[MAX_ECC_BYTES];
6596
    mp_int z1[1];
6597
#else
6598
    byte *h1 = NULL;
6599
    byte *V  = NULL;
6600
    byte *K  = NULL;
6601
    byte *x  = NULL;
6602
    mp_int *z1 = NULL;
6603
#endif
6604
    word32 xSz, VSz, KSz, h1len, qLen;
6605
    byte intOct;
6606
6607
    if (hash == NULL || k == NULL || order == NULL) {
6608
        return BAD_FUNC_ARG;
6609
    }
6610
6611
    if (hashSz > WC_MAX_DIGEST_SIZE) {
6612
        WOLFSSL_MSG("hash size was too large!");
6613
        return BAD_FUNC_ARG;
6614
    }
6615
6616
    if (hashSz != WC_SHA256_DIGEST_SIZE) {
6617
        WOLFSSL_MSG("Currently only SHA256 digest is supported");
6618
        return BAD_FUNC_ARG;
6619
    }
6620
6621
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
6622
        WOLFSSL_MSG("private key larger than max expected!");
6623
        return BAD_FUNC_ARG;
6624
    }
6625
6626
#ifdef WOLFSSL_SMALL_STACK
6627
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
6628
    if (h1 == NULL) {
6629
        ret = MEMORY_E;
6630
    }
6631
6632
    if (ret == 0) {
6633
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
6634
        if (V == NULL)
6635
            ret = MEMORY_E;
6636
    }
6637
6638
    if (ret == 0) {
6639
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
6640
        if (K == NULL)
6641
            ret = MEMORY_E;
6642
    }
6643
6644
    if (ret == 0) {
6645
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
6646
        if (x == NULL)
6647
            ret = MEMORY_E;
6648
    }
6649
6650
    if (ret == 0) {
6651
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
6652
        if (z1 == NULL)
6653
            ret = MEMORY_E;
6654
    }
6655
6656
    /* bail out if any error has been hit at this point */
6657
    if (ret != 0) {
6658
        if (x != NULL)
6659
            XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
6660
        if (K != NULL)
6661
            XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
6662
        if (V != NULL)
6663
            XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
6664
        if (h1 != NULL)
6665
            XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
6666
        return ret;
6667
    }
6668
#endif
6669
6670
    VSz = KSz = hashSz;
6671
    qLen = xSz = h1len = mp_unsigned_bin_size(order);
6672
6673
    /* 3.2 b. Set V = 0x01 0x01 ... */
6674
    XMEMSET(V, 0x01, VSz);
6675
6676
    /* 3.2 c. Set K = 0x00 0x00 ... */
6677
    XMEMSET(K, 0x00, KSz);
6678
6679
    mp_init(z1); /* always init z1 and free z1 */
6680
    ret = mp_to_unsigned_bin_len(priv, x, qLen);
6681
    if (ret == 0) {
6682
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6683
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
6684
    #endif
6685
        qbits = mp_count_bits(order);
6686
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
6687
    }
6688
6689
    /* bits2octets on h1 */
6690
    if (ret == 0) {
6691
        XMEMSET(h1, 0, MAX_ECC_BYTES);
6692
6693
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6694
        /* mod reduce by order using conditional subtract
6695
         * RFC6979 lists a variant that uses the hash directly instead of
6696
         * doing bits2octets(H(m)), when variant macro is used avoid this
6697
         * bits2octets operation */
6698
        if (mp_cmp(z1, order) == MP_GT) {
6699
            int z1Sz;
6700
6701
            mp_sub(z1, order, z1);
6702
            z1Sz = mp_unsigned_bin_size(z1);
6703
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
6704
                ret = BUFFER_E;
6705
            }
6706
            else {
6707
                ret = mp_to_unsigned_bin_len(z1, h1, h1len);
6708
            }
6709
        }
6710
        else
6711
    #endif
6712
        {
6713
            /* use original hash and keep leading 0's */
6714
            mp_to_unsigned_bin_len(z1, h1, h1len);
6715
        }
6716
    }
6717
    mp_free(z1);
6718
6719
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
6720
    if (ret == 0) {
6721
        intOct = 0x00;
6722
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
6723
                hashType, heap);
6724
    }
6725
6726
    /* 3.2 step e. V = HMAC_K(V) */
6727
    if (ret == 0) {
6728
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
6729
                heap);
6730
    }
6731
6732
6733
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
6734
    if (ret == 0) {
6735
        intOct = 0x01;
6736
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
6737
                heap);
6738
    }
6739
6740
    /* 3.2 step g. V = HMAC_K(V) */
6741
    if (ret == 0) {
6742
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
6743
                heap);
6744
    }
6745
6746
    /* 3.2 step h. loop through the next steps until a valid value is found */
6747
    if (ret == 0 ) {
6748
        int err;
6749
6750
        intOct = 0x00;
6751
        do {
6752
            xSz = 0; /* used as tLen */
6753
            err = 0; /* start as good until generated k is tested */
6754
6755
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
6756
            while (xSz < qLen) {
6757
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
6758
                        hashType, heap);
6759
                if (ret == 0) {
6760
                    int sz;
6761
6762
                    sz = MIN(qLen - xSz, VSz);
6763
                    XMEMCPY(x + xSz, V, sz);
6764
                    xSz += sz;
6765
                }
6766
                else {
6767
                    break; /* error case */
6768
                }
6769
            }
6770
6771
            if (ret == 0) {
6772
                mp_clear(k); /* 3.2 step h.1 clear T */
6773
                ret = mp_read_unsigned_bin(k, x, xSz);
6774
            }
6775
6776
            if ((ret == 0) && ((int)(xSz * WOLFSSL_BIT_SIZE) != qbits)) {
6777
                /* handle odd case where shift of 'k' is needed with RFC 6979
6778
                 *  k = bits2int(T) in section 3.2 h.3 */
6779
                mp_rshb(k, (xSz * WOLFSSL_BIT_SIZE) - qbits);
6780
            }
6781
6782
            /* 3.2 step h.3 the key should be smaller than the order of base
6783
             * point */
6784
            if (ret == 0) {
6785
                if (mp_cmp(k, order) != MP_LT) {
6786
                    err = MP_VAL;
6787
                } else if (mp_iszero(k) == MP_YES) {
6788
                    /* no 0 key's */
6789
                    err = MP_ZERO_E;
6790
                }
6791
            }
6792
6793
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
6794
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
6795
            if (ret == 0 && err != 0) {
6796
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
6797
                    hashType, heap);
6798
                if (ret == 0) {
6799
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
6800
                    hashType, heap);
6801
                }
6802
            }
6803
        } while (ret == 0 && err != 0);
6804
    }
6805
6806
    ForceZero(x, MAX_ECC_BYTES);
6807
#ifdef WOLFSSL_SMALL_STACK
6808
    if (z1 != NULL)
6809
        XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
6810
    if (x != NULL)
6811
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
6812
    if (K != NULL)
6813
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
6814
    if (V != NULL)
6815
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
6816
    if (h1 != NULL)
6817
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
6818
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
6819
    wc_MemZero_Check(x, MAX_ECC_BYTES);
6820
#endif
6821
6822
    return ret;
6823
}
6824
6825
6826
/* Sets the deterministic flag for 'k' generation with sign.
6827
 * returns 0 on success
6828
 */
6829
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
6830
{
6831
    if (key == NULL) {
6832
        return BAD_FUNC_ARG;
6833
    }
6834
6835
    key->deterministic = flag;
6836
    return 0;
6837
}
6838
#endif /* end sign_ex and deterministic sign */
6839
6840
6841
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
6842
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
6843
0
{
6844
0
    int ret = MP_OKAY;
6845
0
    DECLARE_CURVE_SPECS(1);
6846
6847
0
    if (k == NULL || klen == 0 || key == NULL) {
6848
0
        return BAD_FUNC_ARG;
6849
0
    }
6850
6851
0
    ALLOC_CURVE_SPECS(1, ret);
6852
0
    if (ret == MP_OKAY) {
6853
0
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6854
0
    }
6855
6856
0
    if (ret != 0) {
6857
0
        FREE_CURVE_SPECS();
6858
0
        return ret;
6859
0
    }
6860
6861
0
    if (key->sign_k == NULL) {
6862
0
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6863
0
                                                            DYNAMIC_TYPE_ECC);
6864
0
        if (key->sign_k) {
6865
0
            ret = mp_init(key->sign_k);
6866
0
        }
6867
0
        else {
6868
0
            ret = MEMORY_E;
6869
0
        }
6870
0
    }
6871
6872
0
    if (ret == 0) {
6873
0
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
6874
0
    }
6875
0
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
6876
0
        ret = MP_VAL;
6877
0
    }
6878
6879
0
    wc_ecc_curve_free(curve);
6880
0
    FREE_CURVE_SPECS();
6881
0
    return ret;
6882
0
}
6883
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
6884
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
6885
6886
#endif /* !HAVE_ECC_SIGN */
6887
6888
#ifdef WOLFSSL_CUSTOM_CURVES
6889
void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
6890
0
{
6891
0
#ifndef WOLFSSL_ECC_CURVE_STATIC
6892
0
    if (curve->prime != NULL)
6893
0
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
6894
0
    if (curve->Af != NULL)
6895
0
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
6896
0
    if (curve->Bf != NULL)
6897
0
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
6898
0
    if (curve->order != NULL)
6899
0
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
6900
0
    if (curve->Gx != NULL)
6901
0
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
6902
0
    if (curve->Gy != NULL)
6903
0
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
6904
0
#endif
6905
6906
0
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
6907
6908
0
    (void)heap;
6909
0
}
6910
#endif /* WOLFSSL_CUSTOM_CURVES */
6911
6912
/**
6913
  Free an ECC key from memory
6914
  key   The key you wish to free
6915
*/
6916
WOLFSSL_ABI
6917
int wc_ecc_free(ecc_key* key)
6918
0
{
6919
0
    if (key == NULL) {
6920
0
        return 0;
6921
0
    }
6922
6923
0
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
6924
0
    if (key->sign_k != NULL) {
6925
0
        mp_forcezero(key->sign_k);
6926
0
        mp_free(key->sign_k);
6927
0
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6928
0
    }
6929
0
#endif
6930
6931
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6932
    #ifdef WC_ASYNC_ENABLE_ECC
6933
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
6934
    #endif
6935
    wc_ecc_free_async(key);
6936
#endif
6937
6938
#ifdef WOLFSSL_QNX_CAAM
6939
    /* free secure memory */
6940
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
6941
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
6942
       caamFreePart(key->partNum);
6943
    }
6944
#endif
6945
6946
#ifdef WOLFSSL_SE050
6947
    se050_ecc_free_key(key);
6948
#endif
6949
6950
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6951
    atmel_ecc_free(key->slot);
6952
    key->slot = ATECC_INVALID_SLOT;
6953
#endif /* WOLFSSL_ATECC508A */
6954
6955
#ifdef WOLFSSL_KCAPI_ECC
6956
    KcapiEcc_Free(key);
6957
#endif
6958
6959
0
    mp_clear(key->pubkey.x);
6960
0
    mp_clear(key->pubkey.y);
6961
0
    mp_clear(key->pubkey.z);
6962
6963
0
    mp_forcezero(&key->k);
6964
6965
0
#ifdef WOLFSSL_CUSTOM_CURVES
6966
0
    if (key->deallocSet && key->dp != NULL)
6967
0
        wc_ecc_free_curve(key->dp, key->heap);
6968
0
#endif
6969
6970
#ifdef WOLFSSL_CHECK_MEM_ZERO
6971
    wc_MemZero_Check(key, sizeof(ecc_key));
6972
#endif
6973
6974
0
    return 0;
6975
0
}
6976
6977
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6978
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
6979
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
6980
/* Handles add failure cases:
6981
 *
6982
 * Before add:
6983
 *   Case 1: A is infinity
6984
 *        -> Copy B into result.
6985
 *   Case 2: B is infinity
6986
 *        -> Copy A into result.
6987
 *   Case 3: x and z are the same in A and B (same x value in affine)
6988
 *     Case 3a: y values the same - same point
6989
 *           -> Double instead of add.
6990
 *     Case 3b: y values different - negative of the other when points on curve
6991
 *           -> Need to set result to infinity.
6992
 *
6993
 * After add:
6994
 *   Case 1: A and B are the same point (maybe different z)
6995
 *           (Result was: x == y == z == 0)
6996
 *        -> Need to double instead.
6997
 *
6998
 *   Case 2: A + B = <infinity> = 0.
6999
 *           (Result was: z == 0, x and/or y not 0)
7000
 *        -> Need to set result to infinity.
7001
 */
7002
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
7003
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
7004
0
{
7005
0
    int err;
7006
7007
0
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
7008
        /* A is infinity. */
7009
0
        err = wc_ecc_copy_point(B, R);
7010
0
    }
7011
0
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
7012
        /* B is infinity. */
7013
0
        err = wc_ecc_copy_point(A, R);
7014
0
    }
7015
0
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
7016
        /* x ordinattes the same. */
7017
0
        if (mp_cmp(A->y, B->y) == MP_EQ) {
7018
            /* A = B */
7019
0
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
7020
0
        }
7021
0
        else {
7022
            /* A = -B */
7023
0
            err = mp_set(R->x, 0);
7024
0
            if (err == MP_OKAY)
7025
0
                err = mp_set(R->y, 0);
7026
0
            if (err == MP_OKAY)
7027
0
                err = mp_set(R->z, 1);
7028
0
            if ((err == MP_OKAY) && (infinity != NULL))
7029
0
                *infinity = 1;
7030
0
        }
7031
0
    }
7032
0
    else {
7033
0
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
7034
0
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
7035
            /* When all zero then should have done a double */
7036
0
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
7037
0
                if (mp_iszero(B->z)) {
7038
0
                    err = wc_ecc_copy_point(B, R);
7039
0
                    if (err == MP_OKAY) {
7040
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
7041
0
                    }
7042
0
                    if (err == MP_OKAY) {
7043
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
7044
0
                    }
7045
0
                }
7046
0
                else {
7047
0
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
7048
0
                }
7049
0
            }
7050
            /* When only Z zero then result is infinity */
7051
0
            else {
7052
0
                err = mp_set(R->x, 0);
7053
0
                if (err == MP_OKAY)
7054
0
                    err = mp_set(R->y, 0);
7055
0
                if (err == MP_OKAY)
7056
0
                    err = mp_set(R->z, 1);
7057
0
                if ((err == MP_OKAY) && (infinity != NULL))
7058
0
                    *infinity = 1;
7059
0
            }
7060
0
        }
7061
0
    }
7062
7063
0
    return err;
7064
0
}
7065
7066
/* Handles when P is the infinity point.
7067
 *
7068
 * Double infinity -> infinity.
7069
 * Otherwise do normal double - which can't lead to infinity as odd order.
7070
 */
7071
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
7072
                                  mp_int* modulus, mp_digit mp)
7073
0
{
7074
0
    int err;
7075
7076
0
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
7077
        /* P is infinity. */
7078
0
        err = wc_ecc_copy_point(P, R);
7079
0
    }
7080
0
    else {
7081
0
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
7082
0
    }
7083
7084
0
    return err;
7085
0
}
7086
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A
7087
          && !WOLFSSL_CRYPTOCELL && !WOLFSSL_SP_MATH */
7088
7089
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
7090
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \
7091
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
7092
#ifdef ECC_SHAMIR
7093
7094
/** Computes kA*A + kB*B = C using Shamir's Trick
7095
  A        First point to multiply
7096
  kA       What to multiple A by
7097
  B        Second point to multiply
7098
  kB       What to multiple B by
7099
  C        [out] Destination point (can overlap with A or B)
7100
  a        ECC curve parameter a
7101
  modulus  Modulus for curve
7102
  return MP_OKAY on success
7103
*/
7104
#ifdef FP_ECC
7105
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
7106
                             ecc_point* B, mp_int* kB,
7107
                             ecc_point* C, mp_int* a, mp_int* modulus,
7108
                             void* heap)
7109
#else
7110
int ecc_mul2add(ecc_point* A, mp_int* kA,
7111
                    ecc_point* B, mp_int* kB,
7112
                    ecc_point* C, mp_int* a, mp_int* modulus,
7113
                    void* heap)
7114
#endif
7115
0
{
7116
#ifdef WOLFSSL_SMALL_STACK_CACHE
7117
  ecc_key        *key = NULL;
7118
#endif
7119
0
#ifdef WOLFSSL_SMALL_STACK
7120
0
  ecc_point**    precomp = NULL;
7121
#else
7122
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
7123
  #ifdef WOLFSSL_NO_MALLOC
7124
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
7125
  #endif
7126
#endif
7127
0
  unsigned       bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
7128
#ifdef WOLFSSL_NO_MALLOC
7129
  unsigned char tA[ECC_BUFSIZE];
7130
  unsigned char tB[ECC_BUFSIZE];
7131
#else
7132
0
  unsigned char* tA = NULL;
7133
0
  unsigned char* tB = NULL;
7134
0
#endif
7135
0
  int            err = MP_OKAY, first, x, y;
7136
0
  mp_digit       mp = 0;
7137
7138
  /* argchks */
7139
0
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
7140
0
                                                         modulus == NULL) {
7141
0
     return ECC_BAD_ARG_E;
7142
0
  }
7143
7144
0
#ifndef WOLFSSL_NO_MALLOC
7145
  /* allocate memory */
7146
0
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7147
0
  if (tA == NULL) {
7148
0
     return GEN_MEM_ERR;
7149
0
  }
7150
0
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7151
0
  if (tB == NULL) {
7152
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7153
0
     return GEN_MEM_ERR;
7154
0
  }
7155
0
#endif
7156
7157
0
#ifdef WOLFSSL_SMALL_STACK
7158
  #ifdef WOLFSSL_SMALL_STACK_CACHE
7159
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
7160
  if (key == NULL) {
7161
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7162
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7163
     return GEN_MEM_ERR;
7164
  }
7165
  #endif
7166
0
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
7167
0
                                                       DYNAMIC_TYPE_ECC_BUFFER);
7168
0
  if (precomp == NULL) {
7169
0
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7170
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7171
  #ifdef WOLFSSL_SMALL_STACK_CACHE
7172
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
7173
  #endif
7174
0
     return GEN_MEM_ERR;
7175
0
  }
7176
0
#endif
7177
#ifdef WOLFSSL_SMALL_STACK_CACHE
7178
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7179
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7180
#ifdef ALT_ECC_SIZE
7181
  key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7182
  key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7183
  key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7184
#endif
7185
7186
  if (key->t1 == NULL || key->t2 == NULL
7187
#ifdef ALT_ECC_SIZE
7188
     || key.x == NULL || key.y == NULL || key.z == NULL
7189
#endif
7190
  ) {
7191
#ifdef ALT_ECC_SIZE
7192
      XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
7193
      XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
7194
      XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
7195
#endif
7196
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
7197
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
7198
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
7199
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7200
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7201
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
7202
      return MEMORY_E;
7203
  }
7204
  C->key = key;
7205
#endif /* WOLFSSL_SMALL_STACK_CACHE */
7206
7207
  /* init variables */
7208
0
  XMEMSET(tA, 0, ECC_BUFSIZE);
7209
0
  XMEMSET(tB, 0, ECC_BUFSIZE);
7210
#ifndef WOLFSSL_SMALL_STACK
7211
  XMEMSET(precomp, 0, sizeof(precomp));
7212
#else
7213
0
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
7214
0
#endif
7215
#ifdef WOLFSSL_CHECK_MEM_ZERO
7216
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
7217
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
7218
#endif
7219
7220
  /* get sizes */
7221
0
  lenA = mp_unsigned_bin_size(kA);
7222
0
  lenB = mp_unsigned_bin_size(kB);
7223
0
  len  = MAX(lenA, lenB);
7224
7225
  /* sanity check */
7226
0
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
7227
0
    err = BAD_FUNC_ARG;
7228
0
  }
7229
7230
0
  if (err == MP_OKAY) {
7231
    /* extract and justify kA */
7232
0
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
7233
7234
    /* extract and justify kB */
7235
0
    if (err == MP_OKAY)
7236
0
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
7237
7238
    /* allocate the table */
7239
0
    if (err == MP_OKAY) {
7240
0
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
7241
        #ifdef WOLFSSL_NO_MALLOC
7242
            precomp[x] = &lcl_precomp[x];
7243
        #endif
7244
0
            err = wc_ecc_new_point_ex(&precomp[x], heap);
7245
0
            if (err != MP_OKAY)
7246
0
                break;
7247
        #ifdef WOLFSSL_SMALL_STACK_CACHE
7248
            precomp[x]->key = key;
7249
        #endif
7250
0
        }
7251
0
    }
7252
0
  }
7253
7254
0
  if (err == MP_OKAY)
7255
    /* init montgomery reduction */
7256
0
    err = mp_montgomery_setup(modulus, &mp);
7257
7258
0
  if (err == MP_OKAY) {
7259
0
  #ifdef WOLFSSL_SMALL_STACK
7260
0
    mp_int* mu;
7261
  #else
7262
    mp_int  mu[1];
7263
  #endif
7264
0
  #ifdef WOLFSSL_SMALL_STACK
7265
0
    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7266
0
    if (mu == NULL)
7267
0
        err = MEMORY_E;
7268
0
  #endif
7269
0
    if (err == MP_OKAY) {
7270
0
        err = mp_init(mu);
7271
0
    }
7272
0
    if (err == MP_OKAY) {
7273
0
      err = mp_montgomery_calc_normalization(mu, modulus);
7274
7275
0
      if (err == MP_OKAY)
7276
        /* copy ones ... */
7277
0
        err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
7278
7279
0
      if (err == MP_OKAY)
7280
0
        err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
7281
0
      if (err == MP_OKAY)
7282
0
        err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
7283
7284
0
      if (err == MP_OKAY)
7285
0
        err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
7286
0
      if (err == MP_OKAY)
7287
0
        err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
7288
0
      if (err == MP_OKAY)
7289
0
        err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
7290
7291
      /* done with mu */
7292
0
      mp_clear(mu);
7293
0
    }
7294
0
  #ifdef WOLFSSL_SMALL_STACK
7295
0
    if (mu != NULL) {
7296
0
      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
7297
0
    }
7298
0
  #endif
7299
0
  }
7300
7301
0
  if (err == MP_OKAY) {
7302
    /* precomp [i,0](A + B) table */
7303
0
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
7304
0
  }
7305
0
  if (err == MP_OKAY) {
7306
0
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
7307
0
                                                          a, modulus, mp, NULL);
7308
0
  }
7309
7310
0
  if (err == MP_OKAY) {
7311
    /* precomp [0,i](A + B) table */
7312
0
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
7313
0
  }
7314
0
  if (err == MP_OKAY) {
7315
0
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
7316
0
                                                             modulus, mp, NULL);
7317
0
  }
7318
7319
0
  if (err == MP_OKAY) {
7320
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
7321
0
    for (x = 1; x < 4; x++) {
7322
0
      for (y = 1; y < 4; y++) {
7323
0
        if (err == MP_OKAY) {
7324
0
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
7325
0
                                                  precomp[x+(y<<2)], a, modulus,
7326
0
                                                  mp, NULL);
7327
0
        }
7328
0
      }
7329
0
    }
7330
0
  }
7331
7332
0
  if (err == MP_OKAY) {
7333
0
    nibble  = 3;
7334
0
    first   = 1;
7335
0
    bitbufA = tA[0];
7336
0
    bitbufB = tB[0];
7337
7338
    /* for every byte of the multiplicands */
7339
0
    for (x = 0; x < (int)len || nibble != 3; ) {
7340
        /* grab a nibble */
7341
0
        if (++nibble == 4) {
7342
0
            if (x == (int)len) break;
7343
0
            bitbufA = tA[x];
7344
0
            bitbufB = tB[x];
7345
0
            nibble  = 0;
7346
0
            x++;
7347
0
        }
7348
7349
        /* extract two bits from both, shift/update */
7350
0
        nA = (bitbufA >> 6) & 0x03;
7351
0
        nB = (bitbufB >> 6) & 0x03;
7352
0
        bitbufA = (bitbufA << 2) & 0xFF;
7353
0
        bitbufB = (bitbufB << 2) & 0xFF;
7354
7355
        /* if both zero, if first, continue */
7356
0
        if ((nA == 0) && (nB == 0) && (first == 1)) {
7357
0
            continue;
7358
0
        }
7359
7360
        /* double twice, only if this isn't the first */
7361
0
        if (first == 0) {
7362
            /* double twice */
7363
0
            if (err == MP_OKAY)
7364
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
7365
0
            if (err == MP_OKAY)
7366
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
7367
0
            else
7368
0
                break;
7369
0
        }
7370
7371
        /* if not both zero */
7372
0
        if ((nA != 0) || (nB != 0)) {
7373
0
            int i = nA + (nB<<2);
7374
0
            if (first == 1) {
7375
                /* if first, copy from table */
7376
0
                first = 0;
7377
0
                if (err == MP_OKAY)
7378
0
                    err = mp_copy(precomp[i]->x, C->x);
7379
7380
0
                if (err == MP_OKAY)
7381
0
                    err = mp_copy(precomp[i]->y, C->y);
7382
7383
0
                if (err == MP_OKAY)
7384
0
                    err = mp_copy(precomp[i]->z, C->z);
7385
0
                else
7386
0
                    break;
7387
0
            } else {
7388
                /* if not first, add from table */
7389
0
                if (err == MP_OKAY)
7390
0
                    err = ecc_projective_add_point_safe(C, precomp[i],
7391
0
                                                        C, a, modulus, mp,
7392
0
                                                        &first);
7393
0
                if (err != MP_OKAY)
7394
0
                    break;
7395
0
            }
7396
0
        }
7397
0
    }
7398
0
  }
7399
7400
  /* reduce to affine */
7401
0
  if (err == MP_OKAY)
7402
0
    err = ecc_map(C, modulus, mp);
7403
7404
  /* clean up */
7405
0
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
7406
0
     wc_ecc_del_point_ex(precomp[x], heap);
7407
0
  }
7408
7409
0
  ForceZero(tA, ECC_BUFSIZE);
7410
0
  ForceZero(tB, ECC_BUFSIZE);
7411
#ifdef WOLFSSL_SMALL_STACK_CACHE
7412
#ifdef ALT_ECC_SIZE
7413
  XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
7414
  XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
7415
  XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
7416
#endif
7417
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
7418
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
7419
  XFREE(key, heap, DYNAMIC_TYPE_ECC);
7420
  C->key = NULL;
7421
#endif
7422
0
#ifdef WOLFSSL_SMALL_STACK
7423
0
  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
7424
0
#endif
7425
0
#ifndef WOLFSSL_NO_MALLOC
7426
0
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7427
0
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7428
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
7429
  wc_MemZero_Check(tB, ECC_BUFSIZE);
7430
  wc_MemZero_Check(tA, ECC_BUFSIZE);
7431
#endif
7432
0
  return err;
7433
0
}
7434
7435
#endif /* ECC_SHAMIR */
7436
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
7437
        * !WOLFSSL_CRYPTOCEL */
7438
7439
7440
#ifdef HAVE_ECC_VERIFY
7441
#ifndef NO_ASN
7442
/* verify
7443
 *
7444
 * w  = s^-1 mod n
7445
 * u1 = xw
7446
 * u2 = rw
7447
 * X = u1*G + u2*Q
7448
 * v = X_x1 mod n
7449
 * accept if v == r
7450
 */
7451
7452
/**
7453
 Verify an ECC signature
7454
 sig         The signature to verify
7455
 siglen      The length of the signature (octets)
7456
 hash        The hash (message digest) that was signed
7457
 hashlen     The length of the hash (octets)
7458
 res         Result of signature, 1==valid, 0==invalid
7459
 key         The corresponding public ECC key
7460
 return      MP_OKAY if successful (even if the signature is not valid)
7461
 */
7462
WOLFSSL_ABI
7463
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
7464
                       word32 hashlen, int* res, ecc_key* key)
7465
0
{
7466
0
    int err;
7467
7468
0
    mp_int *r = NULL, *s = NULL;
7469
#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)) && \
7470
    !defined(WOLFSSL_SMALL_STACK)
7471
    mp_int r_lcl, s_lcl;
7472
#endif
7473
#ifdef WOLFSSL_ASYNC_CRYPT
7474
    int isPrivateKeyOnly = 0;
7475
#endif
7476
7477
0
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
7478
0
        return ECC_BAD_ARG_E;
7479
0
    }
7480
7481
0
#ifdef WOLF_CRYPTO_CB
7482
0
    if (key->devId != INVALID_DEVID) {
7483
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
7484
0
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
7485
0
        if (err != CRYPTOCB_UNAVAILABLE)
7486
0
            return err;
7487
        /* fall-through when unavailable */
7488
0
    #endif
7489
0
    }
7490
    #ifdef WOLF_CRYPTO_CB_ONLY_ECC
7491
    else {
7492
        err = NO_VALID_DEVID;
7493
    }
7494
    #endif
7495
0
#endif
7496
7497
0
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
7498
7499
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7500
    err = wc_ecc_alloc_async(key);
7501
    if (err != 0)
7502
        return err;
7503
    r = key->r;
7504
    s = key->s;
7505
#else
7506
    #ifndef WOLFSSL_SMALL_STACK
7507
    r = &r_lcl;
7508
    s = &s_lcl;
7509
    #else
7510
0
    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7511
0
    if (r == NULL)
7512
0
        return MEMORY_E;
7513
0
    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7514
0
    if (s == NULL) {
7515
0
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7516
0
        return MEMORY_E;
7517
0
    }
7518
0
    #endif
7519
0
    XMEMSET(r, 0, sizeof(mp_int));
7520
0
    XMEMSET(s, 0, sizeof(mp_int));
7521
0
#endif /* WOLFSSL_ASYNC_CRYPT */
7522
7523
0
    switch (key->state) {
7524
0
        case ECC_STATE_NONE:
7525
0
        case ECC_STATE_VERIFY_DECODE:
7526
0
            key->state = ECC_STATE_VERIFY_DECODE;
7527
7528
            /* default to invalid signature */
7529
0
            *res = 0;
7530
7531
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
7532
             * If either of those don't allocate correctly, none of
7533
             * the rest of this function will execute, and everything
7534
             * gets cleaned up at the end. */
7535
            /* decode DSA header */
7536
0
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
7537
0
            if (err < 0) {
7538
0
                break;
7539
0
            }
7540
0
            FALL_THROUGH;
7541
7542
0
        case ECC_STATE_VERIFY_DO:
7543
0
            key->state = ECC_STATE_VERIFY_DO;
7544
        #ifdef WOLFSSL_ASYNC_CRYPT
7545
            if (key->type == ECC_PRIVATEKEY_ONLY) {
7546
                isPrivateKeyOnly = 1;
7547
            }
7548
        #endif
7549
0
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
7550
7551
0
        #ifndef WOLFSSL_ASYNC_CRYPT
7552
            /* done with R/S */
7553
0
            mp_clear(r);
7554
0
            mp_clear(s);
7555
0
        #ifdef WOLFSSL_SMALL_STACK
7556
0
            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
7557
0
            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7558
0
            r = NULL;
7559
0
            s = NULL;
7560
0
        #endif
7561
0
        #endif
7562
7563
0
            if (err < 0) {
7564
0
                break;
7565
0
            }
7566
0
            FALL_THROUGH;
7567
7568
0
        case ECC_STATE_VERIFY_RES:
7569
0
            key->state = ECC_STATE_VERIFY_RES;
7570
0
            err = 0;
7571
0
            break;
7572
7573
0
        default:
7574
0
            err = BAD_STATE_E;
7575
0
    }
7576
7577
#ifdef WOLFSSL_ASYNC_CRYPT
7578
    /* if async pending then return and skip done cleanup below */
7579
    if (err == WC_PENDING_E) {
7580
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
7581
            key->state++;
7582
        return err;
7583
    }
7584
#endif
7585
7586
    /* cleanup */
7587
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7588
    wc_ecc_free_async(key);
7589
#elif defined(WOLFSSL_SMALL_STACK)
7590
0
    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
7591
0
    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7592
0
    r = NULL;
7593
0
    s = NULL;
7594
0
#endif
7595
7596
    /* make sure required variables are reset */
7597
0
    wc_ecc_reset(key);
7598
#else
7599
    (void)siglen;
7600
    (void)hashlen;
7601
    #ifndef WOLFSSL_SMALL_STACK
7602
    (void)s_lcl;
7603
    (void)r_lcl;
7604
    #endif
7605
    (void)s;
7606
    (void)r;
7607
    (void)err;
7608
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
7609
7610
0
    return err;
7611
0
}
7612
#endif /* !NO_ASN */
7613
7614
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
7615
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
7616
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
7617
0
{
7618
0
    int err = MP_OKAY;
7619
0
    DECLARE_CURVE_SPECS(1);
7620
7621
0
    ALLOC_CURVE_SPECS(1, err);
7622
0
    if (err == MP_OKAY) {
7623
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7624
0
    }
7625
0
    if (err != 0) {
7626
0
        FREE_CURVE_SPECS();
7627
0
        return err;
7628
0
    }
7629
7630
0
    if (mp_iszero(r) || mp_iszero(s)) {
7631
0
        err = MP_ZERO_E;
7632
0
    }
7633
0
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
7634
0
        err = MP_VAL;
7635
0
    }
7636
0
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
7637
0
        err = MP_VAL;
7638
0
    }
7639
7640
0
    wc_ecc_curve_free(curve);
7641
0
    FREE_CURVE_SPECS();
7642
0
    return err;
7643
0
}
7644
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
7645
7646
7647
/**
7648
   Verify an ECC signature
7649
   r           The signature R component to verify
7650
   s           The signature S component to verify
7651
   hash        The hash (message digest) that was signed
7652
   hashlen     The length of the hash (octets)
7653
   res         Result of signature, 1==valid, 0==invalid
7654
   key         The corresponding public ECC key
7655
   return      MP_OKAY if successful (even if the signature is not valid)
7656
*/
7657
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
7658
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
7659
                    word32 hashlen, int* res, ecc_key* key)
7660
#if defined(WOLFSSL_STM32_PKA)
7661
{
7662
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
7663
}
7664
#elif defined(WOLFSSL_PSOC6_CRYPTO)
7665
{
7666
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
7667
}
7668
#else
7669
0
{
7670
0
   int           err;
7671
0
   word32        keySz = 0;
7672
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7673
   byte sigRS[ATECC_KEY_SIZE*2];
7674
#elif defined(WOLFSSL_CRYPTOCELL)
7675
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
7676
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
7677
   word32 msgLenInBytes = hashlen;
7678
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
7679
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
7680
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
7681
#elif defined(WOLFSSL_KCAPI_ECC)
7682
   byte sigRS[MAX_ECC_BYTES*2];
7683
#elif defined(WOLFSSL_SE050)
7684
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
7685
#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
7686
0
   int          did_init = 0;
7687
0
   ecc_point    *mG = NULL, *mQ = NULL;
7688
   #ifdef WOLFSSL_NO_MALLOC
7689
   ecc_point    lcl_mG, lcl_mQ;
7690
   #endif
7691
0
   #ifdef WOLFSSL_SMALL_STACK
7692
0
   mp_int*       v = NULL;
7693
0
   mp_int*       w = NULL;
7694
0
   mp_int*       u1 = NULL;
7695
0
   mp_int*       u2 = NULL;
7696
0
      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7697
0
   mp_int*       e_lcl = NULL;
7698
0
      #endif
7699
   #else /* WOLFSSL_SMALL_STACK */
7700
   mp_int        v[1];
7701
   mp_int        w[1];
7702
   mp_int        u1[1];
7703
   mp_int        u2[1];
7704
      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7705
   mp_int        e_lcl[1];
7706
      #endif
7707
   #endif /* WOLFSSL_SMALL_STACK */
7708
0
   mp_int*       e;
7709
0
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7710
0
#endif
7711
7712
0
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
7713
0
       return ECC_BAD_ARG_E;
7714
7715
   /* default to invalid signature */
7716
0
   *res = 0;
7717
7718
   /* is the IDX valid ?  */
7719
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7720
0
      return ECC_BAD_ARG_E;
7721
0
   }
7722
7723
0
   err = wc_ecc_check_r_s_range(key, r, s);
7724
0
   if (err != MP_OKAY) {
7725
0
      return err;
7726
0
   }
7727
7728
0
   keySz = key->dp->size;
7729
7730
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7731
       defined(WOLFSSL_ASYNC_CRYPT_TEST)
7732
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7733
        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) {
7734
            WC_ASYNC_TEST* testDev = &key->asyncDev.test;
7735
            testDev->eccVerify.r = r;
7736
            testDev->eccVerify.s = s;
7737
            testDev->eccVerify.hash = hash;
7738
            testDev->eccVerify.hashlen = hashlen;
7739
            testDev->eccVerify.stat = res;
7740
            testDev->eccVerify.key = key;
7741
            return WC_PENDING_E;
7742
        }
7743
    }
7744
#endif
7745
7746
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
7747
    defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) || \
7748
    defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_SE050)
7749
7750
    /* Extract R and S with front zero padding (if required) */
7751
    XMEMSET(sigRS, 0, keySz * 2);
7752
    err = mp_to_unsigned_bin(r, sigRS +
7753
                                (keySz - mp_unsigned_bin_size(r)));
7754
    if (err != MP_OKAY) {
7755
        return err;
7756
    }
7757
    err = mp_to_unsigned_bin(s, sigRS + keySz +
7758
                                (keySz - mp_unsigned_bin_size(s)));
7759
    if (err != MP_OKAY) {
7760
        return err;
7761
    }
7762
7763
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7764
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
7765
    if (err != 0) {
7766
       return err;
7767
    }
7768
    (void)hashlen;
7769
#elif defined(WOLFSSL_CRYPTOCELL)
7770
7771
   /* truncate if hash is longer than key size */
7772
   if (msgLenInBytes > keySz) {
7773
       msgLenInBytes = keySz;
7774
   }
7775
   hash_mode = cc310_hashModeECC(msgLenInBytes);
7776
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
7777
       /* hash_mode = */ cc310_hashModeECC(keySz);
7778
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
7779
   }
7780
7781
   /* verify the signature using the public key */
7782
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
7783
                           &key->ctx.pubKey,
7784
                           hash_mode,
7785
                           &sigRS[0],
7786
                           keySz*2,
7787
                           (byte*)hash,
7788
                           msgLenInBytes);
7789
7790
   if (err != SA_SILIB_RET_OK) {
7791
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
7792
       return err;
7793
   }
7794
   /* valid signature if we get to this point */
7795
   *res = 1;
7796
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
7797
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
7798
                                hash, hashlen,
7799
                                res, key);
7800
#elif defined(WOLFSSL_KCAPI_ECC)
7801
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
7802
    if (err == 0) {
7803
        *res = 1;
7804
    }
7805
#elif defined(WOLFSSL_SE050)
7806
    err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, keySz * 2, key, res);
7807
#endif
7808
7809
#else
7810
  /* checking if private key with no public part */
7811
0
  if (key->type == ECC_PRIVATEKEY_ONLY) {
7812
0
      WOLFSSL_MSG("Verify called with private key, generating public part");
7813
0
      err = ecc_make_pub_ex(key, NULL, NULL, NULL);
7814
0
      if (err != MP_OKAY) {
7815
0
           WOLFSSL_MSG("Unable to extract public key");
7816
0
           return err;
7817
0
      }
7818
0
  }
7819
7820
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
7821
  if (key->handle != -1) {
7822
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
7823
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7824
  }
7825
  if (wolfSSL_GetHandleCbSet() == 1) {
7826
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
7827
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7828
  }
7829
#endif
7830
7831
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
7832
    if (key->idx == ECC_CUSTOM_IDX || (1
7833
    #ifndef WOLFSSL_SP_NO_256
7834
         && ecc_sets[key->idx].id != ECC_SECP256R1
7835
    #endif
7836
    #ifdef WOLFSSL_SP_384
7837
         && ecc_sets[key->idx].id != ECC_SECP384R1
7838
    #endif
7839
    #ifdef WOLFSSL_SP_521
7840
         && ecc_sets[key->idx].id != ECC_SECP521R1
7841
    #endif
7842
        )) {
7843
        return WC_KEY_SIZE_E;
7844
    }
7845
#endif
7846
7847
#if defined(WOLFSSL_HAVE_SP_ECC)
7848
    if (key->idx != ECC_CUSTOM_IDX
7849
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7850
        && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC
7851
    #endif
7852
    ) {
7853
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7854
        /* perform blocking call to non-blocking function */
7855
        ecc_nb_ctx_t nb_ctx;
7856
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7857
        err = NOT_COMPILED_IN; /* set default error */
7858
    #endif
7859
    #ifndef WOLFSSL_SP_NO_256
7860
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7861
        #ifdef WC_ECC_NONBLOCK
7862
            if (key->nb_ctx) {
7863
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
7864
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
7865
                    key->heap);
7866
            }
7867
            #ifdef WC_ECC_NONBLOCK_ONLY
7868
            do { /* perform blocking call to non-blocking function */
7869
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
7870
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
7871
                    key->heap);
7872
            } while (err == FP_WOULDBLOCK);
7873
            return err;
7874
            #endif
7875
        #endif /* WC_ECC_NONBLOCK */
7876
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7877
            {
7878
                int ret;
7879
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7880
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
7881
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7882
                RESTORE_VECTOR_REGISTERS();
7883
                return ret;
7884
            }
7885
        #endif
7886
        }
7887
    #endif
7888
    #ifdef WOLFSSL_SP_384
7889
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7890
        #ifdef WC_ECC_NONBLOCK
7891
            if (key->nb_ctx) {
7892
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
7893
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
7894
                    key->heap);
7895
            }
7896
            #ifdef WC_ECC_NONBLOCK_ONLY
7897
            do { /* perform blocking call to non-blocking function */
7898
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
7899
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
7900
                    key->heap);
7901
            } while (err == FP_WOULDBLOCK);
7902
            return err;
7903
            #endif
7904
        #endif /* WC_ECC_NONBLOCK */
7905
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7906
            {
7907
                int ret;
7908
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7909
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
7910
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7911
                RESTORE_VECTOR_REGISTERS();
7912
                return ret;
7913
            }
7914
        #endif
7915
        }
7916
    #endif
7917
    #ifdef WOLFSSL_SP_521
7918
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7919
        #ifdef WC_ECC_NONBLOCK
7920
            if (key->nb_ctx) {
7921
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
7922
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
7923
                    key->heap);
7924
            }
7925
            #ifdef WC_ECC_NONBLOCK_ONLY
7926
            do { /* perform blocking call to non-blocking function */
7927
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
7928
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
7929
                    key->heap);
7930
            } while (err == FP_WOULDBLOCK);
7931
            return err;
7932
            #endif
7933
        #endif /* WC_ECC_NONBLOCK */
7934
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7935
            {
7936
                int ret;
7937
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7938
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
7939
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7940
                RESTORE_VECTOR_REGISTERS();
7941
                return ret;
7942
            }
7943
        #endif
7944
        }
7945
    #endif
7946
    }
7947
#endif
7948
7949
0
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
7950
0
   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7951
0
   if (err != 0) {
7952
0
      return err;
7953
0
   }
7954
7955
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7956
   err = wc_ecc_alloc_mpint(key, &key->e);
7957
   if (err != 0) {
7958
      FREE_CURVE_SPECS();
7959
      return err;
7960
   }
7961
   e = key->e;
7962
#else
7963
0
#ifdef WOLFSSL_SMALL_STACK
7964
0
   e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7965
0
   if (e_lcl == NULL) {
7966
0
       FREE_CURVE_SPECS();
7967
0
       return MEMORY_E;
7968
0
   }
7969
0
#endif
7970
0
   e = e_lcl;
7971
0
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
7972
7973
0
   err = mp_init(e);
7974
0
   if (err != MP_OKAY) {
7975
0
      FREE_CURVE_SPECS();
7976
0
      return MEMORY_E;
7977
0
   }
7978
7979
   /* read in the specs for this curve */
7980
0
   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7981
7982
   /* read hash */
7983
0
   if (err == MP_OKAY) {
7984
       /* we may need to truncate if hash is longer than key size */
7985
0
       unsigned int orderBits = mp_count_bits(curve->order);
7986
7987
       /* truncate down to byte size, may be all that's needed */
7988
0
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
7989
0
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7990
0
       err = mp_read_unsigned_bin(e, hash, hashlen);
7991
7992
       /* may still need bit truncation too */
7993
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
7994
0
           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
7995
0
   }
7996
7997
   /* check for async hardware acceleration */
7998
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7999
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8000
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8001
   #ifdef HAVE_CAVIUM_V
8002
      if (NitroxEccIsCurveSupported(key))
8003
   #endif
8004
      {
8005
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8006
          if (err == MP_OKAY)
8007
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
8008
          if (err == MP_OKAY)
8009
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
8010
          if (err == MP_OKAY)
8011
          #ifdef HAVE_CAVIUM_V
8012
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
8013
                    &key->pubkey.y->raw, &r->raw, &s->raw,
8014
                    &curve->prime->raw, &curve->order->raw, res);
8015
          #else
8016
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
8017
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
8018
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
8019
                    &curve->Gx->raw, &curve->Gy->raw, res);
8020
          #endif
8021
8022
      #ifndef HAVE_CAVIUM_V
8023
          mp_clear(e);
8024
      #endif
8025
          wc_ecc_curve_free(curve);
8026
          FREE_CURVE_SPECS();
8027
8028
          return err;
8029
      }
8030
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8031
   }
8032
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8033
8034
0
#ifdef WOLFSSL_SMALL_STACK
8035
0
   if (err == MP_OKAY) {
8036
0
       v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8037
0
       if (v == NULL)
8038
0
           err = MEMORY_E;
8039
0
   }
8040
0
   if (err == MP_OKAY) {
8041
0
       w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8042
0
       if (w == NULL)
8043
0
           err = MEMORY_E;
8044
0
   }
8045
0
   if (err == MP_OKAY) {
8046
0
       u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8047
0
       if (u1 == NULL)
8048
0
           err = MEMORY_E;
8049
0
   }
8050
0
   if (err == MP_OKAY) {
8051
0
       u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8052
0
       if (u2 == NULL)
8053
0
           err = MEMORY_E;
8054
0
   }
8055
0
#endif
8056
8057
   /* allocate ints */
8058
0
   if (err == MP_OKAY) {
8059
0
       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
8060
0
          err = MEMORY_E;
8061
0
       } else {
8062
0
           did_init = 1;
8063
0
       }
8064
0
   }
8065
8066
   /* allocate points */
8067
0
   if (err == MP_OKAY) {
8068
   #ifdef WOLFSSL_NO_MALLOC
8069
       mG = &lcl_mG;
8070
   #endif
8071
0
       err = wc_ecc_new_point_ex(&mG, key->heap);
8072
0
   }
8073
0
   if (err == MP_OKAY) {
8074
   #ifdef WOLFSSL_NO_MALLOC
8075
       mQ = &lcl_mQ;
8076
   #endif
8077
0
       err = wc_ecc_new_point_ex(&mQ, key->heap);
8078
0
   }
8079
8080
   /*  w  = s^-1 mod n */
8081
0
   if (err == MP_OKAY)
8082
0
       err = mp_invmod(s, curve->order, w);
8083
8084
   /* u1 = ew */
8085
0
   if (err == MP_OKAY)
8086
0
       err = mp_mulmod(e, w, curve->order, u1);
8087
8088
   /* u2 = rw */
8089
0
   if (err == MP_OKAY)
8090
0
       err = mp_mulmod(r, w, curve->order, u2);
8091
8092
   /* find mG and mQ */
8093
0
   if (err == MP_OKAY)
8094
0
       err = mp_copy(curve->Gx, mG->x);
8095
0
   if (err == MP_OKAY)
8096
0
       err = mp_copy(curve->Gy, mG->y);
8097
0
   if (err == MP_OKAY)
8098
0
       err = mp_set(mG->z, 1);
8099
8100
0
   if (err == MP_OKAY)
8101
0
       err = mp_copy(key->pubkey.x, mQ->x);
8102
0
   if (err == MP_OKAY)
8103
0
       err = mp_copy(key->pubkey.y, mQ->y);
8104
0
   if (err == MP_OKAY)
8105
0
       err = mp_copy(key->pubkey.z, mQ->z);
8106
8107
#if defined(FREESCALE_LTC_ECC)
8108
   /* use PKHA to compute u1*mG + u2*mQ */
8109
   if (err == MP_OKAY)
8110
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
8111
   if (err == MP_OKAY)
8112
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
8113
   if (err == MP_OKAY)
8114
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
8115
#else
8116
#ifndef ECC_SHAMIR
8117
    if (err == MP_OKAY)
8118
    {
8119
        mp_digit mp = 0;
8120
8121
        if (!mp_iszero(u1)) {
8122
            /* compute u1*mG + u2*mQ = mG */
8123
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
8124
                                                                     key->heap);
8125
            if (err == MP_OKAY) {
8126
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
8127
                                                                     key->heap);
8128
            }
8129
8130
            /* find the montgomery mp */
8131
            if (err == MP_OKAY)
8132
                err = mp_montgomery_setup(curve->prime, &mp);
8133
8134
            /* add them */
8135
            if (err == MP_OKAY)
8136
                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
8137
                                                        curve->prime, mp, NULL);
8138
        }
8139
        else {
8140
            /* compute 0*mG + u2*mQ = mG */
8141
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
8142
                                                                     key->heap);
8143
            /* find the montgomery mp */
8144
            if (err == MP_OKAY)
8145
                err = mp_montgomery_setup(curve->prime, &mp);
8146
        }
8147
8148
        /* reduce */
8149
        if (err == MP_OKAY)
8150
            err = ecc_map(mG, curve->prime, mp);
8151
    }
8152
#else
8153
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
8154
0
    if (err == MP_OKAY) {
8155
0
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
8156
0
                                                                     key->heap);
8157
0
    }
8158
0
#endif /* ECC_SHAMIR */
8159
0
#endif /* FREESCALE_LTC_ECC */
8160
   /* v = X_x1 mod n */
8161
0
   if (err == MP_OKAY)
8162
0
       err = mp_mod(mG->x, curve->order, v);
8163
8164
   /* does v == r */
8165
0
   if (err == MP_OKAY) {
8166
0
       if (mp_cmp(v, r) == MP_EQ)
8167
0
           *res = 1;
8168
0
   }
8169
8170
   /* cleanup */
8171
0
   wc_ecc_del_point_ex(mG, key->heap);
8172
0
   wc_ecc_del_point_ex(mQ, key->heap);
8173
8174
0
   mp_clear(e);
8175
0
   if (did_init) {
8176
0
       mp_clear(v);
8177
0
       mp_clear(w);
8178
0
       mp_clear(u1);
8179
0
       mp_clear(u2);
8180
0
   }
8181
0
#ifdef WOLFSSL_SMALL_STACK
8182
0
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
8183
0
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
8184
0
   XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
8185
0
   XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
8186
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8187
0
   XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8188
0
#endif
8189
0
#endif
8190
8191
0
   wc_ecc_curve_free(curve);
8192
0
   FREE_CURVE_SPECS();
8193
8194
0
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
8195
0
#endif /* WOLFSSL_ATECC508A */
8196
8197
0
   (void)keySz;
8198
0
   (void)hashlen;
8199
8200
0
   return err;
8201
0
}
8202
#endif /* WOLFSSL_STM32_PKA */
8203
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
8204
#endif /* HAVE_ECC_VERIFY */
8205
8206
#ifdef HAVE_ECC_KEY_IMPORT
8207
/* import point from der
8208
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
8209
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
8210
                               const int curve_idx, ecc_point* point,
8211
                               int shortKeySize)
8212
0
{
8213
0
    int err = 0;
8214
0
#ifdef HAVE_COMP_KEY
8215
0
    int compressed = 0;
8216
0
#endif
8217
0
    int keysize;
8218
0
    byte pointType;
8219
8220
#ifndef HAVE_COMP_KEY
8221
    (void)shortKeySize;
8222
#endif
8223
8224
0
    if (in == NULL || point == NULL || (curve_idx < 0) ||
8225
0
        (wc_ecc_is_valid_idx(curve_idx) == 0))
8226
0
        return ECC_BAD_ARG_E;
8227
8228
    /* must be odd */
8229
0
    if ((inLen & 1) == 0) {
8230
0
        return ECC_BAD_ARG_E;
8231
0
    }
8232
8233
    /* clear if previously allocated */
8234
0
    mp_clear(point->x);
8235
0
    mp_clear(point->y);
8236
0
    mp_clear(point->z);
8237
8238
    /* init point */
8239
#ifdef ALT_ECC_SIZE
8240
    point->x = (mp_int*)&point->xyz[0];
8241
    point->y = (mp_int*)&point->xyz[1];
8242
    point->z = (mp_int*)&point->xyz[2];
8243
    alt_fp_init(point->x);
8244
    alt_fp_init(point->y);
8245
    alt_fp_init(point->z);
8246
#else
8247
0
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
8248
0
#endif
8249
0
    if (err != MP_OKAY)
8250
0
        return MEMORY_E;
8251
8252
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
8253
8254
    /* check for point type (4, 2, or 3) */
8255
0
    pointType = in[0];
8256
0
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
8257
0
                                         pointType != ECC_POINT_COMP_ODD) {
8258
0
        err = ASN_PARSE_E;
8259
0
    }
8260
8261
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
8262
0
#ifdef HAVE_COMP_KEY
8263
0
        compressed = 1;
8264
#else
8265
        err = NOT_COMPILED_IN;
8266
#endif
8267
0
    }
8268
8269
    /* adjust to skip first byte */
8270
0
    inLen -= 1;
8271
0
    in += 1;
8272
8273
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
8274
     * is true */
8275
0
#ifdef HAVE_COMP_KEY
8276
0
    keysize = compressed && !shortKeySize ? inLen : inLen>>1;
8277
#else
8278
    keysize = inLen>>1;
8279
#endif
8280
8281
    /* read data */
8282
0
    if (err == MP_OKAY)
8283
0
        err = mp_read_unsigned_bin(point->x, in, keysize);
8284
8285
0
#ifdef HAVE_COMP_KEY
8286
0
    if (err == MP_OKAY && compressed == 1) {   /* build y */
8287
    #if defined(WOLFSSL_HAVE_SP_ECC)
8288
        #ifndef WOLFSSL_SP_NO_256
8289
        if (curve_idx != ECC_CUSTOM_IDX &&
8290
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
8291
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
8292
        }
8293
        else
8294
        #endif
8295
        #ifdef WOLFSSL_SP_384
8296
        if (curve_idx != ECC_CUSTOM_IDX &&
8297
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
8298
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
8299
        }
8300
        else
8301
        #endif
8302
        #ifdef WOLFSSL_SP_521
8303
        if (curve_idx != ECC_CUSTOM_IDX &&
8304
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
8305
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
8306
        }
8307
        else
8308
        #endif
8309
    #endif
8310
0
    #if !defined(WOLFSSL_SP_MATH)
8311
0
        {
8312
0
            int did_init = 0;
8313
0
        #ifdef WOLFSSL_SMALL_STACK
8314
0
            mp_int* t1 = NULL;
8315
0
            mp_int* t2 = NULL;
8316
        #else
8317
            mp_int t1[1], t2[1];
8318
        #endif
8319
0
            DECLARE_CURVE_SPECS(3);
8320
8321
0
            ALLOC_CURVE_SPECS(3, err);
8322
8323
0
        #ifdef WOLFSSL_SMALL_STACK
8324
0
            if (err == MP_OKAY) {
8325
0
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
8326
0
                                      DYNAMIC_TYPE_BIGINT);
8327
0
                if (t1 == NULL) {
8328
0
                    err = MEMORY_E;
8329
0
                }
8330
0
            }
8331
0
            if (err == MP_OKAY) {
8332
0
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
8333
0
                                      DYNAMIC_TYPE_BIGINT);
8334
0
                if (t2 == NULL) {
8335
0
                    err = MEMORY_E;
8336
0
                }
8337
0
            }
8338
0
        #endif
8339
8340
0
            if (err == MP_OKAY) {
8341
0
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
8342
0
                    err = MEMORY_E;
8343
0
                else
8344
0
                    did_init = 1;
8345
0
            }
8346
8347
            /* load curve info */
8348
0
            if (err == MP_OKAY)
8349
0
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
8350
0
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
8351
0
                        ECC_CURVE_FIELD_BF));
8352
8353
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
8354
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
8355
            /* validate prime is prime for custom curves */
8356
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
8357
                int isPrime = MP_NO;
8358
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
8359
                if (err == MP_OKAY && isPrime == MP_NO)
8360
                    err = MP_VAL;
8361
            }
8362
        #endif
8363
8364
            /* compute x^3 */
8365
0
            if (err == MP_OKAY)
8366
0
                err = mp_sqr(point->x, t1);
8367
0
            if (err == MP_OKAY)
8368
0
                err = mp_mulmod(t1, point->x, curve->prime, t1);
8369
8370
            /* compute x^3 + a*x */
8371
0
            if (err == MP_OKAY)
8372
0
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
8373
0
            if (err == MP_OKAY)
8374
0
                err = mp_add(t1, t2, t1);
8375
8376
            /* compute x^3 + a*x + b */
8377
0
            if (err == MP_OKAY)
8378
0
                err = mp_add(t1, curve->Bf, t1);
8379
8380
            /* compute sqrt(x^3 + a*x + b) */
8381
0
            if (err == MP_OKAY)
8382
0
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
8383
8384
            /* adjust y */
8385
0
            if (err == MP_OKAY) {
8386
0
                if ((mp_isodd(t2) == MP_YES &&
8387
0
                                            pointType == ECC_POINT_COMP_ODD) ||
8388
0
                    (mp_isodd(t2) == MP_NO &&
8389
0
                                            pointType == ECC_POINT_COMP_EVEN)) {
8390
0
                    err = mp_mod(t2, curve->prime, point->y);
8391
0
                }
8392
0
                else {
8393
0
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
8394
0
                }
8395
0
            }
8396
8397
0
            if (did_init) {
8398
0
                mp_clear(t2);
8399
0
                mp_clear(t1);
8400
0
            }
8401
8402
0
        #ifdef WOLFSSL_SMALL_STACK
8403
0
            if (t1 != NULL) {
8404
0
                XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
8405
0
            }
8406
0
            if (t2 != NULL) {
8407
0
                XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
8408
0
            }
8409
0
        #endif
8410
8411
0
            wc_ecc_curve_free(curve);
8412
0
            FREE_CURVE_SPECS();
8413
0
        }
8414
    #else
8415
        {
8416
            err = WC_KEY_SIZE_E;
8417
        }
8418
    #endif
8419
0
    }
8420
0
#endif
8421
8422
0
    if (err == MP_OKAY) {
8423
0
#ifdef HAVE_COMP_KEY
8424
0
        if (compressed == 0)
8425
0
#endif
8426
0
            err = mp_read_unsigned_bin(point->y, in + keysize, keysize);
8427
0
    }
8428
0
    if (err == MP_OKAY)
8429
0
        err = mp_set(point->z, 1);
8430
8431
0
    if (err != MP_OKAY) {
8432
0
        mp_clear(point->x);
8433
0
        mp_clear(point->y);
8434
0
        mp_clear(point->z);
8435
0
    }
8436
8437
0
    RESTORE_VECTOR_REGISTERS();
8438
8439
0
    return err;
8440
0
}
8441
8442
/* function for backwards compatiblity with previous implementations */
8443
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
8444
                            ecc_point* point)
8445
0
{
8446
0
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
8447
0
}
8448
#endif /* HAVE_ECC_KEY_IMPORT */
8449
8450
#ifdef HAVE_ECC_KEY_EXPORT
8451
/* export point to der */
8452
8453
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
8454
                               word32* outLen, int compressed)
8455
0
{
8456
0
    if (compressed == 0)
8457
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
8458
0
#ifdef HAVE_COMP_KEY
8459
0
    else
8460
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
8461
#else
8462
    return NOT_COMPILED_IN;
8463
#endif
8464
0
}
8465
8466
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
8467
                            word32* outLen)
8468
0
{
8469
0
    int    ret = MP_OKAY;
8470
0
    word32 numlen;
8471
0
#ifdef WOLFSSL_SMALL_STACK
8472
0
    byte*  buf;
8473
#else
8474
    byte   buf[ECC_BUFSIZE];
8475
#endif
8476
8477
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
8478
0
        return ECC_BAD_ARG_E;
8479
8480
0
    numlen = ecc_sets[curve_idx].size;
8481
8482
    /* return length needed only */
8483
0
    if (point != NULL && out == NULL && outLen != NULL) {
8484
0
        *outLen = 1 + 2*numlen;
8485
0
        return LENGTH_ONLY_E;
8486
0
    }
8487
8488
0
    if (point == NULL || out == NULL || outLen == NULL)
8489
0
        return ECC_BAD_ARG_E;
8490
8491
0
    if (*outLen < (1 + 2*numlen)) {
8492
0
        *outLen = 1 + 2*numlen;
8493
0
        return BUFFER_E;
8494
0
    }
8495
8496
    /* Sanity check the ordinates' sizes. */
8497
0
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
8498
0
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
8499
0
        return ECC_BAD_ARG_E;
8500
0
    }
8501
8502
    /* store byte point type */
8503
0
    out[0] = ECC_POINT_UNCOMP;
8504
8505
0
#ifdef WOLFSSL_SMALL_STACK
8506
0
    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8507
0
    if (buf == NULL)
8508
0
        return MEMORY_E;
8509
0
#endif
8510
8511
    /* pad and store x */
8512
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
8513
0
    ret = mp_to_unsigned_bin(point->x, buf +
8514
0
                                 (numlen - mp_unsigned_bin_size(point->x)));
8515
0
    if (ret != MP_OKAY)
8516
0
        goto done;
8517
0
    XMEMCPY(out+1, buf, numlen);
8518
8519
    /* pad and store y */
8520
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
8521
0
    ret = mp_to_unsigned_bin(point->y, buf +
8522
0
                                 (numlen - mp_unsigned_bin_size(point->y)));
8523
0
    if (ret != MP_OKAY)
8524
0
        goto done;
8525
0
    XMEMCPY(out+1+numlen, buf, numlen);
8526
8527
0
    *outLen = 1 + 2*numlen;
8528
8529
0
done:
8530
0
#ifdef WOLFSSL_SMALL_STACK
8531
0
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8532
0
#endif
8533
8534
0
    return ret;
8535
0
}
8536
8537
8538
/* export point to der */
8539
#ifdef HAVE_COMP_KEY
8540
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
8541
                                       byte* out, word32* outLen)
8542
0
{
8543
0
    int    ret = MP_OKAY;
8544
0
    word32 numlen;
8545
0
    word32 output_len;
8546
0
#ifdef WOLFSSL_SMALL_STACK
8547
0
    byte*  buf;
8548
#else
8549
    byte   buf[ECC_BUFSIZE];
8550
#endif
8551
8552
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
8553
0
        return ECC_BAD_ARG_E;
8554
8555
0
    numlen = ecc_sets[curve_idx].size;
8556
0
    output_len = 1 + numlen; /* y point type + x */
8557
8558
    /* return length needed only */
8559
0
    if (point != NULL && out == NULL && outLen != NULL) {
8560
0
        *outLen = output_len;
8561
0
        return LENGTH_ONLY_E;
8562
0
    }
8563
8564
0
    if (point == NULL || out == NULL || outLen == NULL)
8565
0
        return ECC_BAD_ARG_E;
8566
8567
8568
0
    if (*outLen < output_len) {
8569
0
        *outLen = output_len;
8570
0
        return BUFFER_E;
8571
0
    }
8572
8573
    /* Sanity check the ordinate's size. */
8574
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
8575
0
        return ECC_BAD_ARG_E;
8576
0
    }
8577
8578
    /* store byte point type */
8579
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
8580
0
                                            ECC_POINT_COMP_EVEN;
8581
8582
0
#ifdef WOLFSSL_SMALL_STACK
8583
0
    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8584
0
    if (buf == NULL)
8585
0
        return MEMORY_E;
8586
0
#endif
8587
8588
    /* pad and store x */
8589
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
8590
0
    ret = mp_to_unsigned_bin(point->x, buf +
8591
0
                                 (numlen - mp_unsigned_bin_size(point->x)));
8592
0
    if (ret != MP_OKAY)
8593
0
        goto done;
8594
0
    XMEMCPY(out+1, buf, numlen);
8595
8596
0
    *outLen = output_len;
8597
8598
0
done:
8599
0
#ifdef WOLFSSL_SMALL_STACK
8600
0
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8601
0
#endif
8602
8603
0
    return ret;
8604
0
}
8605
#endif /* HAVE_COMP_KEY */
8606
8607
/* export public ECC key in ANSI X9.63 format */
8608
WOLFSSL_ABI
8609
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
8610
0
{
8611
0
   int    ret = MP_OKAY;
8612
0
   word32 numlen;
8613
0
#ifdef WOLFSSL_SMALL_STACK
8614
0
   byte*  buf;
8615
#else
8616
   byte   buf[ECC_BUFSIZE];
8617
#endif
8618
0
   word32 pubxlen, pubylen;
8619
8620
   /* return length needed only */
8621
0
   if (key != NULL && out == NULL && outLen != NULL) {
8622
      /* if key hasn't been setup assume max bytes for size estimation */
8623
0
      numlen = key->dp ? key->dp->size : MAX_ECC_BYTES;
8624
0
      *outLen = 1 + 2*numlen;
8625
0
      return LENGTH_ONLY_E;
8626
0
   }
8627
8628
0
   if (key == NULL || out == NULL || outLen == NULL)
8629
0
      return ECC_BAD_ARG_E;
8630
8631
0
   if (key->type == ECC_PRIVATEKEY_ONLY)
8632
0
       return ECC_PRIVATEONLY_E;
8633
8634
#ifdef WOLFSSL_QNX_CAAM
8635
    /* check if public key in secure memory */
8636
    if (key->securePubKey > 0) {
8637
        int keySz = wc_ecc_size(key);
8638
8639
        /* store byte point type */
8640
        out[0] = ECC_POINT_UNCOMP;
8641
8642
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
8643
            return WC_HW_E;
8644
8645
        *outLen = 1 + 2*keySz;
8646
        return MP_OKAY;
8647
    }
8648
#endif
8649
8650
0
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
8651
0
       return ECC_BAD_ARG_E;
8652
0
   }
8653
8654
0
   numlen = key->dp->size;
8655
8656
    /* verify room in out buffer */
8657
0
   if (*outLen < (1 + 2*numlen)) {
8658
0
      *outLen = 1 + 2*numlen;
8659
0
      return BUFFER_E;
8660
0
   }
8661
8662
   /* verify public key length is less than key size */
8663
0
   pubxlen = mp_unsigned_bin_size(key->pubkey.x);
8664
0
   pubylen = mp_unsigned_bin_size(key->pubkey.y);
8665
0
   if ((pubxlen > numlen) || (pubylen > numlen)) {
8666
0
      WOLFSSL_MSG("Public key x/y invalid!");
8667
0
      return BUFFER_E;
8668
0
   }
8669
8670
   /* store byte point type */
8671
0
   out[0] = ECC_POINT_UNCOMP;
8672
8673
0
#ifdef WOLFSSL_SMALL_STACK
8674
0
   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8675
0
   if (buf == NULL)
8676
0
      return MEMORY_E;
8677
0
#endif
8678
8679
   /* pad and store x */
8680
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
8681
0
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
8682
0
   if (ret != MP_OKAY)
8683
0
      goto done;
8684
0
   XMEMCPY(out+1, buf, numlen);
8685
8686
   /* pad and store y */
8687
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
8688
0
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
8689
0
   if (ret != MP_OKAY)
8690
0
      goto done;
8691
0
   XMEMCPY(out+1+numlen, buf, numlen);
8692
8693
0
   *outLen = 1 + 2*numlen;
8694
8695
0
done:
8696
0
#ifdef WOLFSSL_SMALL_STACK
8697
0
   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8698
0
#endif
8699
8700
0
   return ret;
8701
0
}
8702
8703
8704
/* export public ECC key in ANSI X9.63 format, extended with
8705
 * compression option */
8706
WOLFSSL_ABI
8707
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
8708
                          int compressed)
8709
0
{
8710
0
    if (compressed == 0)
8711
0
        return wc_ecc_export_x963(key, out, outLen);
8712
0
#ifdef HAVE_COMP_KEY
8713
0
    else
8714
0
        return wc_ecc_export_x963_compressed(key, out, outLen);
8715
#else
8716
    return NOT_COMPILED_IN;
8717
#endif
8718
0
}
8719
#endif /* HAVE_ECC_KEY_EXPORT */
8720
8721
8722
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
8723
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) && \
8724
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8725
8726
/* is ecc point on curve described by dp ? */
8727
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
8728
0
{
8729
0
#if !defined(WOLFSSL_SP_MATH)
8730
0
   int err;
8731
0
#ifdef WOLFSSL_SMALL_STACK
8732
0
   mp_int* t1;
8733
0
   mp_int* t2;
8734
#else
8735
   mp_int  t1[1], t2[1];
8736
#endif
8737
8738
0
#ifdef WOLFSSL_SMALL_STACK
8739
0
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
8740
0
   if (t1 == NULL)
8741
0
       return MEMORY_E;
8742
0
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
8743
0
   if (t2 == NULL) {
8744
0
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8745
0
       return MEMORY_E;
8746
0
   }
8747
0
#endif
8748
8749
0
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
8750
0
   #ifdef WOLFSSL_SMALL_STACK
8751
0
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
8752
0
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8753
0
   #endif
8754
0
      return err;
8755
0
   }
8756
8757
0
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
8758
8759
   /* compute y^2 */
8760
0
   if (err == MP_OKAY)
8761
0
       err = mp_sqr(ecp->y, t1);
8762
8763
   /* compute x^3 */
8764
0
   if (err == MP_OKAY)
8765
0
       err = mp_sqr(ecp->x, t2);
8766
0
   if (err == MP_OKAY)
8767
0
       err = mp_mod(t2, prime, t2);
8768
0
   if (err == MP_OKAY)
8769
0
       err = mp_mul(ecp->x, t2, t2);
8770
8771
   /* compute y^2 - x^3 */
8772
0
   if (err == MP_OKAY)
8773
0
       err = mp_submod(t1, t2, prime, t1);
8774
8775
   /* Determine if curve "a" should be used in calc */
8776
0
#ifdef WOLFSSL_CUSTOM_CURVES
8777
0
   if (err == MP_OKAY) {
8778
      /* Use a and prime to determine if a == 3 */
8779
0
      err = mp_set(t2, 0);
8780
0
      if (err == MP_OKAY)
8781
0
          err = mp_submod(prime, a, prime, t2);
8782
0
   }
8783
0
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
8784
      /* compute y^2 - x^3 + a*x */
8785
0
      if (err == MP_OKAY)
8786
0
          err = mp_mulmod(t2, ecp->x, prime, t2);
8787
0
      if (err == MP_OKAY)
8788
0
          err = mp_addmod(t1, t2, prime, t1);
8789
0
   }
8790
0
   else
8791
0
#endif /* WOLFSSL_CUSTOM_CURVES */
8792
0
   {
8793
      /* assumes "a" == 3 */
8794
0
      (void)a;
8795
8796
      /* compute y^2 - x^3 + 3x */
8797
0
      if (err == MP_OKAY)
8798
0
          err = mp_add(t1, ecp->x, t1);
8799
0
      if (err == MP_OKAY)
8800
0
          err = mp_add(t1, ecp->x, t1);
8801
0
      if (err == MP_OKAY)
8802
0
          err = mp_add(t1, ecp->x, t1);
8803
0
      if (err == MP_OKAY)
8804
0
          err = mp_mod(t1, prime, t1);
8805
0
  }
8806
8807
   /* adjust range (0, prime) */
8808
0
   while (err == MP_OKAY && mp_isneg(t1)) {
8809
0
      err = mp_add(t1, prime, t1);
8810
0
   }
8811
0
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
8812
0
      err = mp_sub(t1, prime, t1);
8813
0
   }
8814
8815
   /* compare to b */
8816
0
   if (err == MP_OKAY) {
8817
0
       if (mp_cmp(t1, b) != MP_EQ) {
8818
0
          err = IS_POINT_E;
8819
0
       } else {
8820
0
          err = MP_OKAY;
8821
0
       }
8822
0
   }
8823
8824
0
   mp_clear(t1);
8825
0
   mp_clear(t2);
8826
8827
0
   RESTORE_VECTOR_REGISTERS();
8828
8829
0
#ifdef WOLFSSL_SMALL_STACK
8830
0
   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
8831
0
   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8832
0
#endif
8833
8834
0
   return err;
8835
#else
8836
   (void)a;
8837
   (void)b;
8838
8839
#ifdef WOLFSSL_HAVE_SP_ECC
8840
#ifndef WOLFSSL_SP_NO_256
8841
   if (mp_count_bits(prime) == 256) {
8842
       return sp_ecc_is_point_256(ecp->x, ecp->y);
8843
   }
8844
#endif
8845
#ifdef WOLFSSL_SP_384
8846
   if (mp_count_bits(prime) == 384) {
8847
       return sp_ecc_is_point_384(ecp->x, ecp->y);
8848
   }
8849
#endif
8850
#ifdef WOLFSSL_SP_521
8851
   if (mp_count_bits(prime) == 521) {
8852
       return sp_ecc_is_point_521(ecp->x, ecp->y);
8853
   }
8854
#endif
8855
#else
8856
   (void)ecp;
8857
   (void)prime;
8858
#endif
8859
   return WC_KEY_SIZE_E;
8860
#endif
8861
0
}
8862
8863
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
8864
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
8865
    !defined(WOLFSSL_KCAPI_ECC)
8866
/* validate privkey * generator == pubkey, 0 on success */
8867
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
8868
{
8869
    int        err;
8870
    ecc_point* base = NULL;
8871
    ecc_point* res  = NULL;
8872
#ifdef WOLFSSL_NO_MALLOC
8873
    ecc_point lcl_base;
8874
    ecc_point lcl_res;
8875
#endif
8876
    DECLARE_CURVE_SPECS(3);
8877
8878
    if (key == NULL)
8879
        return BAD_FUNC_ARG;
8880
8881
    ALLOC_CURVE_SPECS(3, err);
8882
8883
#ifdef WOLFSSL_NO_MALLOC
8884
    res = &lcl_res;
8885
#endif
8886
    err = wc_ecc_new_point_ex(&res, key->heap);
8887
8888
#ifdef WOLFSSL_HAVE_SP_ECC
8889
#ifndef WOLFSSL_SP_NO_256
8890
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
8891
        if (err == MP_OKAY) {
8892
            err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap);
8893
        }
8894
    }
8895
    else
8896
#endif
8897
#ifdef WOLFSSL_SP_384
8898
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
8899
        if (err == MP_OKAY) {
8900
            err = sp_ecc_mulmod_base_384(&key->k, res, 1, key->heap);
8901
        }
8902
    }
8903
    else
8904
#endif
8905
#ifdef WOLFSSL_SP_521
8906
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
8907
        if (err == MP_OKAY) {
8908
            err = sp_ecc_mulmod_base_521(&key->k, res, 1, key->heap);
8909
        }
8910
    }
8911
    else
8912
#endif
8913
#endif
8914
    {
8915
        if (err == MP_OKAY) {
8916
        #ifdef WOLFSSL_NO_MALLOC
8917
            base = &lcl_base;
8918
        #endif
8919
            err = wc_ecc_new_point_ex(&base, key->heap);
8920
        }
8921
8922
        if (err == MP_OKAY) {
8923
            /* load curve info */
8924
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
8925
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
8926
        }
8927
8928
        /* set up base generator */
8929
        if (err == MP_OKAY)
8930
            err = mp_copy(curve->Gx, base->x);
8931
        if (err == MP_OKAY)
8932
            err = mp_copy(curve->Gy, base->y);
8933
        if (err == MP_OKAY)
8934
            err = mp_set(base->z, 1);
8935
8936
#ifdef WOLFSSL_KCAPI_ECC
8937
        if (err == MP_OKAY) {
8938
            word32 pubkey_sz = (word32)key->dp->size*2;
8939
            if (key->handle == NULL) {
8940
                /* if handle loaded, then pubkey_raw already populated */
8941
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
8942
            }
8943
            if (err == 0) {
8944
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
8945
                                           pubkey_sz/2);
8946
            }
8947
            if (err == MP_OKAY) {
8948
                err = mp_read_unsigned_bin(res->y,
8949
                                           key->pubkey_raw + pubkey_sz/2,
8950
                                           pubkey_sz/2);
8951
            }
8952
            if (err == MP_OKAY) {
8953
                err = mp_set(res->z, 1);
8954
            }
8955
        }
8956
        (void)a;
8957
        (void)prime;
8958
#else
8959
#ifdef ECC_TIMING_RESISTANT
8960
        if (err == MP_OKAY)
8961
            err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
8962
                                                        key->rng, 1, key->heap);
8963
#else
8964
        if (err == MP_OKAY)
8965
            err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
8966
                                                            NULL, 1, key->heap);
8967
#endif
8968
#endif /* WOLFSSL_KCAPI_ECC */
8969
    }
8970
8971
    if (err == MP_OKAY) {
8972
        /* compare result to public key */
8973
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
8974
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
8975
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
8976
            /* didn't match */
8977
            err = ECC_PRIV_KEY_E;
8978
        }
8979
    }
8980
8981
    wc_ecc_curve_free(curve);
8982
    wc_ecc_del_point_ex(res, key->heap);
8983
    wc_ecc_del_point_ex(base, key->heap);
8984
    FREE_CURVE_SPECS();
8985
8986
    return err;
8987
}
8988
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
8989
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
8990
8991
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
8992
    !defined(WOLFSSL_KCAPI_ECC)
8993
8994
/* check privkey generator helper, creates prime needed */
8995
static int ecc_check_privkey_gen_helper(ecc_key* key)
8996
{
8997
    int    err;
8998
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
8999
    DECLARE_CURVE_SPECS(2);
9000
#endif
9001
9002
    if (key == NULL)
9003
        return BAD_FUNC_ARG;
9004
9005
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9006
    /* Hardware based private key, so this operation is not supported */
9007
    err = MP_OKAY; /* just report success */
9008
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9009
    /* Hardware based private key, so this operation is not supported */
9010
    err = MP_OKAY; /* just report success */
9011
#elif defined(WOLFSSL_KCAPI_ECC)
9012
    /* Hardware based private key, so this operation is not supported */
9013
    err = MP_OKAY; /* just report success */
9014
#else
9015
    err = MP_OKAY;
9016
    ALLOC_CURVE_SPECS(2, err);
9017
9018
    /* load curve info */
9019
    if (err == MP_OKAY)
9020
        err = wc_ecc_curve_load(key->dp, &curve,
9021
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
9022
9023
    if (err == MP_OKAY)
9024
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
9025
9026
    wc_ecc_curve_free(curve);
9027
    FREE_CURVE_SPECS();
9028
9029
#endif /* WOLFSSL_ATECC508A */
9030
9031
    return err;
9032
}
9033
9034
/* Performs a Pairwise Consistency Test on an ECC key pair. */
9035
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
9036
{
9037
    int err = 0;
9038
    int flags = key->flags;
9039
9040
    /* If flags not set default to cofactor and dec/sign */
9041
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
9042
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
9043
    }
9044
9045
    if (flags & WC_ECC_FLAG_COFACTOR) {
9046
        err = ecc_check_privkey_gen_helper(key);
9047
    }
9048
9049
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
9050
        byte* sig;
9051
        byte* digest;
9052
        word32 sigLen, digestLen;
9053
        int dynRng = 0, res = 0;
9054
9055
        sigLen = wc_ecc_sig_size(key);
9056
        digestLen = WC_SHA256_DIGEST_SIZE;
9057
        sig = (byte*)XMALLOC(sigLen + digestLen, NULL, DYNAMIC_TYPE_ECC);
9058
        if (sig == NULL)
9059
            return MEMORY_E;
9060
        digest = sig + sigLen;
9061
9062
        if (rng == NULL) {
9063
            dynRng = 1;
9064
            rng = wc_rng_new(NULL, 0, NULL);
9065
            if (rng == NULL) {
9066
                XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
9067
                return MEMORY_E;
9068
            }
9069
        }
9070
9071
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
9072
9073
        if (!err)
9074
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
9075
                    rng, key);
9076
        if (!err)
9077
            err = wc_ecc_verify_hash(sig, sigLen,
9078
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
9079
9080
        if (res == 0)
9081
            err = ECC_PCT_E;
9082
9083
        if (dynRng) {
9084
            wc_rng_free(rng);
9085
        }
9086
        ForceZero(sig, sigLen + digestLen);
9087
        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
9088
    }
9089
    (void)rng;
9090
9091
    if (err != 0)
9092
        err = ECC_PCT_E;
9093
9094
    return err;
9095
}
9096
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) &&!WOLFSSL_KCAPI_ECC */
9097
9098
#ifndef WOLFSSL_SP_MATH
9099
/* validate order * pubkey = point at infinity, 0 on success */
9100
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
9101
        mp_int* prime, mp_int* order)
9102
0
{
9103
0
    ecc_point* inf = NULL;
9104
#ifdef WOLFSSL_NO_MALLOC
9105
    ecc_point  lcl_inf;
9106
#endif
9107
0
    int err;
9108
9109
0
    if (key == NULL)
9110
0
        return BAD_FUNC_ARG;
9111
0
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
9112
0
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
9113
0
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
9114
0
       return IS_POINT_E;
9115
0
   }
9116
9117
#ifdef WOLFSSL_NO_MALLOC
9118
    inf = &lcl_inf;
9119
#endif
9120
0
    err = wc_ecc_new_point_ex(&inf, key->heap);
9121
0
    if (err == MP_OKAY) {
9122
#ifdef WOLFSSL_HAVE_SP_ECC
9123
#ifndef WOLFSSL_SP_NO_256
9124
        if (key->idx != ECC_CUSTOM_IDX &&
9125
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
9126
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
9127
        }
9128
        else
9129
#endif
9130
#ifdef WOLFSSL_SP_384
9131
        if (key->idx != ECC_CUSTOM_IDX &&
9132
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
9133
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
9134
        }
9135
        else
9136
#endif
9137
#ifdef WOLFSSL_SP_521
9138
        if (key->idx != ECC_CUSTOM_IDX &&
9139
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
9140
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
9141
        }
9142
        else
9143
#endif
9144
#endif
9145
0
#if !defined(WOLFSSL_SP_MATH)
9146
0
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
9147
0
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
9148
0
            err = ECC_INF_E;
9149
#else
9150
        {
9151
            (void)a;
9152
            (void)prime;
9153
9154
            err = WC_KEY_SIZE_E;
9155
        }
9156
#endif
9157
0
    }
9158
9159
0
    wc_ecc_del_point_ex(inf, key->heap);
9160
9161
0
    return err;
9162
0
}
9163
#endif /* !WOLFSSL_SP_MATH */
9164
9165
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL*/
9166
9167
#ifdef OPENSSL_EXTRA
9168
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
9169
0
{
9170
0
    int err = MP_OKAY;
9171
0
    DECLARE_CURVE_SPECS(2);
9172
9173
0
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
9174
0
        return BAD_FUNC_ARG;
9175
9176
0
    ALLOC_CURVE_SPECS(2, err);
9177
9178
0
    if (err == MP_OKAY)
9179
0
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9180
0
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
9181
0
    if (err == MP_OKAY)
9182
0
        err = mp_copy(curve->Gx, ecp->x);
9183
0
    if (err == MP_OKAY)
9184
0
        err = mp_copy(curve->Gy, ecp->y);
9185
0
    if (err == MP_OKAY)
9186
0
        err = mp_set(ecp->z, 1);
9187
9188
0
    wc_ecc_curve_free(curve);
9189
0
    FREE_CURVE_SPECS();
9190
9191
0
    return err;
9192
0
}
9193
#endif /* OPENSSLALL */
9194
9195
9196
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
9197
 * ECC Full Public Key Validation Routine. If the parameter
9198
 * partial is set, then it follows section 5.6.2.3.4, the ECC
9199
 * Partial Public Key Validation Routine.
9200
 * If the parameter priv is set, add in a few extra
9201
 * checks on the bounds of the private key. */
9202
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
9203
0
{
9204
0
    int err = MP_OKAY;
9205
0
#ifndef WOLFSSL_SP_MATH
9206
0
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
9207
0
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
9208
0
    !defined(WOLFSSL_SE050) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
9209
0
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9210
0
    mp_int* b = NULL;
9211
0
    #ifdef USE_ECC_B_PARAM
9212
0
        DECLARE_CURVE_SPECS(4);
9213
    #else
9214
        #ifndef WOLFSSL_SMALL_STACK
9215
            mp_int b_lcl;
9216
        #endif
9217
        DECLARE_CURVE_SPECS(3);
9218
    #endif /* USE_ECC_B_PARAM */
9219
0
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
9220
          !WOLFSSL_CRYPTOCELL && !WOLFSSL_SILABS_SE_ACCEL && !WOLFSSL_SE050 */
9221
0
#endif /* !WOLFSSL_SP_MATH */
9222
9223
0
    ASSERT_SAVED_VECTOR_REGISTERS();
9224
9225
0
    if (key == NULL)
9226
0
        return BAD_FUNC_ARG;
9227
9228
#ifdef WOLFSSL_HAVE_SP_ECC
9229
#ifndef WOLFSSL_SP_NO_256
9230
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
9231
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
9232
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9233
    }
9234
#endif
9235
#ifdef WOLFSSL_SP_384
9236
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
9237
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
9238
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9239
    }
9240
#endif
9241
#ifdef WOLFSSL_SP_521
9242
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
9243
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
9244
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9245
    }
9246
#endif
9247
#ifdef WOLFSSL_SP_1024
9248
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
9249
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
9250
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9251
    }
9252
#endif
9253
#endif
9254
9255
0
#ifndef WOLFSSL_SP_MATH
9256
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
9257
    defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) || \
9258
    defined(WOLFSSL_SE050) || defined(WOLF_CRYPTO_CB_ONLY_ECC)
9259
9260
    /* consider key check success on HW crypto
9261
     * ex: ATECC508/608A, CryptoCell and Silabs
9262
     *
9263
     * consider key check success on Crypt Cb
9264
     */
9265
    err = MP_OKAY;
9266
9267
#else
9268
0
    #ifdef USE_ECC_B_PARAM
9269
0
        ALLOC_CURVE_SPECS(4, err);
9270
    #else
9271
        ALLOC_CURVE_SPECS(3, err);
9272
        #ifndef WOLFSSL_SMALL_STACK
9273
            b = &b_lcl;
9274
        #else
9275
            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9276
            if (b == NULL) {
9277
                FREE_CURVE_SPECS();
9278
                return MEMORY_E;
9279
            }
9280
        #endif
9281
        XMEMSET(b, 0, sizeof(mp_int));
9282
    #endif
9283
9284
    #ifdef WOLFSSL_CAAM
9285
    /* keys can be black encrypted ones which can not be checked like plain text
9286
     * keys */
9287
    if (key->blackKey > 0) {
9288
        /* encrypted key was used */
9289
        #ifdef WOLFSSL_SMALL_STACK
9290
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
9291
        #endif
9292
        FREE_CURVE_SPECS();
9293
        return 0;
9294
    }
9295
    #endif
9296
9297
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
9298
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
9299
    /* pubkey point cannot be at infinity */
9300
0
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
9301
0
    #ifdef WOLFSSL_SMALL_STACK
9302
0
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
9303
0
    #endif
9304
0
        FREE_CURVE_SPECS();
9305
0
        return ECC_INF_E;
9306
0
    }
9307
9308
    /* load curve info */
9309
0
    if (err == MP_OKAY)
9310
0
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
9311
0
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
9312
0
#ifdef USE_ECC_B_PARAM
9313
0
            | ECC_CURVE_FIELD_BF
9314
0
#endif
9315
0
    ));
9316
9317
#ifndef USE_ECC_B_PARAM
9318
    /* load curve b parameter */
9319
    if (err == MP_OKAY)
9320
        err = mp_init(b);
9321
    if (err == MP_OKAY)
9322
        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
9323
#else
9324
0
    if (err == MP_OKAY)
9325
0
        b = curve->Bf;
9326
0
#endif
9327
9328
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
9329
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
9330
    /* Qx must be in the range [0, p-1] */
9331
0
    if (err == MP_OKAY) {
9332
0
        if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
9333
0
            err = ECC_OUT_OF_RANGE_E;
9334
0
    }
9335
9336
    /* Qy must be in the range [0, p-1] */
9337
0
    if (err == MP_OKAY) {
9338
0
        if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
9339
0
            err = ECC_OUT_OF_RANGE_E;
9340
0
    }
9341
9342
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
9343
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
9344
    /* make sure point is actually on curve */
9345
0
    if (err == MP_OKAY)
9346
0
        err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
9347
9348
0
    if (!partial) {
9349
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
9350
        /* pubkey * order must be at infinity */
9351
0
        if (err == MP_OKAY)
9352
0
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
9353
0
                    curve->prime, curve->order);
9354
0
    }
9355
9356
0
    if (priv) {
9357
        /* SP 800-56Ar3, section 5.6.2.1.2 */
9358
        /* private keys must be in the range [1, n-1] */
9359
0
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
9360
0
            (mp_iszero(&key->k) || mp_isneg(&key->k) ||
9361
0
            (mp_cmp(&key->k, curve->order) != MP_LT))
9362
        #ifdef WOLFSSL_KCAPI_ECC
9363
            && key->handle == NULL
9364
        #endif
9365
0
        ) {
9366
0
            err = ECC_PRIV_KEY_E;
9367
0
        }
9368
9369
    #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
9370
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
9371
        /* private * base generator must equal pubkey */
9372
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
9373
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
9374
    #endif
9375
0
    }
9376
9377
0
    wc_ecc_curve_free(curve);
9378
9379
#ifndef USE_ECC_B_PARAM
9380
    mp_clear(b);
9381
    #ifdef WOLFSSL_SMALL_STACK
9382
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
9383
    #endif
9384
#endif
9385
9386
0
    FREE_CURVE_SPECS();
9387
0
#endif /* HW Based Crypto */
9388
#else
9389
    err = WC_KEY_SIZE_E;
9390
#endif /* !WOLFSSL_SP_MATH */
9391
0
    (void)partial;
9392
0
    (void)priv;
9393
0
    return err;
9394
0
}
9395
9396
9397
/* perform sanity checks on ecc key validity, 0 on success */
9398
WOLFSSL_ABI
9399
int wc_ecc_check_key(ecc_key* key)
9400
0
{
9401
0
    int ret;
9402
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9403
0
    ret = _ecc_validate_public_key(key, 0, 1);
9404
0
    RESTORE_VECTOR_REGISTERS();
9405
0
    return ret;
9406
0
}
9407
9408
9409
#ifdef HAVE_ECC_KEY_IMPORT
9410
/* import public ECC key in ANSI X9.63 format */
9411
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
9412
                          int curve_id)
9413
0
{
9414
0
    int err = MP_OKAY;
9415
0
#ifdef HAVE_COMP_KEY
9416
0
    int compressed = 0;
9417
0
#endif
9418
0
    int keysize = 0;
9419
0
    byte pointType;
9420
#ifdef WOLFSSL_CRYPTOCELL
9421
    const CRYS_ECPKI_Domain_t* pDomain;
9422
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
9423
#endif
9424
0
    if (in == NULL || key == NULL)
9425
0
        return BAD_FUNC_ARG;
9426
9427
    /* must be odd */
9428
0
    if ((inLen & 1) == 0) {
9429
0
        return ECC_BAD_ARG_E;
9430
0
    }
9431
9432
    /* make sure required variables are reset */
9433
0
    wc_ecc_reset(key);
9434
9435
    /* init key */
9436
    #ifdef ALT_ECC_SIZE
9437
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
9438
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
9439
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
9440
        alt_fp_init(key->pubkey.x);
9441
        alt_fp_init(key->pubkey.y);
9442
        alt_fp_init(key->pubkey.z);
9443
        err = mp_init(&key->k);
9444
    #else
9445
0
        err = mp_init_multi(&key->k,
9446
0
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
9447
0
    #endif
9448
0
    if (err != MP_OKAY)
9449
0
        return MEMORY_E;
9450
9451
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9452
9453
    /* check for point type (4, 2, or 3) */
9454
0
    pointType = in[0];
9455
0
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9456
0
                                         pointType != ECC_POINT_COMP_ODD) {
9457
0
        err = ASN_PARSE_E;
9458
0
    }
9459
9460
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9461
0
    #ifdef HAVE_COMP_KEY
9462
0
        compressed = 1;
9463
    #else
9464
        err = NOT_COMPILED_IN;
9465
    #endif
9466
0
    }
9467
9468
    /* adjust to skip first byte */
9469
0
    inLen -= 1;
9470
0
    in += 1;
9471
9472
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9473
    /* For SECP256R1 only save raw public key for hardware */
9474
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
9475
    #ifdef HAVE_COMP_KEY
9476
        if (!compressed)
9477
    #endif
9478
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
9479
    }
9480
#elif defined(WOLFSSL_KCAPI_ECC)
9481
    XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
9482
#endif
9483
9484
0
    if (err == MP_OKAY) {
9485
0
    #ifdef HAVE_COMP_KEY
9486
        /* adjust inLen if compressed */
9487
0
        if (compressed)
9488
0
            inLen = inLen*2 + 1;  /* used uncompressed len */
9489
0
    #endif
9490
9491
        /* determine key size */
9492
0
        keysize = (inLen>>1);
9493
0
        err = wc_ecc_set_curve(key, keysize, curve_id);
9494
0
        key->type = ECC_PUBLICKEY;
9495
0
    }
9496
9497
    /* read data */
9498
0
    if (err == MP_OKAY)
9499
0
        err = mp_read_unsigned_bin(key->pubkey.x, in, keysize);
9500
9501
0
#ifdef HAVE_COMP_KEY
9502
0
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9503
0
#if !defined(WOLFSSL_SP_MATH)
9504
0
    #ifdef WOLFSSL_SMALL_STACK
9505
0
        mp_int* t1 = NULL;
9506
0
        mp_int* t2 = NULL;
9507
    #else
9508
        mp_int t1[1], t2[1];
9509
    #endif
9510
0
        int did_init = 0;
9511
9512
0
        DECLARE_CURVE_SPECS(3);
9513
0
        ALLOC_CURVE_SPECS(3, err);
9514
9515
0
        #ifdef WOLFSSL_SMALL_STACK
9516
0
        if (err == MP_OKAY) {
9517
0
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
9518
0
            if (t1 == NULL) {
9519
0
                err = MEMORY_E;
9520
0
            }
9521
0
        }
9522
0
        if (err == MP_OKAY) {
9523
0
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
9524
0
            if (t2 == NULL) {
9525
0
                err = MEMORY_E;
9526
0
            }
9527
0
        }
9528
0
        #endif
9529
0
        if (err == MP_OKAY) {
9530
0
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9531
0
                err = MEMORY_E;
9532
0
            else
9533
0
                did_init = 1;
9534
0
        }
9535
9536
        /* load curve info */
9537
0
        if (err == MP_OKAY)
9538
0
            err = wc_ecc_curve_load(key->dp, &curve,
9539
0
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9540
0
                 ECC_CURVE_FIELD_BF));
9541
9542
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
9543
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
9544
        /* validate prime is prime for custom curves */
9545
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
9546
            int isPrime = MP_NO;
9547
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
9548
            if (err == MP_OKAY && isPrime == MP_NO)
9549
                err = MP_VAL;
9550
        }
9551
    #endif
9552
9553
        /* compute x^3 */
9554
0
        if (err == MP_OKAY)
9555
0
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
9556
0
        if (err == MP_OKAY)
9557
0
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
9558
9559
        /* compute x^3 + a*x */
9560
0
        if (err == MP_OKAY)
9561
0
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
9562
0
        if (err == MP_OKAY)
9563
0
            err = mp_add(t1, t2, t1);
9564
9565
        /* compute x^3 + a*x + b */
9566
0
        if (err == MP_OKAY)
9567
0
            err = mp_add(t1, curve->Bf, t1);
9568
9569
        /* compute sqrt(x^3 + a*x + b) */
9570
0
        if (err == MP_OKAY)
9571
0
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
9572
9573
        /* adjust y */
9574
0
        if (err == MP_OKAY) {
9575
0
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
9576
0
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
9577
0
                err = mp_mod(t2, curve->prime, t2);
9578
0
            }
9579
0
            else {
9580
0
                err = mp_submod(curve->prime, t2, curve->prime, t2);
9581
0
            }
9582
0
            if (err == MP_OKAY)
9583
0
                err = mp_copy(t2, key->pubkey.y);
9584
0
        }
9585
9586
0
        if (did_init) {
9587
0
            mp_clear(t2);
9588
0
            mp_clear(t1);
9589
0
        }
9590
0
    #ifdef WOLFSSL_SMALL_STACK
9591
0
        if (t1 != NULL) {
9592
0
            XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
9593
0
        }
9594
0
        if (t2 != NULL) {
9595
0
            XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
9596
0
        }
9597
0
    #endif
9598
9599
0
        wc_ecc_curve_free(curve);
9600
0
        FREE_CURVE_SPECS();
9601
#else
9602
    #ifndef WOLFSSL_SP_NO_256
9603
        if (key->dp->id == ECC_SECP256R1) {
9604
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
9605
                key->pubkey.y);
9606
        }
9607
        else
9608
    #endif
9609
    #ifdef WOLFSSL_SP_384
9610
        if (key->dp->id == ECC_SECP384R1) {
9611
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
9612
                key->pubkey.y);
9613
        }
9614
        else
9615
    #endif
9616
    #ifdef WOLFSSL_SP_521
9617
        if (key->dp->id == ECC_SECP521R1) {
9618
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
9619
                key->pubkey.y);
9620
        }
9621
        else
9622
    #endif
9623
        {
9624
            err = WC_KEY_SIZE_E;
9625
        }
9626
#endif
9627
0
    }
9628
0
#endif /* HAVE_COMP_KEY */
9629
9630
0
    if (err == MP_OKAY) {
9631
0
    #ifdef HAVE_COMP_KEY
9632
0
        if (compressed == 0)
9633
0
    #endif
9634
0
        {
9635
0
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize, keysize);
9636
0
        }
9637
0
    }
9638
0
    if (err == MP_OKAY)
9639
0
        err = mp_set(key->pubkey.z, 1);
9640
9641
#ifdef WOLFSSL_CRYPTOCELL
9642
    if (err == MP_OKAY) {
9643
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
9644
9645
        /* create public key from external key buffer */
9646
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
9647
                                               (byte*)in-1, /* re-adjust */
9648
                                               inLen+1,     /* original input */
9649
                                               &key->ctx.pubKey,
9650
                                               &tempBuff);
9651
9652
        if (err != SA_SILIB_RET_OK){
9653
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
9654
        }
9655
    }
9656
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9657
    if (err == MP_OKAY)
9658
        err = silabs_ecc_import(key, keysize);
9659
#endif
9660
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
9661
    if (err == MP_OKAY)
9662
        err = wc_ecc_check_key(key);
9663
#endif
9664
9665
0
    if (err != MP_OKAY) {
9666
0
        mp_clear(key->pubkey.x);
9667
0
        mp_clear(key->pubkey.y);
9668
0
        mp_clear(key->pubkey.z);
9669
0
        mp_clear(&key->k);
9670
0
    }
9671
9672
0
    RESTORE_VECTOR_REGISTERS();
9673
9674
0
    return err;
9675
0
}
9676
9677
WOLFSSL_ABI
9678
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
9679
0
{
9680
0
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
9681
0
}
9682
#endif /* HAVE_ECC_KEY_IMPORT */
9683
9684
#ifdef HAVE_ECC_KEY_EXPORT
9685
9686
/* export ecc key to component form, d is optional if only exporting public
9687
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
9688
 * return MP_OKAY on success */
9689
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
9690
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
9691
0
{
9692
0
    int err = 0;
9693
0
    word32 keySz;
9694
9695
0
    if (key == NULL) {
9696
0
        return BAD_FUNC_ARG;
9697
0
    }
9698
9699
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9700
0
        return ECC_BAD_ARG_E;
9701
0
    }
9702
0
    keySz = key->dp->size;
9703
9704
    /* private key, d */
9705
0
    if (d != NULL) {
9706
0
        if (dLen == NULL ||
9707
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
9708
0
            return BAD_FUNC_ARG;
9709
9710
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9711
        /* Hardware cannot export private portion */
9712
        return NOT_COMPILED_IN;
9713
    #else
9714
    #if defined(WOLFSSL_SECO_CAAM)
9715
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
9716
            /* Hardware cannot export private portion */
9717
            WOLFSSL_MSG("Can not export private key from HSM");
9718
            return NOT_COMPILED_IN;
9719
        }
9720
    #endif
9721
    #ifdef WOLFSSL_QNX_CAAM
9722
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
9723
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
9724
                *dLen = keySz + WC_CAAM_MAC_SZ;
9725
                return BUFFER_E;
9726
            }
9727
9728
            err = wc_export_int(&key->k, d, dLen, keySz + WC_CAAM_MAC_SZ,
9729
                encType);
9730
            *dLen = keySz + WC_CAAM_MAC_SZ;
9731
        }
9732
        else if (encType == WC_TYPE_BLACK_KEY &&
9733
                key->blackKey != CAAM_BLACK_KEY_ECB &&
9734
                key->blackKey > 0) {
9735
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
9736
                *dLen = keySz + WC_CAAM_MAC_SZ;
9737
                return BUFFER_E;
9738
            }
9739
9740
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
9741
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
9742
                    return WC_HW_E;
9743
            }
9744
9745
            *dLen = keySz + WC_CAAM_MAC_SZ;
9746
        }
9747
        else
9748
    #endif
9749
0
        {
9750
0
            err = wc_export_int(&key->k, d, dLen, keySz, encType);
9751
0
            if (err != MP_OKAY)
9752
0
                return err;
9753
0
        }
9754
0
    #endif
9755
0
    }
9756
9757
    /* public x component */
9758
0
    if (qx != NULL) {
9759
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
9760
0
            return BAD_FUNC_ARG;
9761
9762
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
9763
0
        if (err != MP_OKAY)
9764
0
            return err;
9765
0
    }
9766
9767
    /* public y component */
9768
0
    if (qy != NULL) {
9769
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
9770
0
            return BAD_FUNC_ARG;
9771
9772
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
9773
0
        if (err != MP_OKAY)
9774
0
            return err;
9775
0
    }
9776
9777
0
    return err;
9778
0
}
9779
9780
9781
/* export ecc private key only raw, outLen is in/out size as unsigned bin
9782
   return MP_OKAY on success */
9783
WOLFSSL_ABI
9784
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
9785
0
{
9786
0
    if (out == NULL || outLen == NULL) {
9787
0
        return BAD_FUNC_ARG;
9788
0
    }
9789
9790
#ifdef WOLFSSL_QNX_CAAM
9791
    /* check if black key in secure memory */
9792
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
9793
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
9794
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
9795
            WC_TYPE_BLACK_KEY);
9796
    }
9797
#endif
9798
9799
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
9800
0
        WC_TYPE_UNSIGNED_BIN);
9801
0
}
9802
9803
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
9804
 * return MP_OKAY on success, negative on error */
9805
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
9806
                             byte* qy, word32* qyLen)
9807
0
{
9808
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
9809
0
        return BAD_FUNC_ARG;
9810
0
    }
9811
9812
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
9813
0
        WC_TYPE_UNSIGNED_BIN);
9814
0
}
9815
9816
/* export ecc key to raw elements including public (Qx,Qy) and
9817
 *   private (d) as unsigned bin
9818
 * return MP_OKAY on success, negative on error */
9819
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
9820
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
9821
0
{
9822
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
9823
0
        WC_TYPE_UNSIGNED_BIN);
9824
0
}
9825
9826
#endif /* HAVE_ECC_KEY_EXPORT */
9827
9828
#ifdef HAVE_ECC_KEY_IMPORT
9829
/* import private key, public part optional if (pub) passed as NULL */
9830
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
9831
                                 const byte* pub, word32 pubSz, ecc_key* key,
9832
                                 int curve_id)
9833
0
{
9834
0
    int ret;
9835
#ifdef WOLFSSL_CRYPTOCELL
9836
    const CRYS_ECPKI_Domain_t* pDomain;
9837
#endif
9838
0
    if (key == NULL || priv == NULL)
9839
0
        return BAD_FUNC_ARG;
9840
9841
    /* public optional, NULL if only importing private */
9842
0
    if (pub != NULL) {
9843
0
    #ifndef NO_ASN
9844
0
        word32 idx = 0;
9845
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
9846
0
        if (ret < 0)
9847
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
9848
0
        key->type = ECC_PRIVATEKEY;
9849
    #else
9850
        (void)pubSz;
9851
        ret = NOT_COMPILED_IN;
9852
    #endif
9853
0
    }
9854
0
    else {
9855
        /* make sure required variables are reset */
9856
0
        wc_ecc_reset(key);
9857
9858
        /* set key size */
9859
0
        ret = wc_ecc_set_curve(key, privSz, curve_id);
9860
0
        key->type = ECC_PRIVATEKEY_ONLY;
9861
0
    }
9862
9863
0
    if (ret != 0)
9864
0
        return ret;
9865
9866
#ifdef WOLFSSL_CRYPTOCELL
9867
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
9868
    /* import private key - priv checked for NULL at top */
9869
    if (priv[0] != '\0') {
9870
9871
        /* Create private key from external key buffer*/
9872
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
9873
                                      priv,
9874
                                      privSz,
9875
                                      &key->ctx.privKey);
9876
9877
        if (ret != SA_SILIB_RET_OK) {
9878
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
9879
            return ret;
9880
        }
9881
9882
        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
9883
    }
9884
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9885
    if (ret == MP_OKAY)
9886
        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
9887
9888
    if (ret == MP_OKAY) {
9889
        if (pub) {
9890
            ret = silabs_ecc_import(key, key->dp->size);
9891
        }
9892
        else {
9893
            ret = silabs_ecc_import_private(key, key->dp->size);
9894
        }
9895
    }
9896
#elif defined(WOLFSSL_QNX_CAAM)
9897
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
9898
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
9899
        int part = caamFindUnusedPartition();
9900
        if (part >= 0) {
9901
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
9902
            if (vaddr == 0) {
9903
                WOLFSSL_MSG("Unable to get partition");
9904
                return MEMORY_E;
9905
            }
9906
9907
            key->partNum  = part;
9908
            key->blackKey = (word32)vaddr;
9909
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
9910
                return WC_HW_E;
9911
9912
            if (pub != NULL) {
9913
                /* +1 to account for x963 compressed bit */
9914
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
9915
                    return WC_HW_E;
9916
                key->securePubKey = (word32)vaddr + privSz;
9917
            }
9918
        }
9919
        else {
9920
            WOLFSSL_MSG("Unable to find an unused partition");
9921
            return MEMORY_E;
9922
        }
9923
    #else
9924
        key->blackKey = CAAM_BLACK_KEY_CCM;
9925
        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
9926
    #endif
9927
    }
9928
    else {
9929
        key->blackKey = 0;
9930
        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
9931
9932
        /* If using AES-ECB encrypted black keys check here if key is valid,
9933
         * if not valid than assume is an encrypted key. A public key is needed
9934
         * for testing validity. */
9935
        if (key->devId == WOLFSSL_CAAM_DEVID && (
9936
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
9937
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
9938
            if ((pub != NULL) && (ret == MP_OKAY) &&
9939
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
9940
                key->blackKey = CAAM_BLACK_KEY_ECB;
9941
            }
9942
            else if ((pub == NULL) && (ret == MP_OKAY)) {
9943
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
9944
                key->blackKey = CAAM_BLACK_KEY_ECB;
9945
            }
9946
            else {
9947
                WOLFSSL_MSG("Importing key that is not a black key!");
9948
            }
9949
        }
9950
    }
9951
#else
9952
9953
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
9954
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9955
#endif
9956
9957
0
    ret = mp_read_unsigned_bin(&key->k, priv, privSz);
9958
#ifdef HAVE_WOLF_BIGINT
9959
    if (ret == 0 &&
9960
                  wc_bigint_from_unsigned_bin(&key->k.raw, priv, privSz) != 0) {
9961
        mp_clear(&key->k);
9962
        ret = ASN_GETINT_E;
9963
    }
9964
#endif /* HAVE_WOLF_BIGINT */
9965
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
9966
    if (ret == 0) {
9967
    #ifdef WOLFSSL_SMALL_STACK
9968
        mp_int* order = NULL;
9969
    #else
9970
        mp_int order[1];
9971
    #endif
9972
9973
    #ifdef WOLFSSL_SMALL_STACK
9974
        order = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9975
        if (order == NULL) {
9976
            ret = MEMORY_E;
9977
        }
9978
    #endif
9979
9980
        if (ret == 0) {
9981
            ret = mp_init(order);
9982
        }
9983
        if (ret == 0) {
9984
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
9985
        }
9986
        if ((ret == 0) && (mp_cmp(&key->k, order) != MP_LT)) {
9987
            ret = ECC_PRIV_KEY_E;
9988
        }
9989
9990
    #ifdef WOLFSSL_SMALL_STACK
9991
        XFREE(order, key->heap, DYNAMIC_TYPE_ECC);
9992
    #endif
9993
    }
9994
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
9995
9996
0
#endif /* WOLFSSL_CRYPTOCELL */
9997
9998
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
9999
    if ((pub != NULL) && (ret == MP_OKAY))
10000
        /* public key needed to perform key validation */
10001
        ret = _ecc_validate_public_key(key, 1, 1);
10002
10003
#endif
10004
10005
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10006
    RESTORE_VECTOR_REGISTERS();
10007
#endif
10008
10009
0
    return ret;
10010
0
}
10011
10012
/* ecc private key import, public key in ANSI X9.63 format, private raw */
10013
WOLFSSL_ABI
10014
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
10015
                           word32 pubSz, ecc_key* key)
10016
0
{
10017
0
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
10018
0
                                                                ECC_CURVE_DEF);
10019
0
}
10020
#endif /* HAVE_ECC_KEY_IMPORT */
10021
10022
#ifndef NO_ASN
10023
/**
10024
   Convert ECC R,S to signature
10025
   r       R component of signature
10026
   s       S component of signature
10027
   out     DER-encoded ECDSA signature
10028
   outlen  [in/out] output buffer size, output signature size
10029
   return  MP_OKAY on success
10030
*/
10031
WOLFSSL_ABI
10032
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
10033
0
{
10034
0
    int err;
10035
0
#ifdef WOLFSSL_SMALL_STACK
10036
0
    mp_int* rtmp = NULL;
10037
0
    mp_int* stmp = NULL;
10038
#else
10039
    mp_int  rtmp[1];
10040
    mp_int  stmp[1];
10041
#endif
10042
10043
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
10044
0
        return ECC_BAD_ARG_E;
10045
10046
0
#ifdef WOLFSSL_SMALL_STACK
10047
0
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10048
0
    if (rtmp == NULL)
10049
0
        return MEMORY_E;
10050
0
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10051
0
    if (stmp == NULL) {
10052
0
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
10053
0
        return MEMORY_E;
10054
0
    }
10055
0
#endif
10056
10057
0
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
10058
0
    if (err != MP_OKAY) {
10059
0
    #ifdef WOLFSSL_SMALL_STACK
10060
0
        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
10061
0
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
10062
0
    #endif
10063
0
        return err;
10064
0
    }
10065
10066
0
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
10067
0
    if (err == MP_OKAY)
10068
0
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
10069
10070
0
    if (err == MP_OKAY) {
10071
0
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
10072
0
            err = MP_ZERO_E;
10073
0
    }
10074
0
    if (err == MP_OKAY) {
10075
0
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
10076
0
            err = MP_READ_E;
10077
0
        }
10078
0
    }
10079
10080
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
10081
0
    if (err == MP_OKAY)
10082
0
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
10083
10084
0
    mp_clear(rtmp);
10085
0
    mp_clear(stmp);
10086
0
#ifdef WOLFSSL_SMALL_STACK
10087
0
    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
10088
0
    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
10089
0
#endif
10090
10091
0
    return err;
10092
0
}
10093
10094
/**
10095
   Convert ECC R,S raw unsigned bin to signature
10096
   r       R component of signature
10097
   rSz     R size
10098
   s       S component of signature
10099
   sSz     S size
10100
   out     DER-encoded ECDSA signature
10101
   outlen  [in/out] output buffer size, output signature size
10102
   return  MP_OKAY on success
10103
*/
10104
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
10105
    byte* out, word32* outlen)
10106
0
{
10107
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
10108
0
        return ECC_BAD_ARG_E;
10109
10110
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
10111
0
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
10112
0
}
10113
10114
/**
10115
   Convert ECC signature to R,S
10116
   sig     DER-encoded ECDSA signature
10117
   sigLen  length of signature in octets
10118
   r       R component of signature
10119
   rLen    [in/out] output "r" buffer size, output "r" size
10120
   s       S component of signature
10121
   sLen    [in/out] output "s" buffer size, output "s" size
10122
   return  MP_OKAY on success, negative on error
10123
*/
10124
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
10125
                     byte* s, word32* sLen)
10126
0
{
10127
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
10128
0
        return ECC_BAD_ARG_E;
10129
10130
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
10131
0
}
10132
#endif /* !NO_ASN */
10133
10134
#ifdef HAVE_ECC_KEY_IMPORT
10135
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
10136
          const char* qy, const char* d, int curve_id, int encType)
10137
0
{
10138
0
    int err = MP_OKAY;
10139
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
10140
    !defined(WOLFSSL_ATECC608A)
10141
    const CRYS_ECPKI_Domain_t* pDomain;
10142
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10143
    byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
10144
#endif
10145
10146
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
10147
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_CRYPTOCELL)
10148
    word32 keySz = 0;
10149
#endif
10150
10151
    /* if d is NULL, only import as public key using Qx,Qy */
10152
0
    if (key == NULL || qx == NULL || qy == NULL) {
10153
0
        return BAD_FUNC_ARG;
10154
0
    }
10155
10156
    /* make sure required variables are reset */
10157
0
    wc_ecc_reset(key);
10158
10159
    /* set curve type and index */
10160
0
    err = wc_ecc_set_curve(key, 0, curve_id);
10161
0
    if (err != 0) {
10162
0
        return err;
10163
0
    }
10164
10165
    /* init key */
10166
#ifdef ALT_ECC_SIZE
10167
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10168
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10169
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10170
    alt_fp_init(key->pubkey.x);
10171
    alt_fp_init(key->pubkey.y);
10172
    alt_fp_init(key->pubkey.z);
10173
    err = mp_init(&key->k);
10174
#else
10175
0
    err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10176
0
                                                                  NULL, NULL);
10177
0
#endif
10178
0
    if (err != MP_OKAY)
10179
0
        return MEMORY_E;
10180
10181
    /* read Qx */
10182
0
    if (err == MP_OKAY) {
10183
0
        if (encType == WC_TYPE_HEX_STR)
10184
0
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
10185
0
        else
10186
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
10187
0
                key->dp->size);
10188
10189
0
        if (mp_isneg(key->pubkey.x)) {
10190
0
            WOLFSSL_MSG("Invalid Qx");
10191
0
            err = BAD_FUNC_ARG;
10192
0
        }
10193
0
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
10194
0
            err = BAD_FUNC_ARG;
10195
0
        }
10196
0
    }
10197
10198
    /* read Qy */
10199
0
    if (err == MP_OKAY) {
10200
0
        if (encType == WC_TYPE_HEX_STR)
10201
0
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
10202
0
        else
10203
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
10204
0
                key->dp->size);
10205
10206
0
        if (mp_isneg(key->pubkey.y)) {
10207
0
            WOLFSSL_MSG("Invalid Qy");
10208
0
            err = BAD_FUNC_ARG;
10209
0
        }
10210
0
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
10211
0
            err = BAD_FUNC_ARG;
10212
0
        }
10213
0
    }
10214
10215
0
    if (err == MP_OKAY) {
10216
0
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
10217
0
            WOLFSSL_MSG("Invalid Qx and Qy");
10218
0
            err = ECC_INF_E;
10219
0
        }
10220
0
    }
10221
10222
0
    if (err == MP_OKAY)
10223
0
        err = mp_set(key->pubkey.z, 1);
10224
10225
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10226
    /* For SECP256R1 only save raw public key for hardware */
10227
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
10228
        keySz = key->dp->size;
10229
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
10230
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
10231
        if (err == MP_OKAY)
10232
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
10233
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
10234
    }
10235
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10236
    keySz = key->dp->size;
10237
    if (err == MP_OKAY) {
10238
        err = silabs_ecc_sig_to_rs(key, keySz);
10239
    }
10240
#elif defined(WOLFSSL_CRYPTOCELL)
10241
    if (err == MP_OKAY) {
10242
        key_raw[0] = ECC_POINT_UNCOMP;
10243
        keySz = (word32)key->dp->size;
10244
        err = wc_export_int(key->pubkey.x, &key_raw[1], &keySz, keySz,
10245
            WC_TYPE_UNSIGNED_BIN);
10246
        if (err == MP_OKAY) {
10247
            err = wc_export_int(key->pubkey.y, &key_raw[1+keySz],
10248
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
10249
        }
10250
10251
        if (err == MP_OKAY) {
10252
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
10253
10254
            /* create public key from external key buffer */
10255
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
10256
                                                   key_raw,
10257
                                                   keySz*2 + 1,
10258
                                                   &key->ctx.pubKey,
10259
                                                   &tempBuff);
10260
        }
10261
10262
        if (err != SA_SILIB_RET_OK){
10263
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
10264
            return err;
10265
        }
10266
    }
10267
#elif defined(WOLFSSL_KCAPI_ECC)
10268
    if (err == MP_OKAY) {
10269
        word32 keySz = key->dp->size;
10270
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
10271
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
10272
        if (err == MP_OKAY) {
10273
            err = wc_export_int(key->pubkey.y,
10274
                &key->pubkey_raw[keySz], &keySz, keySz,
10275
                WC_TYPE_UNSIGNED_BIN);
10276
        }
10277
    }
10278
#endif
10279
10280
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10281
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10282
#endif
10283
10284
    /* import private key */
10285
0
    if (err == MP_OKAY) {
10286
0
        if (d != NULL) {
10287
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10288
            /* Hardware doesn't support loading private key */
10289
            err = NOT_COMPILED_IN;
10290
10291
        #elif defined(WOLFSSL_SILABS_SE_ACCEL)
10292
            err = silabs_ecc_import_private_raw(key, keySz, d, encType);
10293
10294
        #elif defined(WOLFSSL_CRYPTOCELL)
10295
            key->type = ECC_PRIVATEKEY;
10296
10297
            if (encType == WC_TYPE_HEX_STR)
10298
                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
10299
            else
10300
                err = mp_read_unsigned_bin(&key->k, (const byte*)d,
10301
                    key->dp->size);
10302
            if (err == MP_OKAY) {
10303
                err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz,
10304
                    WC_TYPE_UNSIGNED_BIN);
10305
            }
10306
10307
            if (err == MP_OKAY) {
10308
                /* Create private key from external key buffer*/
10309
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
10310
                                              key_raw,
10311
                                              keySz,
10312
                                              &key->ctx.privKey);
10313
10314
                if (err != SA_SILIB_RET_OK){
10315
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
10316
                    return err;
10317
                }
10318
            }
10319
10320
        #else
10321
0
            key->type = ECC_PRIVATEKEY;
10322
0
            if (encType == WC_TYPE_HEX_STR)
10323
0
                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
10324
0
            else {
10325
            #ifdef WOLFSSL_QNX_CAAM
10326
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
10327
                    err = mp_read_unsigned_bin(&key->k, (const byte*)d,
10328
                    key->dp->size + WC_CAAM_MAC_SZ);
10329
                }
10330
                else
10331
            #endif /* WOLFSSL_QNX_CAAM */
10332
0
                {
10333
0
                    err = mp_read_unsigned_bin(&key->k, (const byte*)d,
10334
0
                    key->dp->size);
10335
0
                }
10336
0
            }
10337
0
        #endif /* WOLFSSL_ATECC508A */
10338
0
            if (mp_iszero(&key->k) || mp_isneg(&key->k)) {
10339
0
                WOLFSSL_MSG("Invalid private key");
10340
0
                return BAD_FUNC_ARG;
10341
0
            }
10342
0
        } else {
10343
0
            key->type = ECC_PUBLICKEY;
10344
0
        }
10345
0
    }
10346
10347
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10348
    if (err == MP_OKAY) {
10349
        err = wc_ecc_check_key(key);
10350
        if (err == IS_POINT_E && (mp_iszero(key->pubkey.x) ||
10351
                                  mp_iszero(key->pubkey.y))) {
10352
            err = BAD_FUNC_ARG;
10353
        }
10354
    }
10355
#endif
10356
10357
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10358
    RESTORE_VECTOR_REGISTERS();
10359
#endif
10360
10361
0
    if (err != MP_OKAY) {
10362
0
        mp_clear(key->pubkey.x);
10363
0
        mp_clear(key->pubkey.y);
10364
0
        mp_clear(key->pubkey.z);
10365
0
        mp_clear(&key->k);
10366
0
    }
10367
10368
0
    return err;
10369
0
}
10370
10371
/**
10372
   Import raw ECC key
10373
   key       The destination ecc_key structure
10374
   qx        x component of the public key, as ASCII hex string
10375
   qy        y component of the public key, as ASCII hex string
10376
   d         private key, as ASCII hex string, optional if importing public
10377
             key only
10378
   dp        Custom ecc_set_type
10379
   return    MP_OKAY on success
10380
*/
10381
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
10382
                   const char* d, int curve_id)
10383
0
{
10384
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
10385
0
        WC_TYPE_HEX_STR);
10386
10387
0
}
10388
10389
/* Import x, y and optional private (d) as unsigned binary */
10390
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
10391
                   const byte* d, int curve_id)
10392
0
{
10393
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
10394
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
10395
0
}
10396
10397
/**
10398
   Import raw ECC key
10399
   key       The destination ecc_key structure
10400
   qx        x component of the public key, as ASCII hex string
10401
   qy        y component of the public key, as ASCII hex string
10402
   d         private key, as ASCII hex string, optional if importing public
10403
             key only
10404
   curveName ECC curve name, from ecc_sets[]
10405
   return    MP_OKAY on success
10406
*/
10407
WOLFSSL_ABI
10408
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
10409
                   const char* d, const char* curveName)
10410
0
{
10411
0
    int err, x;
10412
10413
    /* if d is NULL, only import as public key using Qx,Qy */
10414
0
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
10415
0
        return BAD_FUNC_ARG;
10416
0
    }
10417
10418
    /* set curve type and index */
10419
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
10420
0
        if (XSTRNCMP(ecc_sets[x].name, curveName,
10421
0
                     XSTRLEN(curveName)) == 0) {
10422
0
            break;
10423
0
        }
10424
0
    }
10425
10426
0
    if (ecc_sets[x].size == 0) {
10427
0
        WOLFSSL_MSG("ecc_set curve name not found");
10428
0
        err = ASN_PARSE_E;
10429
0
    } else {
10430
0
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
10431
0
            WC_TYPE_HEX_STR);
10432
0
    }
10433
10434
0
    return err;
10435
0
}
10436
#endif /* HAVE_ECC_KEY_IMPORT */
10437
10438
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
10439
/* public key size in octets */
10440
static int ecc_public_key_size(ecc_key* key, word32* sz)
10441
0
{
10442
0
    if (key == NULL || key->dp == NULL)
10443
0
        return BAD_FUNC_ARG;
10444
10445
    /* 'Uncompressed' | x | y */
10446
0
    *sz = 1 + 2 * key->dp->size;
10447
10448
0
    return 0;
10449
0
}
10450
#endif
10451
10452
/* key size in octets */
10453
WOLFSSL_ABI
10454
int wc_ecc_size(ecc_key* key)
10455
0
{
10456
0
    if (key == NULL || key->dp == NULL)
10457
0
        return 0;
10458
10459
0
    return key->dp->size;
10460
0
}
10461
10462
/* maximum signature size based on key size */
10463
WOLFSSL_ABI
10464
int wc_ecc_sig_size_calc(int sz)
10465
0
{
10466
0
    int maxSigSz = 0;
10467
10468
    /* calculate based on key bits */
10469
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
10470
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
10471
10472
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
10473
0
    if (maxSigSz < (128 + 2)) {
10474
0
        maxSigSz -= 1;
10475
0
    }
10476
10477
0
    return maxSigSz;
10478
0
}
10479
10480
/* maximum signature size based on actual key curve */
10481
WOLFSSL_ABI
10482
int wc_ecc_sig_size(const ecc_key* key)
10483
0
{
10484
0
    int maxSigSz;
10485
0
    int orderBits, keySz;
10486
10487
0
    if (key == NULL || key->dp == NULL)
10488
0
        return 0;
10489
10490
    /* the signature r and s will always be less than order */
10491
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
10492
        extra byte for r and s, so add 2 */
10493
0
    keySz = key->dp->size;
10494
0
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
10495
0
    if (orderBits > keySz * 8) {
10496
0
        keySz = (orderBits + 7) / 8;
10497
0
    }
10498
    /* maximum possible signature header size is 7 bytes */
10499
0
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
10500
0
    if ((orderBits % 8) == 0) {
10501
        /* MSB can be set, so add 2 */
10502
0
        maxSigSz += ECC_MAX_PAD_SZ;
10503
0
    }
10504
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
10505
0
    if (maxSigSz < (128 + 2)) {
10506
0
        maxSigSz -= 1;
10507
0
    }
10508
10509
0
    return maxSigSz;
10510
0
}
10511
10512
10513
#ifdef FP_ECC
10514
10515
/* fixed point ECC cache */
10516
/* number of entries in the cache */
10517
#ifndef FP_ENTRIES
10518
    #define FP_ENTRIES 15
10519
#endif
10520
10521
/* number of bits in LUT */
10522
#ifndef FP_LUT
10523
    #define FP_LUT     8U
10524
#endif
10525
10526
#ifdef ECC_SHAMIR
10527
    /* Sharmir requires a bigger LUT, TAO */
10528
    #if (FP_LUT > 12) || (FP_LUT < 4)
10529
        #error FP_LUT must be between 4 and 12 inclusively
10530
    #endif
10531
#else
10532
    #if (FP_LUT > 12) || (FP_LUT < 2)
10533
        #error FP_LUT must be between 2 and 12 inclusively
10534
    #endif
10535
#endif
10536
10537
10538
#if !defined(WOLFSSL_SP_MATH)
10539
10540
/** Our FP cache */
10541
typedef struct {
10542
   ecc_point* g;               /* cached COPY of base point */
10543
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
10544
   int        LUT_set;         /* flag to determine if the LUT has been computed */
10545
   mp_int     mu;              /* copy of the montgomery constant */
10546
   int        lru_count;       /* amount of times this entry has been used */
10547
   int        lock;            /* flag to indicate cache eviction */
10548
                               /* permitted (0) or not (1) */
10549
} fp_cache_t;
10550
10551
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
10552
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
10553
10554
#ifndef HAVE_THREAD_LS
10555
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
10556
    static wolfSSL_Mutex ecc_fp_lock;
10557
#endif /* HAVE_THREAD_LS */
10558
10559
/* simple table to help direct the generation of the LUT */
10560
static const struct {
10561
   int ham, terma, termb;
10562
} lut_orders[] = {
10563
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
10564
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
10565
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
10566
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
10567
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
10568
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
10569
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
10570
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
10571
#if FP_LUT > 6
10572
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
10573
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
10574
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
10575
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
10576
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
10577
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
10578
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
10579
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
10580
#if FP_LUT > 7
10581
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
10582
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
10583
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
10584
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
10585
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
10586
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
10587
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
10588
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
10589
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
10590
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
10591
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
10592
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
10593
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
10594
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
10595
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
10596
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
10597
#if FP_LUT > 8
10598
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
10599
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
10600
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
10601
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
10602
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
10603
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
10604
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
10605
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
10606
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
10607
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
10608
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
10609
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
10610
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
10611
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
10612
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
10613
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
10614
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
10615
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
10616
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
10617
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
10618
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
10619
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
10620
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
10621
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
10622
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
10623
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
10624
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
10625
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
10626
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
10627
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
10628
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
10629
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
10630
#if FP_LUT > 9
10631
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
10632
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
10633
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
10634
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
10635
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
10636
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
10637
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
10638
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
10639
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
10640
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
10641
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
10642
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
10643
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
10644
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
10645
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
10646
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
10647
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
10648
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
10649
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
10650
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
10651
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
10652
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
10653
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
10654
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
10655
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
10656
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
10657
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
10658
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
10659
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
10660
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
10661
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
10662
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
10663
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
10664
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
10665
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
10666
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
10667
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
10668
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
10669
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
10670
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
10671
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
10672
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
10673
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
10674
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
10675
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
10676
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
10677
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
10678
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
10679
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
10680
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
10681
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
10682
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
10683
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
10684
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
10685
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
10686
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
10687
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
10688
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
10689
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
10690
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
10691
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
10692
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
10693
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
10694
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
10695
#if FP_LUT > 10
10696
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
10697
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
10698
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
10699
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
10700
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
10701
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
10702
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
10703
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
10704
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
10705
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
10706
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
10707
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
10708
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
10709
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
10710
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
10711
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
10712
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
10713
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
10714
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
10715
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
10716
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
10717
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
10718
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
10719
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
10720
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
10721
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
10722
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
10723
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
10724
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
10725
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
10726
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
10727
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
10728
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
10729
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
10730
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
10731
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
10732
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
10733
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
10734
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
10735
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
10736
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
10737
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
10738
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
10739
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
10740
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
10741
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
10742
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
10743
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
10744
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
10745
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
10746
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
10747
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
10748
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
10749
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
10750
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
10751
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
10752
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
10753
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
10754
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
10755
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
10756
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
10757
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
10758
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
10759
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
10760
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
10761
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
10762
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
10763
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
10764
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
10765
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
10766
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
10767
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
10768
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
10769
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
10770
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
10771
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
10772
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
10773
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
10774
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
10775
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
10776
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
10777
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
10778
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
10779
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
10780
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
10781
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
10782
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
10783
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
10784
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
10785
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
10786
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
10787
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
10788
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
10789
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
10790
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
10791
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
10792
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
10793
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
10794
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
10795
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
10796
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
10797
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
10798
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
10799
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
10800
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
10801
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
10802
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
10803
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
10804
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
10805
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
10806
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
10807
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
10808
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
10809
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
10810
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
10811
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
10812
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
10813
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
10814
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
10815
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
10816
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
10817
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
10818
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
10819
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
10820
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
10821
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
10822
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
10823
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
10824
#if FP_LUT > 11
10825
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
10826
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
10827
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
10828
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
10829
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
10830
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
10831
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
10832
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
10833
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
10834
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
10835
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
10836
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
10837
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
10838
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
10839
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
10840
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
10841
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
10842
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
10843
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
10844
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
10845
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
10846
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
10847
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
10848
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
10849
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
10850
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
10851
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
10852
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
10853
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
10854
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
10855
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
10856
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
10857
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
10858
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
10859
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
10860
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
10861
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
10862
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
10863
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
10864
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
10865
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
10866
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
10867
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
10868
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
10869
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
10870
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
10871
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
10872
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
10873
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
10874
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
10875
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
10876
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
10877
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
10878
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
10879
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
10880
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
10881
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
10882
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
10883
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
10884
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
10885
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
10886
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
10887
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
10888
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
10889
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
10890
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
10891
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
10892
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
10893
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
10894
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
10895
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
10896
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
10897
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
10898
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
10899
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
10900
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
10901
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
10902
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
10903
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
10904
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
10905
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
10906
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
10907
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
10908
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
10909
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
10910
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
10911
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
10912
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
10913
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
10914
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
10915
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
10916
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
10917
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
10918
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
10919
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
10920
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
10921
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
10922
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
10923
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
10924
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
10925
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
10926
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
10927
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
10928
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
10929
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
10930
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
10931
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
10932
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
10933
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
10934
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
10935
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
10936
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
10937
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
10938
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
10939
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
10940
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
10941
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
10942
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
10943
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
10944
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
10945
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
10946
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
10947
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
10948
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
10949
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
10950
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
10951
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
10952
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
10953
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
10954
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
10955
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
10956
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
10957
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
10958
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
10959
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
10960
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
10961
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
10962
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
10963
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
10964
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
10965
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
10966
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
10967
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
10968
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
10969
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
10970
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
10971
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
10972
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
10973
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
10974
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
10975
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
10976
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
10977
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
10978
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
10979
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
10980
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
10981
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
10982
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
10983
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
10984
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
10985
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
10986
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
10987
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
10988
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
10989
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
10990
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
10991
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
10992
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
10993
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
10994
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
10995
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
10996
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
10997
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
10998
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
10999
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
11000
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
11001
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
11002
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
11003
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
11004
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
11005
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
11006
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
11007
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
11008
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
11009
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
11010
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
11011
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
11012
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
11013
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
11014
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
11015
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
11016
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
11017
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
11018
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
11019
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
11020
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
11021
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
11022
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
11023
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
11024
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
11025
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
11026
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
11027
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
11028
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
11029
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
11030
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
11031
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
11032
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
11033
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
11034
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
11035
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
11036
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
11037
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
11038
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
11039
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
11040
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
11041
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
11042
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
11043
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
11044
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
11045
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
11046
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
11047
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
11048
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
11049
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
11050
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
11051
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
11052
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
11053
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
11054
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
11055
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
11056
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
11057
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
11058
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
11059
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
11060
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
11061
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
11062
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
11063
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
11064
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
11065
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
11066
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
11067
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
11068
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
11069
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
11070
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
11071
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
11072
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
11073
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
11074
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
11075
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
11076
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
11077
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
11078
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
11079
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
11080
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
11081
#endif
11082
#endif
11083
#endif
11084
#endif
11085
#endif
11086
#endif
11087
};
11088
11089
11090
/* find a hole and free as required, return -1 if no hole found */
11091
static int find_hole(void)
11092
{
11093
   unsigned x;
11094
   int      y, z;
11095
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
11096
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
11097
          z = x;
11098
          y = fp_cache[x].lru_count;
11099
       }
11100
   }
11101
11102
   /* decrease all */
11103
   for (x = 0; x < FP_ENTRIES; x++) {
11104
      if (fp_cache[x].lru_count > 3) {
11105
         --(fp_cache[x].lru_count);
11106
      }
11107
   }
11108
11109
   /* free entry z */
11110
   if (z >= 0 && fp_cache[z].g) {
11111
      mp_clear(&fp_cache[z].mu);
11112
      wc_ecc_del_point(fp_cache[z].g);
11113
      fp_cache[z].g  = NULL;
11114
      for (x = 0; x < (1U<<FP_LUT); x++) {
11115
         wc_ecc_del_point(fp_cache[z].LUT[x]);
11116
         fp_cache[z].LUT[x] = NULL;
11117
      }
11118
      fp_cache[z].LUT_set = 0;
11119
      fp_cache[z].lru_count = 0;
11120
   }
11121
   return z;
11122
}
11123
11124
/* determine if a base is already in the cache and if so, where */
11125
static int find_base(ecc_point* g)
11126
{
11127
   int x;
11128
   for (x = 0; x < FP_ENTRIES; x++) {
11129
      if (fp_cache[x].g != NULL &&
11130
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
11131
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
11132
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
11133
         break;
11134
      }
11135
   }
11136
   if (x == FP_ENTRIES) {
11137
      x = -1;
11138
   }
11139
   return x;
11140
}
11141
11142
/* add a new base to the cache */
11143
static int add_entry(int idx, ecc_point *g)
11144
{
11145
   unsigned x, y;
11146
11147
   /* allocate base and LUT */
11148
   fp_cache[idx].g = wc_ecc_new_point();
11149
   if (fp_cache[idx].g == NULL) {
11150
      return GEN_MEM_ERR;
11151
   }
11152
11153
   /* copy x and y */
11154
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
11155
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
11156
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
11157
      wc_ecc_del_point(fp_cache[idx].g);
11158
      fp_cache[idx].g = NULL;
11159
      return GEN_MEM_ERR;
11160
   }
11161
11162
   for (x = 0; x < (1U<<FP_LUT); x++) {
11163
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
11164
      if (fp_cache[idx].LUT[x] == NULL) {
11165
         for (y = 0; y < x; y++) {
11166
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
11167
            fp_cache[idx].LUT[y] = NULL;
11168
         }
11169
         wc_ecc_del_point(fp_cache[idx].g);
11170
         fp_cache[idx].g         = NULL;
11171
         fp_cache[idx].lru_count = 0;
11172
         return GEN_MEM_ERR;
11173
      }
11174
   }
11175
11176
   fp_cache[idx].LUT_set   = 0;
11177
   fp_cache[idx].lru_count = 0;
11178
11179
   return MP_OKAY;
11180
}
11181
#endif
11182
11183
#if !defined(WOLFSSL_SP_MATH)
11184
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
11185
 *
11186
 * The algorithm builds patterns in increasing bit order by first making all
11187
 * single bit input patterns, then all two bit input patterns and so on
11188
 */
11189
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
11190
    mp_int* mu)
11191
{
11192
   int err;
11193
   unsigned x, y, bitlen, lut_gap;
11194
#ifdef WOLFSSL_SMALL_STACK
11195
   mp_int *tmp = NULL;
11196
#else
11197
   mp_int tmp[1];
11198
#endif
11199
   int infinity;
11200
11201
#ifdef WOLFSSL_SMALL_STACK
11202
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
11203
       return MEMORY_E;
11204
#endif
11205
11206
   err = mp_init(tmp);
11207
   if (err != MP_OKAY) {
11208
       err = GEN_MEM_ERR;
11209
       goto errout;
11210
   }
11211
11212
   /* sanity check to make sure lut_order table is of correct size,
11213
      should compile out to a NOP if true */
11214
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
11215
       err = BAD_FUNC_ARG;
11216
       goto errout;
11217
   }
11218
11219
   /* get bitlen and round up to next multiple of FP_LUT */
11220
   bitlen  = mp_unsigned_bin_size(modulus) << 3;
11221
   x       = bitlen % FP_LUT;
11222
   if (x) {
11223
       bitlen += FP_LUT - x;
11224
   }
11225
   lut_gap = bitlen / FP_LUT;
11226
11227
   /* init the mu */
11228
   err = mp_init_copy(&fp_cache[idx].mu, mu);
11229
   if (err != MP_OKAY)
11230
       goto errout;
11231
11232
   /* copy base */
11233
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
11234
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
11235
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
11236
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
11237
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
11238
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
11239
       err = MP_MULMOD_E;
11240
       goto errout;
11241
   }
11242
11243
   /* make all single bit entries */
11244
   for (x = 1; x < FP_LUT; x++) {
11245
      if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
11246
                   fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
11247
          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
11248
                   fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
11249
          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
11250
                   fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
11251
          err = MP_INIT_E;
11252
          goto errout;
11253
      } else {
11254
11255
         /* now double it bitlen/FP_LUT times */
11256
         for (y = 0; y < lut_gap; y++) {
11257
             if ((err = ecc_projective_dbl_point_safe(fp_cache[idx].LUT[1<<x],
11258
                            fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
11259
                 goto errout;
11260
             }
11261
         }
11262
     }
11263
  }
11264
11265
   /* now make all entries in increase order of hamming weight */
11266
   for (x = 2; x <= FP_LUT; x++) {
11267
       if (err != MP_OKAY)
11268
           goto errout;
11269
       for (y = 0; y < (1UL<<FP_LUT); y++) {
11270
           if (lut_orders[y].ham != (int)x) continue;
11271
11272
           /* perform the add */
11273
           if ((err = ecc_projective_add_point_safe(
11274
                           fp_cache[idx].LUT[lut_orders[y].terma],
11275
                           fp_cache[idx].LUT[lut_orders[y].termb],
11276
                           fp_cache[idx].LUT[y], a, modulus, mp,
11277
                           &infinity)) != MP_OKAY) {
11278
               goto errout;
11279
           }
11280
       }
11281
   }
11282
11283
   /* now map all entries back to affine space to make point addition faster */
11284
   for (x = 1; x < (1UL<<FP_LUT); x++) {
11285
       if (err != MP_OKAY)
11286
           break;
11287
11288
       /* convert z to normal from montgomery */
11289
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
11290
11291
       /* invert it */
11292
       if (err == MP_OKAY)
11293
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
11294
                         fp_cache[idx].LUT[x]->z);
11295
11296
       if (err == MP_OKAY)
11297
         /* now square it */
11298
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
11299
11300
       if (err == MP_OKAY)
11301
         /* fix x */
11302
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
11303
                         fp_cache[idx].LUT[x]->x);
11304
11305
       if (err == MP_OKAY)
11306
         /* get 1/z^3 */
11307
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
11308
11309
       if (err == MP_OKAY)
11310
         /* fix y */
11311
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
11312
                         fp_cache[idx].LUT[x]->y);
11313
11314
       if (err == MP_OKAY)
11315
         /* free z */
11316
         mp_clear(fp_cache[idx].LUT[x]->z);
11317
   }
11318
11319
  errout:
11320
11321
   mp_clear(tmp);
11322
#ifdef WOLFSSL_SMALL_STACK
11323
   XFREE(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11324
#endif
11325
11326
   if (err == MP_OKAY) {
11327
       fp_cache[idx].LUT_set = 1;
11328
       return MP_OKAY;
11329
   }
11330
11331
   /* err cleanup */
11332
   for (y = 0; y < (1U<<FP_LUT); y++) {
11333
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
11334
      fp_cache[idx].LUT[y] = NULL;
11335
   }
11336
   wc_ecc_del_point(fp_cache[idx].g);
11337
   fp_cache[idx].g         = NULL;
11338
   fp_cache[idx].LUT_set   = 0;
11339
   fp_cache[idx].lru_count = 0;
11340
   mp_clear(&fp_cache[idx].mu);
11341
11342
   return err;
11343
}
11344
11345
/* perform a fixed point ECC mulmod */
11346
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
11347
                        mp_int* modulus, mp_digit mp, int map)
11348
{
11349
#ifdef WOLFCRYPT_HAVE_SAKKE
11350
    #define KB_SIZE 256
11351
#else
11352
    #define KB_SIZE 128
11353
#endif
11354
11355
#ifdef WOLFSSL_SMALL_STACK
11356
   unsigned char* kb = NULL;
11357
   mp_int*        tk = NULL;
11358
   mp_int*        order = NULL;
11359
#else
11360
   unsigned char kb[KB_SIZE];
11361
   mp_int        tk[1];
11362
   mp_int        order[1];
11363
#endif
11364
   int      x, err;
11365
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
11366
   int first;
11367
11368
#ifdef WOLFSSL_SMALL_STACK
11369
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11370
   if (tk == NULL) {
11371
      err = MEMORY_E; goto done;
11372
   }
11373
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11374
   if (order == NULL) {
11375
      err = MEMORY_E; goto done;
11376
   }
11377
#endif
11378
11379
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
11380
       err = MP_INIT_E; goto done;
11381
   }
11382
11383
   if ((err = mp_copy(k, tk)) != MP_OKAY)
11384
       goto done;
11385
11386
#ifdef WOLFSSL_CHECK_MEM_ZERO
11387
   mp_memzero_add("accel_fp_mul tk", tk);
11388
#endif
11389
11390
   /* if it's smaller than modulus we fine */
11391
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
11392
      /* find order */
11393
      y = mp_unsigned_bin_size(modulus);
11394
      for (x = 0; ecc_sets[x].size; x++) {
11395
         if (y <= (unsigned)ecc_sets[x].size) break;
11396
      }
11397
11398
      /* back off if we are on the 521 bit curve */
11399
      if (y == 66) --x;
11400
11401
      if ((err = mp_read_radix(order, ecc_sets[x].order,
11402
                                                MP_RADIX_HEX)) != MP_OKAY) {
11403
         goto done;
11404
      }
11405
11406
      /* k must be less than modulus */
11407
      if (mp_cmp(tk, order) != MP_LT) {
11408
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
11409
            goto done;
11410
         }
11411
      }
11412
   }
11413
11414
   /* get bitlen and round up to next multiple of FP_LUT */
11415
   bitlen  = mp_unsigned_bin_size(modulus) << 3;
11416
   x       = bitlen % FP_LUT;
11417
   if (x) {
11418
      bitlen += FP_LUT - x;
11419
   }
11420
   lut_gap = bitlen / FP_LUT;
11421
11422
   /* get the k value */
11423
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
11424
      err = BUFFER_E; goto done;
11425
   }
11426
11427
   /* store k */
11428
#ifdef WOLFSSL_SMALL_STACK
11429
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11430
   if (kb == NULL) {
11431
      err = MEMORY_E; goto done;
11432
   }
11433
#endif
11434
11435
   XMEMSET(kb, 0, KB_SIZE);
11436
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
11437
   #ifdef WOLFSSL_CHECK_MEM_ZERO
11438
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
11439
   #endif
11440
      /* let's reverse kb so it's little endian */
11441
      x = 0;
11442
      y = mp_unsigned_bin_size(tk);
11443
      if (y > 0) {
11444
          y -= 1;
11445
      }
11446
11447
      while ((unsigned)x < y) {
11448
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
11449
         ++x; --y;
11450
      }
11451
11452
      /* at this point we can start, yipee */
11453
      first = 1;
11454
      for (x = lut_gap-1; x >= 0; x--) {
11455
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
11456
             by x bits from the start */
11457
          bitpos = x;
11458
          for (y = z = 0; y < FP_LUT; y++) {
11459
             z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
11460
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
11461
                                    the mult in each loop */
11462
          }
11463
11464
          /* double if not first */
11465
          if (!first) {
11466
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
11467
                                                              mp)) != MP_OKAY) {
11468
                break;
11469
             }
11470
          }
11471
11472
          /* add if not first, otherwise copy */
11473
          if (!first && z) {
11474
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
11475
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
11476
                break;
11477
             }
11478
          } else if (z) {
11479
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
11480
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
11481
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
11482
                 err = GEN_MEM_ERR;
11483
                 break;
11484
             }
11485
             first = 0;
11486
          }
11487
      }
11488
   }
11489
11490
   if (err == MP_OKAY) {
11491
      (void) z; /* Acknowledge the unused assignment */
11492
      ForceZero(kb, KB_SIZE);
11493
11494
      /* map R back from projective space */
11495
      if (map) {
11496
         err = ecc_map(R, modulus, mp);
11497
      } else {
11498
         err = MP_OKAY;
11499
      }
11500
   }
11501
11502
done:
11503
   /* cleanup */
11504
   mp_clear(order);
11505
   mp_forcezero(tk);
11506
11507
#ifdef WOLFSSL_SMALL_STACK
11508
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11509
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11510
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11511
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
11512
   wc_MemZero_Check(kb, KB_SIZE);
11513
   mp_memzero_check(tk);
11514
#endif
11515
11516
#undef KB_SIZE
11517
11518
   return err;
11519
}
11520
#endif
11521
11522
#ifdef ECC_SHAMIR
11523
#if !defined(WOLFSSL_SP_MATH)
11524
/* perform a fixed point ECC mulmod */
11525
static int accel_fp_mul2add(int idx1, int idx2,
11526
                            mp_int* kA, mp_int* kB,
11527
                            ecc_point *R, mp_int* a,
11528
                            mp_int* modulus, mp_digit mp)
11529
{
11530
#define KB_SIZE 128
11531
11532
#ifdef WOLFSSL_SMALL_STACK
11533
   unsigned char* kb[2] = {NULL, NULL};
11534
   mp_int*        tka = NULL;
11535
   mp_int*        tkb = NULL;
11536
   mp_int*        order = NULL;
11537
#else
11538
   unsigned char kb[2][KB_SIZE];
11539
   mp_int        tka[1];
11540
   mp_int        tkb[1];
11541
   mp_int        order[1];
11542
#endif
11543
   int      x, err;
11544
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
11545
   int first;
11546
11547
#ifdef WOLFSSL_SMALL_STACK
11548
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11549
   if (tka == NULL) {
11550
      err = MEMORY_E; goto done;
11551
   }
11552
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11553
   if (tkb == NULL) {
11554
      err = MEMORY_E; goto done;
11555
   }
11556
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11557
   if (order == NULL) {
11558
      err = MEMORY_E; goto done;
11559
   }
11560
#endif
11561
11562
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
11563
      err = MP_INIT_E; goto done;
11564
   }
11565
11566
   /* if it's smaller than modulus we fine */
11567
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
11568
      /* find order */
11569
      y = mp_unsigned_bin_size(modulus);
11570
      for (x = 0; ecc_sets[x].size; x++) {
11571
         if (y <= (unsigned)ecc_sets[x].size) break;
11572
      }
11573
11574
      /* back off if we are on the 521 bit curve */
11575
      if (y == 66) --x;
11576
11577
      if ((err = mp_read_radix(order, ecc_sets[x].order,
11578
                                                MP_RADIX_HEX)) != MP_OKAY) {
11579
         goto done;
11580
      }
11581
11582
      /* kA must be less than modulus */
11583
      if (mp_cmp(kA, order) != MP_LT) {
11584
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
11585
            goto done;
11586
         }
11587
      } else {
11588
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
11589
            goto done;
11590
         }
11591
      }
11592
   } else {
11593
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
11594
         goto done;
11595
      }
11596
   }
11597
#ifdef WOLFSSL_CHECK_MEM_ZERO
11598
   mp_memzero_add("accel_fp_mul2add tka", tka);
11599
#endif
11600
11601
   /* if it's smaller than modulus we fine */
11602
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
11603
      /* find order */
11604
      y = mp_unsigned_bin_size(modulus);
11605
      for (x = 0; ecc_sets[x].size; x++) {
11606
         if (y <= (unsigned)ecc_sets[x].size) break;
11607
      }
11608
11609
      /* back off if we are on the 521 bit curve */
11610
      if (y == 66) --x;
11611
11612
      if ((err = mp_read_radix(order, ecc_sets[x].order,
11613
                                                MP_RADIX_HEX)) != MP_OKAY) {
11614
         goto done;
11615
      }
11616
11617
      /* kB must be less than modulus */
11618
      if (mp_cmp(kB, order) != MP_LT) {
11619
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
11620
            goto done;
11621
         }
11622
      } else {
11623
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
11624
            goto done;
11625
         }
11626
      }
11627
   } else {
11628
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
11629
         goto done;
11630
      }
11631
   }
11632
#ifdef WOLFSSL_CHECK_MEM_ZERO
11633
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
11634
#endif
11635
11636
   /* get bitlen and round up to next multiple of FP_LUT */
11637
   bitlen  = mp_unsigned_bin_size(modulus) << 3;
11638
   x       = bitlen % FP_LUT;
11639
   if (x) {
11640
      bitlen += FP_LUT - x;
11641
   }
11642
   lut_gap = bitlen / FP_LUT;
11643
11644
   /* get the k value */
11645
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
11646
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
11647
      err = BUFFER_E; goto done;
11648
   }
11649
11650
   /* store k */
11651
#ifdef WOLFSSL_SMALL_STACK
11652
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11653
   if (kb[0] == NULL) {
11654
      err = MEMORY_E; goto done;
11655
   }
11656
#endif
11657
11658
   XMEMSET(kb[0], 0, KB_SIZE);
11659
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
11660
      goto done;
11661
   }
11662
#ifdef WOLFSSL_CHECK_MEM_ZERO
11663
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
11664
#endif
11665
11666
   /* let's reverse kb so it's little endian */
11667
   x = 0;
11668
   y = mp_unsigned_bin_size(tka);
11669
   if (y > 0) {
11670
       y -= 1;
11671
   }
11672
   mp_clear(tka);
11673
   while ((unsigned)x < y) {
11674
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
11675
      ++x; --y;
11676
   }
11677
11678
   /* store b */
11679
#ifdef WOLFSSL_SMALL_STACK
11680
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11681
   if (kb[1] == NULL) {
11682
      err = MEMORY_E; goto done;
11683
   }
11684
#endif
11685
11686
   XMEMSET(kb[1], 0, KB_SIZE);
11687
#ifdef WOLFSSL_CHECK_MEM_ZERO
11688
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
11689
#endif
11690
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
11691
      x = 0;
11692
      y = mp_unsigned_bin_size(tkb);
11693
      if (y > 0) {
11694
          y -= 1;
11695
      }
11696
11697
      while ((unsigned)x < y) {
11698
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
11699
         ++x; --y;
11700
      }
11701
11702
      /* at this point we can start, yipee */
11703
      first = 1;
11704
      for (x = lut_gap-1; x >= 0; x--) {
11705
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
11706
             offset by x bits from the start */
11707
          bitpos = x;
11708
          for (y = zA = zB = 0; y < FP_LUT; y++) {
11709
             zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
11710
             zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
11711
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
11712
                                      the mult in each loop */
11713
          }
11714
11715
          /* double if not first */
11716
          if (!first) {
11717
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
11718
                                                              mp)) != MP_OKAY) {
11719
                break;
11720
             }
11721
11722
             /* add if not first, otherwise copy */
11723
             if (zA) {
11724
                if ((err = ecc_projective_add_point_safe(R,
11725
                                             fp_cache[idx1].LUT[zA], R, a,
11726
                                             modulus, mp, &first)) != MP_OKAY) {
11727
                   break;
11728
                }
11729
             }
11730
11731
             if (zB) {
11732
                if ((err = ecc_projective_add_point_safe(R,
11733
                                             fp_cache[idx2].LUT[zB], R, a,
11734
                                             modulus, mp, &first)) != MP_OKAY) {
11735
                   break;
11736
                }
11737
             }
11738
          } else {
11739
             if (zA) {
11740
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
11741
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
11742
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
11743
                     err = GEN_MEM_ERR;
11744
                     break;
11745
                 }
11746
                    first = 0;
11747
             }
11748
             if (zB && first == 0) {
11749
                if ((err = ecc_projective_add_point_safe(R,
11750
                                        fp_cache[idx2].LUT[zB], R, a,
11751
                                        modulus, mp, &first)) != MP_OKAY){
11752
                   break;
11753
                }
11754
             } else if (zB && first == 1) {
11755
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
11756
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
11757
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
11758
                     err = GEN_MEM_ERR;
11759
                     break;
11760
                 }
11761
                    first = 0;
11762
             }
11763
          }
11764
      }
11765
   }
11766
11767
done:
11768
   /* cleanup */
11769
   mp_forcezero(tkb);
11770
   mp_forcezero(tka);
11771
   mp_clear(order);
11772
11773
#ifdef WOLFSSL_SMALL_STACK
11774
   if (kb[0])
11775
#endif
11776
      ForceZero(kb[0], KB_SIZE);
11777
#ifdef WOLFSSL_SMALL_STACK
11778
   if (kb[1])
11779
#endif
11780
      ForceZero(kb[1], KB_SIZE);
11781
11782
#ifdef WOLFSSL_SMALL_STACK
11783
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
11784
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
11785
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11786
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11787
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11788
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
11789
   wc_MemZero_Check(kb[1], KB_SIZE);
11790
   wc_MemZero_Check(kb[0], KB_SIZE);
11791
   mp_memzero_check(tkb);
11792
   mp_memzero_check(tka);
11793
#endif
11794
11795
#undef KB_SIZE
11796
11797
    if (err != MP_OKAY)
11798
        return err;
11799
11800
   return ecc_map(R, modulus, mp);
11801
}
11802
11803
11804
/** ECC Fixed Point mulmod global with heap hint used
11805
  Computes kA*A + kB*B = C using Shamir's Trick
11806
  A        First point to multiply
11807
  kA       What to multiple A by
11808
  B        Second point to multiply
11809
  kB       What to multiple B by
11810
  C        [out] Destination point (can overlap with A or B)
11811
  a        ECC curve parameter a
11812
  modulus  Modulus for curve
11813
  return MP_OKAY on success
11814
*/
11815
int ecc_mul2add(ecc_point* A, mp_int* kA,
11816
                ecc_point* B, mp_int* kB,
11817
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
11818
{
11819
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
11820
   mp_digit mp;
11821
#ifdef WOLFSSL_SMALL_STACK
11822
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11823
11824
   if (mu == NULL)
11825
       return MP_MEM;
11826
#else
11827
   mp_int   mu[1];
11828
#endif
11829
11830
   err = mp_init(mu);
11831
   if (err != MP_OKAY) {
11832
#ifdef WOLFSSL_SMALL_STACK
11833
       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11834
#endif
11835
       return err;
11836
   }
11837
11838
#ifndef HAVE_THREAD_LS
11839
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
11840
        wc_InitMutex(&ecc_fp_lock);
11841
        initMutex = 1;
11842
   }
11843
11844
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
11845
#ifdef WOLFSSL_SMALL_STACK
11846
       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11847
#endif
11848
      return BAD_MUTEX_E;
11849
   }
11850
#endif /* HAVE_THREAD_LS */
11851
11852
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
11853
11854
      /* find point */
11855
      idx1 = find_base(A);
11856
11857
      /* no entry? */
11858
      if (idx1 == -1) {
11859
         /* find hole and add it */
11860
         if ((idx1 = find_hole()) >= 0) {
11861
            err = add_entry(idx1, A);
11862
         }
11863
      }
11864
      if (err == MP_OKAY && idx1 != -1) {
11865
         /* increment LRU */
11866
         ++(fp_cache[idx1].lru_count);
11867
      }
11868
11869
      if (err == MP_OKAY) {
11870
        /* find point */
11871
        idx2 = find_base(B);
11872
11873
        /* no entry? */
11874
        if (idx2 == -1) {
11875
           /* find hole and add it */
11876
           if ((idx2 = find_hole()) >= 0)
11877
              err = add_entry(idx2, B);
11878
         }
11879
      }
11880
11881
      if (err == MP_OKAY && idx2 != -1) {
11882
         /* increment LRU */
11883
         ++(fp_cache[idx2].lru_count);
11884
      }
11885
11886
      if (err == MP_OKAY) {
11887
        /* if it's >= 2 AND the LUT is not set build the LUT */
11888
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
11889
           /* compute mp */
11890
           err = mp_montgomery_setup(modulus, &mp);
11891
11892
           if (err == MP_OKAY) {
11893
             mpInit = 1;
11894
             err = mp_montgomery_calc_normalization(mu, modulus);
11895
           }
11896
11897
           if (err == MP_OKAY)
11898
             /* build the LUT */
11899
             err = build_lut(idx1, a, modulus, mp, mu);
11900
        }
11901
      }
11902
11903
      if (err == MP_OKAY) {
11904
        /* if it's >= 2 AND the LUT is not set build the LUT */
11905
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
11906
           if (mpInit == 0) {
11907
                /* compute mp */
11908
                err = mp_montgomery_setup(modulus, &mp);
11909
                if (err == MP_OKAY) {
11910
                    mpInit = 1;
11911
                    err = mp_montgomery_calc_normalization(mu, modulus);
11912
                }
11913
            }
11914
11915
            if (err == MP_OKAY)
11916
              /* build the LUT */
11917
              err = build_lut(idx2, a, modulus, mp, mu);
11918
        }
11919
      }
11920
11921
11922
      if (err == MP_OKAY) {
11923
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
11924
                                     fp_cache[idx2].LUT_set) {
11925
           if (mpInit == 0) {
11926
              /* compute mp */
11927
              err = mp_montgomery_setup(modulus, &mp);
11928
           }
11929
           if (err == MP_OKAY)
11930
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
11931
        } else {
11932
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
11933
        }
11934
      }
11935
11936
      RESTORE_VECTOR_REGISTERS();
11937
11938
#ifndef HAVE_THREAD_LS
11939
    wc_UnLockMutex(&ecc_fp_lock);
11940
#endif /* HAVE_THREAD_LS */
11941
    mp_clear(mu);
11942
#ifdef WOLFSSL_SMALL_STACK
11943
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11944
#endif
11945
11946
    return err;
11947
}
11948
#endif
11949
#endif /* ECC_SHAMIR */
11950
11951
/** ECC Fixed Point mulmod global
11952
    k        The multiplicand
11953
    G        Base point to multiply
11954
    R        [out] Destination of product
11955
    a        ECC curve parameter a
11956
    modulus  The modulus for the curve
11957
    map      [boolean] If non-zero maps the point back to affine coordinates,
11958
             otherwise it's left in jacobian-montgomery form
11959
    return MP_OKAY if successful
11960
*/
11961
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
11962
    mp_int* modulus, int map, void* heap)
11963
{
11964
#if !defined(WOLFSSL_SP_MATH)
11965
   int   idx, err = MP_OKAY;
11966
   mp_digit mp;
11967
#ifdef WOLFSSL_SMALL_STACK
11968
   mp_int   *mu = NULL;
11969
#else
11970
   mp_int   mu[1];
11971
#endif
11972
   int      mpSetup = 0;
11973
#ifndef HAVE_THREAD_LS
11974
   int got_ecc_fp_lock = 0;
11975
#endif
11976
11977
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
11978
       return ECC_BAD_ARG_E;
11979
   }
11980
11981
   /* k can't have more bits than modulus count plus 1 */
11982
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
11983
      return ECC_OUT_OF_RANGE_E;
11984
   }
11985
11986
#ifdef WOLFSSL_SMALL_STACK
11987
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
11988
       return MP_MEM;
11989
#endif
11990
11991
   if (mp_init(mu) != MP_OKAY) {
11992
       err = MP_INIT_E;
11993
       goto out;
11994
   }
11995
11996
#ifndef HAVE_THREAD_LS
11997
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
11998
        wc_InitMutex(&ecc_fp_lock);
11999
        initMutex = 1;
12000
   }
12001
12002
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
12003
      err = BAD_MUTEX_E;
12004
      goto out;
12005
   }
12006
   got_ecc_fp_lock = 1;
12007
#endif /* HAVE_THREAD_LS */
12008
12009
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
12010
12011
      /* find point */
12012
      idx = find_base(G);
12013
12014
      /* no entry? */
12015
      if (idx == -1) {
12016
         /* find hole and add it */
12017
         idx = find_hole();
12018
12019
         if (idx >= 0)
12020
            err = add_entry(idx, G);
12021
      }
12022
      if (err == MP_OKAY && idx >= 0) {
12023
         /* increment LRU */
12024
         ++(fp_cache[idx].lru_count);
12025
      }
12026
12027
12028
      if (err == MP_OKAY) {
12029
        /* if it's 2 build the LUT, if it's higher just use the LUT */
12030
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
12031
           /* compute mp */
12032
           err = mp_montgomery_setup(modulus, &mp);
12033
12034
           if (err == MP_OKAY) {
12035
             /* compute mu */
12036
             mpSetup = 1;
12037
             err = mp_montgomery_calc_normalization(mu, modulus);
12038
           }
12039
12040
           if (err == MP_OKAY)
12041
             /* build the LUT */
12042
             err = build_lut(idx, a, modulus, mp, mu);
12043
        }
12044
      }
12045
12046
      if (err == MP_OKAY) {
12047
        if (idx >= 0 && fp_cache[idx].LUT_set) {
12048
           if (mpSetup == 0) {
12049
              /* compute mp */
12050
              err = mp_montgomery_setup(modulus, &mp);
12051
           }
12052
           if (err == MP_OKAY)
12053
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
12054
        } else {
12055
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
12056
        }
12057
      }
12058
12059
      RESTORE_VECTOR_REGISTERS();
12060
12061
  out:
12062
12063
#ifndef HAVE_THREAD_LS
12064
    if (got_ecc_fp_lock)
12065
        wc_UnLockMutex(&ecc_fp_lock);
12066
#endif /* HAVE_THREAD_LS */
12067
    mp_clear(mu);
12068
#ifdef WOLFSSL_SMALL_STACK
12069
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12070
#endif
12071
12072
    return err;
12073
12074
#else /* WOLFSSL_SP_MATH */
12075
12076
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
12077
        return ECC_BAD_ARG_E;
12078
    }
12079
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
12080
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
12081
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
12082
        return IS_POINT_E;
12083
    }
12084
12085
#ifndef WOLFSSL_SP_NO_256
12086
    if (mp_count_bits(modulus) == 256) {
12087
        int ret;
12088
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12089
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
12090
        RESTORE_VECTOR_REGISTERS();
12091
        return ret;
12092
    }
12093
#endif
12094
#ifdef WOLFSSL_SP_384
12095
    if (mp_count_bits(modulus) == 384) {
12096
        int ret;
12097
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12098
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
12099
        RESTORE_VECTOR_REGISTERS();
12100
        return ret;
12101
    }
12102
#endif
12103
#ifdef WOLFSSL_SP_521
12104
    if (mp_count_bits(modulus) == 521) {
12105
        int ret;
12106
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12107
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
12108
        RESTORE_VECTOR_REGISTERS();
12109
        return ret;
12110
    }
12111
#endif
12112
    return WC_KEY_SIZE_E;
12113
#endif /* WOLFSSL_SP_MATH */
12114
}
12115
12116
/** ECC Fixed Point mulmod global
12117
    k        The multiplicand
12118
    G        Base point to multiply
12119
    R        [out] Destination of product
12120
    a        ECC curve parameter a
12121
    modulus  The modulus for the curve
12122
    map      [boolean] If non-zero maps the point back to affine coordinates,
12123
             otherwise it's left in jacobian-montgomery form
12124
    return MP_OKAY if successful
12125
*/
12126
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
12127
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
12128
{
12129
#if !defined(WOLFSSL_SP_MATH)
12130
   int   idx, err = MP_OKAY;
12131
   mp_digit mp;
12132
#ifdef WOLFSSL_SMALL_STACK
12133
   mp_int   *mu = NULL;
12134
#else
12135
   mp_int   mu[1];
12136
#endif
12137
   int      mpSetup = 0;
12138
#ifndef HAVE_THREAD_LS
12139
   int got_ecc_fp_lock = 0;
12140
#endif
12141
12142
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
12143
                                                                order == NULL) {
12144
       return ECC_BAD_ARG_E;
12145
   }
12146
12147
   /* k can't have more bits than order */
12148
   if (mp_count_bits(k) > mp_count_bits(order)) {
12149
      return ECC_OUT_OF_RANGE_E;
12150
   }
12151
12152
#ifdef WOLFSSL_SMALL_STACK
12153
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12154
       return MP_MEM;
12155
#endif
12156
12157
   if (mp_init(mu) != MP_OKAY) {
12158
       err = MP_INIT_E;
12159
       goto out;
12160
   }
12161
12162
#ifndef HAVE_THREAD_LS
12163
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
12164
        wc_InitMutex(&ecc_fp_lock);
12165
        initMutex = 1;
12166
   }
12167
12168
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
12169
      err = BAD_MUTEX_E;
12170
      goto out;
12171
   }
12172
   got_ecc_fp_lock = 1;
12173
#endif /* HAVE_THREAD_LS */
12174
12175
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
12176
12177
      /* find point */
12178
      idx = find_base(G);
12179
12180
      /* no entry? */
12181
      if (idx == -1) {
12182
         /* find hole and add it */
12183
         idx = find_hole();
12184
12185
         if (idx >= 0)
12186
            err = add_entry(idx, G);
12187
      }
12188
      if (err == MP_OKAY && idx >= 0) {
12189
         /* increment LRU */
12190
         ++(fp_cache[idx].lru_count);
12191
      }
12192
12193
12194
      if (err == MP_OKAY) {
12195
        /* if it's 2 build the LUT, if it's higher just use the LUT */
12196
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
12197
           /* compute mp */
12198
           err = mp_montgomery_setup(modulus, &mp);
12199
12200
           if (err == MP_OKAY) {
12201
             /* compute mu */
12202
             mpSetup = 1;
12203
             err = mp_montgomery_calc_normalization(mu, modulus);
12204
           }
12205
12206
           if (err == MP_OKAY)
12207
             /* build the LUT */
12208
             err = build_lut(idx, a, modulus, mp, mu);
12209
        }
12210
      }
12211
12212
      if (err == MP_OKAY) {
12213
        if (idx >= 0 && fp_cache[idx].LUT_set) {
12214
           if (mpSetup == 0) {
12215
              /* compute mp */
12216
              err = mp_montgomery_setup(modulus, &mp);
12217
           }
12218
           if (err == MP_OKAY)
12219
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
12220
        } else {
12221
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
12222
        }
12223
      }
12224
12225
      RESTORE_VECTOR_REGISTERS();
12226
12227
  out:
12228
12229
#ifndef HAVE_THREAD_LS
12230
    if (got_ecc_fp_lock)
12231
        wc_UnLockMutex(&ecc_fp_lock);
12232
#endif /* HAVE_THREAD_LS */
12233
    mp_clear(mu);
12234
#ifdef WOLFSSL_SMALL_STACK
12235
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12236
#endif
12237
12238
    return err;
12239
12240
#else /* WOLFSSL_SP_MATH */
12241
12242
    (void)rng;
12243
12244
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
12245
                                                                order == NULL) {
12246
        return ECC_BAD_ARG_E;
12247
    }
12248
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
12249
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
12250
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
12251
        return IS_POINT_E;
12252
    }
12253
12254
#ifndef WOLFSSL_SP_NO_256
12255
    if (mp_count_bits(modulus) == 256) {
12256
        int ret;
12257
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12258
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
12259
        RESTORE_VECTOR_REGISTERS();
12260
        return ret;
12261
    }
12262
#endif
12263
#ifdef WOLFSSL_SP_384
12264
    if (mp_count_bits(modulus) == 384) {
12265
        int ret;
12266
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12267
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
12268
        RESTORE_VECTOR_REGISTERS();
12269
        return ret;
12270
    }
12271
#endif
12272
#ifdef WOLFSSL_SP_521
12273
    if (mp_count_bits(modulus) == 521) {
12274
        int ret;
12275
        SAVE_VECTOR_REGISTERS(return _svr_ret);
12276
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
12277
        RESTORE_VECTOR_REGISTERS();
12278
        return ret;
12279
    }
12280
#endif
12281
    return WC_KEY_SIZE_E;
12282
#endif /* WOLFSSL_SP_MATH */
12283
}
12284
12285
#if !defined(WOLFSSL_SP_MATH)
12286
/* helper function for freeing the cache ...
12287
   must be called with the cache mutex locked */
12288
static void wc_ecc_fp_free_cache(void)
12289
{
12290
   unsigned x, y;
12291
   for (x = 0; x < FP_ENTRIES; x++) {
12292
      if (fp_cache[x].g != NULL) {
12293
         for (y = 0; y < (1U<<FP_LUT); y++) {
12294
            wc_ecc_del_point(fp_cache[x].LUT[y]);
12295
            fp_cache[x].LUT[y] = NULL;
12296
         }
12297
         wc_ecc_del_point(fp_cache[x].g);
12298
         fp_cache[x].g         = NULL;
12299
         mp_clear(&fp_cache[x].mu);
12300
         fp_cache[x].LUT_set   = 0;
12301
         fp_cache[x].lru_count = 0;
12302
         fp_cache[x].lock = 0;
12303
      }
12304
   }
12305
}
12306
#endif
12307
12308
12309
/** Init the Fixed Point cache */
12310
void wc_ecc_fp_init(void)
12311
{
12312
#ifndef WOLFSSL_SP_MATH
12313
#ifndef HAVE_THREAD_LS
12314
   if (initMutex == 0) {
12315
        wc_InitMutex(&ecc_fp_lock);
12316
        initMutex = 1;
12317
   }
12318
#endif
12319
#endif
12320
}
12321
12322
12323
/** Free the Fixed Point cache */
12324
WOLFSSL_ABI
12325
void wc_ecc_fp_free(void)
12326
{
12327
#if !defined(WOLFSSL_SP_MATH)
12328
#ifndef HAVE_THREAD_LS
12329
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
12330
        wc_InitMutex(&ecc_fp_lock);
12331
        initMutex = 1;
12332
   }
12333
12334
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
12335
#endif /* HAVE_THREAD_LS */
12336
12337
       wc_ecc_fp_free_cache();
12338
12339
#ifndef HAVE_THREAD_LS
12340
       wc_UnLockMutex(&ecc_fp_lock);
12341
       wc_FreeMutex(&ecc_fp_lock);
12342
       initMutex = 0;
12343
   }
12344
#endif /* HAVE_THREAD_LS */
12345
#endif
12346
}
12347
12348
12349
#endif /* FP_ECC */
12350
12351
#ifdef ECC_TIMING_RESISTANT
12352
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
12353
0
{
12354
0
    int err = 0;
12355
12356
0
    if (key == NULL) {
12357
0
        err = BAD_FUNC_ARG;
12358
0
    }
12359
0
    else {
12360
0
        key->rng = rng;
12361
0
    }
12362
12363
0
    return err;
12364
0
}
12365
#endif
12366
12367
#ifdef HAVE_ECC_ENCRYPT
12368
12369
12370
enum ecCliState {
12371
    ecCLI_INIT      = 1,
12372
    ecCLI_SALT_GET  = 2,
12373
    ecCLI_SALT_SET  = 3,
12374
    ecCLI_SENT_REQ  = 4,
12375
    ecCLI_RECV_RESP = 5,
12376
    ecCLI_BAD_STATE = 99
12377
};
12378
12379
enum ecSrvState {
12380
    ecSRV_INIT      = 1,
12381
    ecSRV_SALT_GET  = 2,
12382
    ecSRV_SALT_SET  = 3,
12383
    ecSRV_RECV_REQ  = 4,
12384
    ecSRV_SENT_RESP = 5,
12385
    ecSRV_BAD_STATE = 99
12386
};
12387
12388
12389
struct ecEncCtx {
12390
    const byte* kdfSalt;   /* optional salt for kdf */
12391
    const byte* kdfInfo;   /* optional info for kdf */
12392
    const byte* macSalt;   /* optional salt for mac */
12393
    word32    kdfSaltSz;   /* size of kdfSalt */
12394
    word32    kdfInfoSz;   /* size of kdfInfo */
12395
    word32    macSaltSz;   /* size of macSalt */
12396
    void*     heap;        /* heap hint for memory used */
12397
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
12398
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
12399
    byte      encAlgo;     /* which encryption type */
12400
    byte      kdfAlgo;     /* which key derivation function type */
12401
    byte      macAlgo;     /* which mac function type */
12402
    byte      protocol;    /* are we REQ_RESP client or server ? */
12403
    byte      cliSt;       /* protocol state, for sanity checks */
12404
    byte      srvSt;       /* protocol state, for sanity checks */
12405
    WC_RNG*   rng;
12406
};
12407
12408
/* optional set info, can be called before or after set_peer_salt */
12409
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
12410
0
{
12411
0
    if (ctx == NULL)
12412
0
        return BAD_FUNC_ARG;
12413
12414
0
    ctx->encAlgo = encAlgo;
12415
0
    ctx->kdfAlgo = kdfAlgo;
12416
0
    ctx->macAlgo = macAlgo;
12417
12418
0
    return 0;
12419
0
}
12420
12421
12422
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
12423
0
{
12424
0
    if (ctx == NULL || ctx->protocol == 0)
12425
0
        return NULL;
12426
12427
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
12428
0
        if (ctx->cliSt == ecCLI_INIT) {
12429
0
            ctx->cliSt =  ecCLI_SALT_GET;
12430
0
            return ctx->clientSalt;
12431
0
        }
12432
0
        else {
12433
0
            ctx->cliSt = ecCLI_BAD_STATE;
12434
0
            return NULL;
12435
0
        }
12436
0
    }
12437
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
12438
0
        if (ctx->srvSt == ecSRV_INIT) {
12439
0
            ctx->srvSt =  ecSRV_SALT_GET;
12440
0
            return ctx->serverSalt;
12441
0
        }
12442
0
        else {
12443
0
            ctx->srvSt = ecSRV_BAD_STATE;
12444
0
            return NULL;
12445
0
        }
12446
0
    }
12447
12448
0
    return NULL;
12449
0
}
12450
12451
12452
/* optional set info, can be called before or after set_peer_salt */
12453
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
12454
0
{
12455
0
    if (ctx == NULL || info == 0 || sz < 0)
12456
0
        return BAD_FUNC_ARG;
12457
12458
0
    ctx->kdfInfo   = info;
12459
0
    ctx->kdfInfoSz = sz;
12460
12461
0
    return 0;
12462
0
}
12463
12464
12465
static const char* exchange_info = "Secure Message Exchange";
12466
12467
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
12468
0
{
12469
0
    byte tmp[EXCHANGE_SALT_SZ/2];
12470
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
12471
12472
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
12473
0
        return BAD_FUNC_ARG;
12474
12475
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
12476
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
12477
0
        if (ctx->cliSt == ecCLI_SALT_GET)
12478
0
            ctx->cliSt =  ecCLI_SALT_SET;
12479
0
        else {
12480
0
            ctx->cliSt =  ecCLI_BAD_STATE;
12481
0
            return BAD_STATE_E;
12482
0
        }
12483
0
    }
12484
0
    else {
12485
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
12486
0
        if (ctx->srvSt == ecSRV_SALT_GET)
12487
0
            ctx->srvSt =  ecSRV_SALT_SET;
12488
0
        else {
12489
0
            ctx->srvSt =  ecSRV_BAD_STATE;
12490
0
            return BAD_STATE_E;
12491
0
        }
12492
0
    }
12493
12494
    /* mix half and half */
12495
    /* tmp stores 2nd half of client before overwrite */
12496
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
12497
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
12498
0
    XMEMCPY(ctx->serverSalt, tmp, halfSz);
12499
12500
0
    ctx->kdfSalt   = ctx->clientSalt;
12501
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
12502
12503
0
    ctx->macSalt   = ctx->serverSalt;
12504
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
12505
12506
0
    if (ctx->kdfInfo == NULL) {
12507
        /* default info */
12508
0
        ctx->kdfInfo   = (const byte*)exchange_info;
12509
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
12510
0
    }
12511
12512
0
    return 0;
12513
0
}
12514
12515
/* Set the salt pointer into context.
12516
 *
12517
 * @param  [in, out]  ctx   ECIES context object.
12518
 * @param  [in]       salt  Salt to use with KDF.
12519
 * @param  [in]       len   Length of salt in bytes.
12520
 * @return  0 on success.
12521
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
12522
 */
12523
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 len)
12524
0
{
12525
0
    if (ctx == NULL || (salt == NULL && len != 0))
12526
0
        return BAD_FUNC_ARG;
12527
12528
0
    ctx->kdfSalt   = salt;
12529
0
    ctx->kdfSaltSz = len;
12530
12531
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
12532
0
        ctx->srvSt = ecSRV_SALT_SET;
12533
0
    }
12534
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
12535
0
        ctx->srvSt = ecSRV_SALT_SET;
12536
0
    }
12537
12538
0
    return 0;
12539
0
}
12540
12541
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
12542
0
{
12543
0
    byte* saltBuffer = NULL;
12544
12545
0
    if (ctx == NULL || flags == 0)
12546
0
        return BAD_FUNC_ARG;
12547
12548
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
12549
12550
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
12551
0
}
12552
12553
12554
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
12555
0
{
12556
0
    if (ctx) {
12557
0
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
12558
12559
0
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12560
0
        #ifdef WOLFSSL_AES_128
12561
0
            ctx->encAlgo  = ecAES_128_CBC;
12562
        #else
12563
            ctx->encAlgo  = ecAES_256_CBC;
12564
        #endif
12565
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
12566
        #ifdef WOLFSSL_AES_256
12567
            ctx->encAlgo  = ecAES_256_CTR;
12568
        #else
12569
            ctx->encAlgo  = ecAES_128_CTR;
12570
        #endif
12571
    #else
12572
        #error "No valid encryption algorithm for ECIES configured."
12573
    #endif
12574
0
        ctx->kdfAlgo  = ecHKDF_SHA256;
12575
0
        ctx->macAlgo  = ecHMAC_SHA256;
12576
0
        ctx->protocol = (byte)flags;
12577
0
        ctx->rng      = rng;
12578
12579
0
        if (flags == REQ_RESP_CLIENT)
12580
0
            ctx->cliSt = ecCLI_INIT;
12581
0
        if (flags == REQ_RESP_SERVER)
12582
0
            ctx->srvSt = ecSRV_INIT;
12583
0
    }
12584
0
}
12585
12586
12587
/* allow ecc context reset so user doesn't have to init/free for reuse */
12588
WOLFSSL_ABI
12589
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
12590
0
{
12591
0
    if (ctx == NULL || rng == NULL)
12592
0
        return BAD_FUNC_ARG;
12593
12594
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
12595
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
12596
0
}
12597
12598
12599
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
12600
0
{
12601
0
    int       ret = 0;
12602
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
12603
0
                                                              DYNAMIC_TYPE_ECC);
12604
12605
0
    if (ctx) {
12606
0
        ctx->protocol = (byte)flags;
12607
0
        ctx->heap     = heap;
12608
0
    }
12609
12610
0
    ret = wc_ecc_ctx_reset(ctx, rng);
12611
0
    if (ret != 0) {
12612
0
        wc_ecc_ctx_free(ctx);
12613
0
        ctx = NULL;
12614
0
    }
12615
12616
0
    return ctx;
12617
0
}
12618
12619
12620
/* alloc/init and set defaults, return new Context  */
12621
WOLFSSL_ABI
12622
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
12623
0
{
12624
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
12625
0
}
12626
12627
12628
/* free any resources, clear any keys */
12629
WOLFSSL_ABI
12630
void wc_ecc_ctx_free(ecEncCtx* ctx)
12631
0
{
12632
0
    if (ctx) {
12633
0
        void* heap = ctx->heap;
12634
0
        ForceZero(ctx, sizeof(ecEncCtx));
12635
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
12636
0
        (void)heap;
12637
0
    }
12638
0
}
12639
12640
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
12641
                             int* keysLen, word32* digestSz, word32* blockSz)
12642
0
{
12643
0
    if (ctx) {
12644
0
        switch (ctx->encAlgo) {
12645
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12646
0
            case ecAES_128_CBC:
12647
0
                *encKeySz = KEY_SIZE_128;
12648
0
                *ivSz     = IV_SIZE_128;
12649
0
                *blockSz  = AES_BLOCK_SIZE;
12650
0
                break;
12651
0
            case ecAES_256_CBC:
12652
0
                *encKeySz = KEY_SIZE_256;
12653
0
                *ivSz     = IV_SIZE_128;
12654
0
                *blockSz  = AES_BLOCK_SIZE;
12655
0
                break;
12656
0
        #endif
12657
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
12658
0
            case ecAES_128_CTR:
12659
0
                *encKeySz = KEY_SIZE_128;
12660
0
                *ivSz     = 12;
12661
0
                *blockSz  = 1;
12662
0
                break;
12663
0
            case ecAES_256_CTR:
12664
0
                *encKeySz = KEY_SIZE_256;
12665
0
                *ivSz     = 12;
12666
0
                *blockSz  = 1;
12667
0
                break;
12668
0
        #endif
12669
0
            default:
12670
0
                return BAD_FUNC_ARG;
12671
0
        }
12672
12673
0
        switch (ctx->macAlgo) {
12674
0
            case ecHMAC_SHA256:
12675
0
                *digestSz = WC_SHA256_DIGEST_SIZE;
12676
0
                break;
12677
0
            default:
12678
0
                return BAD_FUNC_ARG;
12679
0
        }
12680
0
    } else
12681
0
        return BAD_FUNC_ARG;
12682
12683
#ifdef WOLFSSL_ECIES_OLD
12684
    *keysLen  = *encKeySz + *ivSz + *digestSz;
12685
#else
12686
0
    *keysLen  = *encKeySz + *digestSz;
12687
0
#endif
12688
12689
0
    return 0;
12690
0
}
12691
12692
12693
/* ecc encrypt with shared secret run through kdf
12694
   ctx holds non default algos and inputs
12695
   msgSz should be the right size for encAlgo, i.e., already padded
12696
   return 0 on success */
12697
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
12698
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
12699
0
{
12700
0
    int          ret = 0;
12701
0
    word32       blockSz = 0;
12702
0
#ifndef WOLFSSL_ECIES_OLD
12703
0
#ifndef WOLFSSL_ECIES_GEN_IV
12704
0
    byte         iv[ECC_MAX_IV_SIZE];
12705
0
#endif
12706
0
    word32       pubKeySz = 0;
12707
0
#endif
12708
0
    word32       digestSz = 0;
12709
0
    ecEncCtx     localCtx;
12710
0
#ifdef WOLFSSL_SMALL_STACK
12711
0
    byte*        sharedSecret;
12712
0
    byte*        keys;
12713
#else
12714
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
12715
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
12716
#else
12717
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
12718
#endif
12719
    byte         keys[ECC_BUFSIZE];         /* max size */
12720
#endif
12721
0
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
12722
0
    word32       sharedSz = ECC_MAXSIZE;
12723
#else
12724
    /* 'Uncompressed' byte | public key x | public key y | secret */
12725
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
12726
#endif
12727
0
    int          keysLen = 0;
12728
0
    int          encKeySz = 0;
12729
0
    int          ivSz = 0;
12730
0
    int          offset = 0;         /* keys offset if doing msg exchange */
12731
0
    byte*        encKey = NULL;
12732
0
    byte*        encIv = NULL;
12733
0
    byte*        macKey = NULL;
12734
12735
0
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
12736
0
                           outSz  == NULL)
12737
0
        return BAD_FUNC_ARG;
12738
12739
0
    if (ctx == NULL) {  /* use defaults */
12740
0
        ecc_ctx_init(&localCtx, 0, NULL);
12741
0
        ctx = &localCtx;
12742
0
    }
12743
12744
0
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
12745
0
                            &blockSz);
12746
0
    if (ret != 0)
12747
0
        return ret;
12748
12749
0
#ifndef WOLFSSL_ECIES_OLD
12750
0
    if (!compressed) {
12751
0
        pubKeySz = 1 + wc_ecc_size(privKey) * 2;
12752
0
    }
12753
0
    else {
12754
0
        pubKeySz = 1 + wc_ecc_size(privKey);
12755
0
    }
12756
#else
12757
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
12758
#endif
12759
12760
0
    if (ctx->protocol == REQ_RESP_SERVER) {
12761
0
        offset = keysLen;
12762
0
        keysLen *= 2;
12763
12764
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
12765
0
            return BAD_STATE_E;
12766
12767
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
12768
0
    }
12769
0
    else if (ctx->protocol == REQ_RESP_CLIENT) {
12770
0
        if (ctx->cliSt != ecCLI_SALT_SET)
12771
0
            return BAD_STATE_E;
12772
12773
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
12774
0
    }
12775
12776
0
    if (keysLen > ECC_BUFSIZE) /* keys size */
12777
0
        return BUFFER_E;
12778
12779
0
    if ((msgSz % blockSz) != 0)
12780
0
        return BAD_PADDING_E;
12781
12782
#ifdef WOLFSSL_ECIES_OLD
12783
    if (*outSz < (msgSz + digestSz))
12784
        return BUFFER_E;
12785
#elif defined(WOLFSSL_ECIES_GEN_IV)
12786
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
12787
        return BUFFER_E;
12788
#else
12789
0
    if (*outSz < (pubKeySz + msgSz + digestSz))
12790
0
        return BUFFER_E;
12791
0
#endif
12792
12793
0
#ifdef ECC_TIMING_RESISTANT
12794
0
    if (ctx->rng != NULL && privKey->rng == NULL)
12795
0
        privKey->rng = ctx->rng;
12796
0
#endif
12797
12798
0
#ifndef WOLFSSL_ECIES_OLD
12799
0
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
12800
0
#ifdef ECC_TIMING_RESISTANT
12801
0
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
12802
#else
12803
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
12804
#endif
12805
0
        if (ret != 0)
12806
0
            return ret;
12807
0
    }
12808
0
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
12809
0
    if (ret != 0)
12810
0
        return ret;
12811
0
    out += pubKeySz;
12812
0
#endif
12813
12814
0
#ifdef WOLFSSL_SMALL_STACK
12815
0
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12816
0
    if (sharedSecret == NULL)
12817
0
        return MEMORY_E;
12818
12819
0
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12820
0
    if (keys == NULL) {
12821
0
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12822
0
        return MEMORY_E;
12823
0
    }
12824
0
#endif
12825
12826
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
12827
12828
#ifdef WOLFSSL_ECIES_ISO18033
12829
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
12830
    sharedSz -= pubKeySz;
12831
#endif
12832
12833
0
    do {
12834
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
12835
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
12836
        if (ret != 0)
12837
            break;
12838
    #endif
12839
0
    #ifndef WOLFSSL_ECIES_ISO18033
12840
0
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
12841
    #else
12842
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
12843
                                                                     &sharedSz);
12844
    #endif
12845
0
    } while (ret == WC_PENDING_E);
12846
0
    if (ret == 0) {
12847
    #ifdef WOLFSSL_ECIES_ISO18033
12848
        /* KDF data is encoded public key and secret. */
12849
        sharedSz += pubKeySz;
12850
    #endif
12851
0
        switch (ctx->kdfAlgo) {
12852
0
            case ecHKDF_SHA256 :
12853
0
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
12854
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
12855
0
                           keys, keysLen);
12856
0
                break;
12857
12858
0
            default:
12859
0
                ret = BAD_FUNC_ARG;
12860
0
                break;
12861
0
        }
12862
0
    }
12863
12864
0
    if (ret == 0) {
12865
    #ifdef WOLFSSL_ECIES_OLD
12866
        encKey = keys + offset;
12867
        encIv  = encKey + encKeySz;
12868
        macKey = encKey + encKeySz + ivSz;
12869
    #elif defined(WOLFSSL_ECIES_GEN_IV)
12870
        encKey = keys + offset;
12871
        encIv  = out;
12872
        out += ivSz;
12873
        macKey = encKey + encKeySz;
12874
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
12875
    #else
12876
0
        XMEMSET(iv, 0, ivSz);
12877
0
        encKey = keys + offset;
12878
0
        encIv  = iv;
12879
0
        macKey = encKey + encKeySz;
12880
0
    #endif
12881
0
    }
12882
12883
0
    if (ret == 0) {
12884
0
       switch (ctx->encAlgo) {
12885
0
            case ecAES_128_CBC:
12886
0
            case ecAES_256_CBC:
12887
0
            {
12888
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12889
0
            #ifdef WOLFSSL_SMALL_STACK
12890
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
12891
0
                                          DYNAMIC_TYPE_AES);
12892
0
                if (aes == NULL) {
12893
0
                    ret = MEMORY_E;
12894
0
                    break;
12895
0
                }
12896
            #else
12897
                Aes aes[1];
12898
            #endif
12899
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12900
0
                if (ret == 0) {
12901
0
                    ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
12902
0
                                                                AES_ENCRYPTION);
12903
0
                    if (ret == 0) {
12904
0
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
12905
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
12906
                                                    defined(WC_ASYNC_ENABLE_AES)
12907
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
12908
                                            WC_ASYNC_FLAG_NONE);
12909
                    #endif
12910
0
                    }
12911
0
                    wc_AesFree(aes);
12912
0
                }
12913
0
            #ifdef WOLFSSL_SMALL_STACK
12914
0
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
12915
0
            #endif
12916
        #else
12917
                ret = NOT_COMPILED_IN;
12918
        #endif
12919
0
                break;
12920
0
            }
12921
0
            case ecAES_128_CTR:
12922
0
            case ecAES_256_CTR:
12923
0
            {
12924
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
12925
0
                byte ctr_iv[AES_BLOCK_SIZE];
12926
            #ifndef WOLFSSL_SMALL_STACK
12927
                Aes aes[1];
12928
            #else
12929
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
12930
0
                                            DYNAMIC_TYPE_AES);
12931
0
                if (aes == NULL) {
12932
0
                    ret = MEMORY_E;
12933
0
                    break;
12934
0
                }
12935
0
            #endif
12936
12937
                /* Include 4 byte counter starting at all zeros. */
12938
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
12939
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
12940
0
                    AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
12941
12942
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12943
0
                if (ret == 0) {
12944
0
                    ret = wc_AesSetKey(aes, encKey, encKeySz, ctr_iv,
12945
0
                                                                AES_ENCRYPTION);
12946
0
                    if (ret == 0) {
12947
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
12948
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
12949
                                                    defined(WC_ASYNC_ENABLE_AES)
12950
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
12951
                                            WC_ASYNC_FLAG_NONE);
12952
                    #endif
12953
0
                    }
12954
0
                    wc_AesFree(aes);
12955
0
                }
12956
0
            #ifdef WOLFSSL_SMALL_STACK
12957
0
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
12958
0
            #endif
12959
        #else
12960
                ret = NOT_COMPILED_IN;
12961
        #endif
12962
0
                break;
12963
0
            }
12964
0
            default:
12965
0
                ret = BAD_FUNC_ARG;
12966
0
                break;
12967
0
        }
12968
0
    }
12969
12970
0
    if (ret == 0) {
12971
0
        switch (ctx->macAlgo) {
12972
0
            case ecHMAC_SHA256:
12973
0
            {
12974
0
            #ifdef WOLFSSL_SMALL_STACK
12975
0
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
12976
0
                                             DYNAMIC_TYPE_HMAC);
12977
0
                if (hmac == NULL) {
12978
0
                    ret = MEMORY_E;
12979
0
                    break;
12980
0
                }
12981
            #else
12982
                Hmac hmac[1];
12983
            #endif
12984
0
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
12985
0
                if (ret == 0) {
12986
0
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
12987
0
                                                         WC_SHA256_DIGEST_SIZE);
12988
0
                    if (ret == 0) {
12989
0
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
12990
0
                        ret = wc_HmacUpdate(hmac, out, msgSz);
12991
                    #else
12992
                        /* IV is before encrypted message. */
12993
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
12994
                    #endif
12995
0
                    }
12996
0
                    if (ret == 0)
12997
0
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
12998
0
                    if (ret == 0)
12999
0
                        ret = wc_HmacFinal(hmac, out+msgSz);
13000
0
                    wc_HmacFree(hmac);
13001
0
                }
13002
0
            #ifdef WOLFSSL_SMALL_STACK
13003
0
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
13004
0
            #endif
13005
0
                break;
13006
0
            }
13007
13008
0
            default:
13009
0
                ret = BAD_FUNC_ARG;
13010
0
                break;
13011
0
        }
13012
0
    }
13013
13014
0
    if (ret == 0) {
13015
#ifdef WOLFSSL_ECIES_OLD
13016
        *outSz = msgSz + digestSz;
13017
#elif defined(WOLFSSL_ECIES_GEN_IV)
13018
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
13019
#else
13020
0
        *outSz = pubKeySz + msgSz + digestSz;
13021
0
#endif
13022
0
    }
13023
13024
0
    RESTORE_VECTOR_REGISTERS();
13025
13026
0
#ifdef WOLFSSL_SMALL_STACK
13027
0
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13028
0
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13029
0
#endif
13030
13031
0
    return ret;
13032
0
}
13033
13034
/* ecc encrypt with shared secret run through kdf
13035
   ctx holds non default algos and inputs
13036
   msgSz should be the right size for encAlgo, i.e., already padded
13037
   return 0 on success */
13038
WOLFSSL_ABI
13039
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
13040
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
13041
0
{
13042
0
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
13043
0
}
13044
13045
/* ecc decrypt with shared secret run through kdf
13046
   ctx holds non default algos and inputs
13047
   return 0 on success */
13048
WOLFSSL_ABI
13049
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
13050
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
13051
0
{
13052
0
    int          ret = 0;
13053
0
    word32       blockSz = 0;
13054
0
#ifndef WOLFSSL_ECIES_OLD
13055
0
#ifndef WOLFSSL_ECIES_GEN_IV
13056
0
    byte         iv[ECC_MAX_IV_SIZE];
13057
0
#endif
13058
0
    word32       pubKeySz = 0;
13059
0
#ifdef WOLFSSL_SMALL_STACK
13060
0
    ecc_key*     peerKey = NULL;
13061
#else
13062
    ecc_key      peerKey[1];
13063
#endif
13064
0
#endif
13065
0
    word32       digestSz = 0;
13066
0
    ecEncCtx     localCtx;
13067
0
#ifdef WOLFSSL_SMALL_STACK
13068
0
    byte*        sharedSecret;
13069
0
    byte*        keys;
13070
#else
13071
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
13072
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
13073
#else
13074
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
13075
#endif
13076
    byte         keys[ECC_BUFSIZE];         /* max size */
13077
#endif
13078
0
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
13079
0
    word32       sharedSz = ECC_MAXSIZE;
13080
#else
13081
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
13082
#endif
13083
0
    int          keysLen = 0;
13084
0
    int          encKeySz = 0;
13085
0
    int          ivSz = 0;
13086
0
    int          offset = 0;       /* in case using msg exchange */
13087
0
    byte*        encKey = NULL;
13088
0
    const byte*  encIv = NULL;
13089
0
    byte*        macKey = NULL;
13090
13091
13092
0
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
13093
0
        return BAD_FUNC_ARG;
13094
#ifdef WOLFSSL_ECIES_OLD
13095
    if (pubKey == NULL)
13096
        return BAD_FUNC_ARG;
13097
#endif
13098
13099
0
    if (ctx == NULL) {  /* use defaults */
13100
0
        ecc_ctx_init(&localCtx, 0, NULL);
13101
0
        ctx = &localCtx;
13102
0
    }
13103
13104
0
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
13105
0
                            &blockSz);
13106
0
    if (ret != 0)
13107
0
        return ret;
13108
13109
0
#ifndef WOLFSSL_ECIES_OLD
13110
0
    ret = ecc_public_key_size(privKey, &pubKeySz);
13111
0
    if (ret != 0)
13112
0
        return ret;
13113
0
#ifdef HAVE_COMP_KEY
13114
0
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
13115
0
        pubKeySz = (pubKeySz / 2) + 1;
13116
0
    }
13117
0
#endif /* HAVE_COMP_KEY */
13118
0
#endif /* WOLFSSL_ECIES_OLD */
13119
13120
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13121
0
        offset = keysLen;
13122
0
        keysLen *= 2;
13123
13124
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
13125
0
            return BAD_STATE_E;
13126
13127
0
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
13128
0
    }
13129
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13130
0
        if (ctx->srvSt != ecSRV_SALT_SET)
13131
0
            return BAD_STATE_E;
13132
13133
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
13134
0
    }
13135
13136
0
    if (keysLen > ECC_BUFSIZE) /* keys size */
13137
0
        return BUFFER_E;
13138
13139
#ifdef WOLFSSL_ECIES_OLD
13140
    if (((msgSz - digestSz) % blockSz) != 0)
13141
        return BAD_PADDING_E;
13142
13143
    if (*outSz < (msgSz - digestSz))
13144
        return BUFFER_E;
13145
#elif defined(WOLFSSL_ECIES_GEN_IV)
13146
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
13147
        return BAD_PADDING_E;
13148
13149
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
13150
        return BAD_FUNC_ARG;
13151
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
13152
        return BUFFER_E;
13153
#else
13154
0
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
13155
0
        return BAD_PADDING_E;
13156
13157
0
    if (msgSz < pubKeySz + blockSz + digestSz)
13158
0
        return BAD_FUNC_ARG;
13159
0
    if (*outSz < (msgSz - digestSz - pubKeySz))
13160
0
        return BUFFER_E;
13161
0
#endif
13162
13163
0
#ifdef ECC_TIMING_RESISTANT
13164
0
    if (ctx->rng != NULL && privKey->rng == NULL)
13165
0
        privKey->rng = ctx->rng;
13166
0
#endif
13167
13168
0
#ifdef WOLFSSL_SMALL_STACK
13169
0
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13170
0
    if (sharedSecret == NULL) {
13171
0
    #ifndef WOLFSSL_ECIES_OLD
13172
0
        if (pubKey == peerKey)
13173
0
            wc_ecc_free(peerKey);
13174
0
    #endif
13175
0
        return MEMORY_E;
13176
0
    }
13177
13178
0
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13179
0
    if (keys == NULL) {
13180
0
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13181
0
    #ifndef WOLFSSL_ECIES_OLD
13182
0
        if (pubKey == peerKey)
13183
0
            wc_ecc_free(peerKey);
13184
0
    #endif
13185
0
        return MEMORY_E;
13186
0
    }
13187
0
#endif
13188
13189
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
13190
13191
0
#ifndef WOLFSSL_ECIES_OLD
13192
0
    if (pubKey == NULL) {
13193
0
#ifdef WOLFSSL_SMALL_STACK
13194
0
        peerKey = (ecc_key*)XMALLOC(sizeof(*peerKey), ctx->heap,
13195
0
                                                       DYNAMIC_TYPE_ECC_BUFFER);
13196
0
        if (peerKey == NULL)
13197
0
            ret = MEMORY_E;
13198
0
#endif
13199
0
        pubKey = peerKey;
13200
0
    }
13201
0
    else {
13202
        /* if a public key was passed in we should free it here before init
13203
         * and import */
13204
0
        wc_ecc_free(pubKey);
13205
0
    }
13206
0
    if (ret == 0) {
13207
0
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
13208
0
    }
13209
0
    if (ret == 0) {
13210
0
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
13211
0
    }
13212
0
    if (ret == 0) {
13213
        /* Point is not MACed. */
13214
0
        msg += pubKeySz;
13215
0
        msgSz -= pubKeySz;
13216
0
    }
13217
0
#endif
13218
13219
0
    if (ret == 0) {
13220
    #ifdef WOLFSSL_ECIES_ISO18033
13221
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
13222
        sharedSz -= pubKeySz;
13223
    #endif
13224
13225
0
        do {
13226
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
13227
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
13228
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
13229
            if (ret != 0)
13230
                break;
13231
        #endif
13232
0
        #ifndef WOLFSSL_ECIES_ISO18033
13233
0
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
13234
0
                                                                    &sharedSz);
13235
        #else
13236
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
13237
                                                          pubKeySz, &sharedSz);
13238
        #endif
13239
0
        } while (ret == WC_PENDING_E);
13240
0
    }
13241
0
    if (ret == 0) {
13242
    #ifdef WOLFSSL_ECIES_ISO18033
13243
        /* KDF data is encoded public key and secret. */
13244
        sharedSz += pubKeySz;
13245
    #endif
13246
0
        switch (ctx->kdfAlgo) {
13247
0
            case ecHKDF_SHA256 :
13248
0
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
13249
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
13250
0
                           keys, keysLen);
13251
0
                break;
13252
13253
0
            default:
13254
0
                ret = BAD_FUNC_ARG;
13255
0
                break;
13256
0
         }
13257
0
    }
13258
13259
0
    if (ret == 0) {
13260
    #ifdef WOLFSSL_ECIES_OLD
13261
        encKey = keys + offset;
13262
        encIv  = encKey + encKeySz;
13263
        macKey = encKey + encKeySz + ivSz;
13264
    #elif defined(WOLFSSL_ECIES_GEN_IV)
13265
        encKey = keys + offset;
13266
        encIv  = msg;
13267
        msg   += ivSz;
13268
        msgSz -= ivSz;
13269
        macKey = encKey + encKeySz;
13270
    #else
13271
0
        XMEMSET(iv, 0, ivSz);
13272
0
        encKey = keys + offset;
13273
0
        encIv  = iv;
13274
0
        macKey = encKey + encKeySz;
13275
0
    #endif
13276
13277
0
        switch (ctx->macAlgo) {
13278
0
            case ecHMAC_SHA256:
13279
0
            {
13280
0
                byte verify[WC_SHA256_DIGEST_SIZE];
13281
0
            #ifdef WOLFSSL_SMALL_STACK
13282
0
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
13283
0
                                             DYNAMIC_TYPE_HMAC);
13284
0
                if (hmac == NULL) {
13285
0
                    ret = MEMORY_E;
13286
0
                    break;
13287
0
                }
13288
            #else
13289
                Hmac hmac[1];
13290
            #endif
13291
0
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
13292
0
                if (ret == 0) {
13293
0
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
13294
0
                                                         WC_SHA256_DIGEST_SIZE);
13295
0
                    if (ret == 0)
13296
0
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
13297
0
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
13298
                    #else
13299
                        /* IV is before encrypted message. */
13300
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
13301
                    #endif
13302
0
                    if (ret == 0)
13303
0
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
13304
13305
0
                    if (ret == 0)
13306
0
                        ret = wc_HmacFinal(hmac, verify);
13307
0
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
13308
0
                                                              digestSz) != 0)) {
13309
0
                        ret = -1;
13310
0
                    }
13311
13312
0
                    wc_HmacFree(hmac);
13313
0
                }
13314
0
            #ifdef WOLFSSL_SMALL_STACK
13315
0
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
13316
0
            #endif
13317
0
                break;
13318
0
            }
13319
13320
0
            default:
13321
0
                ret = BAD_FUNC_ARG;
13322
0
                break;
13323
0
        }
13324
0
    }
13325
13326
0
    if (ret == 0) {
13327
0
        switch (ctx->encAlgo) {
13328
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13329
0
            case ecAES_128_CBC:
13330
0
            case ecAES_256_CBC:
13331
0
            {
13332
0
            #ifdef WOLFSSL_SMALL_STACK
13333
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
13334
0
                                          DYNAMIC_TYPE_AES);
13335
0
                if (aes == NULL) {
13336
0
                    ret = MEMORY_E;
13337
0
                    break;
13338
0
                }
13339
            #else
13340
                Aes aes[1];
13341
            #endif
13342
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13343
0
                if (ret == 0) {
13344
0
                    ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
13345
0
                                                                AES_DECRYPTION);
13346
0
                    if (ret == 0) {
13347
0
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
13348
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
13349
                                                    defined(WC_ASYNC_ENABLE_AES)
13350
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
13351
                                                            WC_ASYNC_FLAG_NONE);
13352
                    #endif
13353
0
                    }
13354
0
                    wc_AesFree(aes);
13355
0
                }
13356
0
            #ifdef WOLFSSL_SMALL_STACK
13357
0
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
13358
0
            #endif
13359
0
                break;
13360
0
            }
13361
0
        #endif
13362
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
13363
0
            case ecAES_128_CTR:
13364
0
            case ecAES_256_CTR:
13365
0
            {
13366
0
            #ifdef WOLFSSL_SMALL_STACK
13367
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
13368
0
                                          DYNAMIC_TYPE_AES);
13369
0
                if (aes == NULL) {
13370
0
                    ret = MEMORY_E;
13371
0
                    break;
13372
0
                }
13373
             #else
13374
                Aes aes[1];
13375
             #endif
13376
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13377
0
                if (ret == 0) {
13378
0
                    byte ctr_iv[AES_BLOCK_SIZE];
13379
                    /* Make a 16 byte IV from the bytes passed in. */
13380
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
13381
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
13382
0
                        AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
13383
0
                    ret = wc_AesSetKey(aes, encKey, encKeySz, ctr_iv,
13384
0
                                                                AES_ENCRYPTION);
13385
0
                    if (ret == 0) {
13386
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
13387
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
13388
                                                    defined(WC_ASYNC_ENABLE_AES)
13389
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
13390
                                                            WC_ASYNC_FLAG_NONE);
13391
                    #endif
13392
0
                    }
13393
0
                    wc_AesFree(aes);
13394
0
                }
13395
0
            #ifdef WOLFSSL_SMALL_STACK
13396
0
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
13397
0
            #endif
13398
0
                break;
13399
0
            }
13400
0
        #endif
13401
0
            default:
13402
0
                ret = BAD_FUNC_ARG;
13403
0
                break;
13404
0
        }
13405
0
    }
13406
13407
0
    if (ret == 0)
13408
0
       *outSz = msgSz - digestSz;
13409
13410
0
    RESTORE_VECTOR_REGISTERS();
13411
13412
0
#ifndef WOLFSSL_ECIES_OLD
13413
0
    if (pubKey == peerKey)
13414
0
        wc_ecc_free(peerKey);
13415
0
#endif
13416
0
#ifdef WOLFSSL_SMALL_STACK
13417
0
#ifndef WOLFSSL_ECIES_OLD
13418
0
    if (peerKey != NULL) {
13419
0
        XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13420
0
    }
13421
0
#endif
13422
0
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13423
0
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13424
0
#endif
13425
13426
0
    return ret;
13427
0
}
13428
13429
13430
#endif /* HAVE_ECC_ENCRYPT */
13431
13432
13433
#ifdef HAVE_COMP_KEY
13434
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
13435
    !defined(WOLFSSL_CRYPTOCELL)
13436
13437
#ifndef WOLFSSL_SP_MATH
13438
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
13439
 */
13440
int mp_jacobi(mp_int* a, mp_int* n, int* c)
13441
0
{
13442
0
#ifdef WOLFSSL_SMALL_STACK
13443
0
    mp_int*  a1 = NULL;
13444
0
    mp_int*  n1 = NULL;
13445
#else
13446
    mp_int   a1[1], n1[1];
13447
#endif
13448
0
    int      res;
13449
0
    int      s = 1;
13450
0
    int      k;
13451
0
    mp_int*  t[2];
13452
0
    mp_int*  ts;
13453
0
    mp_digit residue;
13454
13455
0
    if (mp_isneg(a) == MP_YES) {
13456
0
        return MP_VAL;
13457
0
    }
13458
0
    if (mp_isneg(n) == MP_YES) {
13459
0
        return MP_VAL;
13460
0
    }
13461
0
    if (mp_iseven(n) == MP_YES) {
13462
0
        return MP_VAL;
13463
0
    }
13464
13465
0
#ifdef WOLFSSL_SMALL_STACK
13466
0
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
13467
0
    if (a1 == NULL) {
13468
0
        return MP_MEM;
13469
0
    }
13470
0
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
13471
0
    if (n1 == NULL) {
13472
0
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13473
0
        return MP_MEM;
13474
0
    }
13475
0
#endif
13476
13477
0
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
13478
0
#ifdef WOLFSSL_SMALL_STACK
13479
0
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13480
0
        XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
13481
0
#endif
13482
0
        return res;
13483
0
    }
13484
13485
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
13486
13487
0
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
13488
0
        goto done;
13489
0
    }
13490
13491
0
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
13492
0
        goto done;
13493
0
    }
13494
13495
0
    t[0] = a1;
13496
0
    t[1] = n1;
13497
13498
    /* Keep reducing until first number is 0. */
13499
0
    while (!mp_iszero(t[0])) {
13500
        /* Divide by 2 until odd. */
13501
0
        k = mp_cnt_lsb(t[0]);
13502
0
        if (k > 0) {
13503
0
            mp_rshb(t[0], k);
13504
13505
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
13506
             * Odd number of divides results in a negate.
13507
             */
13508
0
            residue = t[1]->dp[0] & 7;
13509
0
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
13510
0
                s = -s;
13511
0
            }
13512
0
        }
13513
13514
        /* Swap t[0] and t[1]. */
13515
0
        ts   = t[0];
13516
0
        t[0] = t[1];
13517
0
        t[1] = ts;
13518
13519
        /* Negate s if both numbers == 3 mod 4. */
13520
0
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
13521
0
             s = -s;
13522
0
        }
13523
13524
        /* Reduce first number modulo second. */
13525
0
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
13526
0
            res = mp_sub(t[0], t[1], t[0]);
13527
0
        }
13528
0
        else {
13529
0
            res = mp_mod(t[0], t[1], t[0]);
13530
0
        }
13531
0
        if (res != MP_OKAY) {
13532
0
            goto done;
13533
0
        }
13534
0
    }
13535
13536
    /* When the two numbers have divisors in common. */
13537
0
    if (!mp_isone(t[1])) {
13538
0
        s = 0;
13539
0
    }
13540
0
    *c = s;
13541
13542
0
done:
13543
13544
0
    RESTORE_VECTOR_REGISTERS();
13545
13546
    /* cleanup */
13547
0
    mp_clear(n1);
13548
0
    mp_clear(a1);
13549
13550
0
#ifdef WOLFSSL_SMALL_STACK
13551
0
    XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13552
0
    XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
13553
0
#endif
13554
13555
0
  return res;
13556
0
}
13557
13558
13559
/* Solves the modular equation x^2 = n (mod p)
13560
 * where prime number is greater than 2 (odd prime).
13561
 * The result is returned in the third argument x
13562
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
13563
 */
13564
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
13565
0
{
13566
#ifdef SQRTMOD_USE_MOD_EXP
13567
  int res;
13568
13569
  mp_int e;
13570
13571
  SAVE_VECTOR_REGISTERS(return _svr_ret;);
13572
13573
  res = mp_init(&e);
13574
  if (res == MP_OKAY)
13575
      res = mp_add_d(prime, 1, &e);
13576
  if (res == MP_OKAY)
13577
      res = mp_div_2d(&e, 2, &e, NULL);
13578
  if (res == MP_OKAY)
13579
      res = mp_exptmod(n, &e, prime, ret);
13580
13581
  mp_clear(&e);
13582
13583
  RESTORE_VECTOR_REGISTERS();
13584
13585
  return res;
13586
#else
13587
0
  int res, legendre, done = 0;
13588
0
  mp_digit i;
13589
0
#ifdef WOLFSSL_SMALL_STACK
13590
0
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13591
0
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13592
0
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13593
0
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13594
0
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13595
0
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13596
0
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13597
0
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13598
0
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13599
0
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13600
#else
13601
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
13602
#endif
13603
13604
0
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
13605
13606
0
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
13607
0
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
13608
0
    res = MP_INIT_E;
13609
0
    goto out;
13610
0
  }
13611
13612
0
#ifdef WOLFSSL_SMALL_STACK
13613
0
  if ((t1 == NULL) ||
13614
0
      (C == NULL) ||
13615
0
      (Q == NULL) ||
13616
0
      (S == NULL) ||
13617
0
      (Z == NULL) ||
13618
0
      (M == NULL) ||
13619
0
      (T == NULL) ||
13620
0
      (R == NULL) ||
13621
0
      (N == NULL) ||
13622
0
      (two == NULL)) {
13623
0
    res = MP_MEM;
13624
0
    goto out;
13625
0
  }
13626
0
#endif
13627
13628
  /* first handle the simple cases n = 0 or n = 1 */
13629
0
  if (mp_cmp_d(n, 0) == MP_EQ) {
13630
0
    mp_zero(ret);
13631
0
    res = MP_OKAY;
13632
0
    goto out;
13633
0
  }
13634
0
  if (mp_cmp_d(n, 1) == MP_EQ) {
13635
0
    res = mp_set(ret, 1);
13636
0
    goto out;
13637
0
  }
13638
13639
  /* prime must be odd */
13640
0
  if (mp_cmp_d(prime, 2) == MP_EQ) {
13641
0
    res = MP_VAL;
13642
0
    goto out;
13643
0
  }
13644
13645
  /* reduce n to less than prime */
13646
0
  res = mp_mod(n, prime, N);
13647
0
  if (res != MP_OKAY) {
13648
0
    goto out;
13649
0
  }
13650
  /* when N is zero, sqrt is zero */
13651
0
  if (mp_iszero(N)) {
13652
0
    mp_set(ret, 0);
13653
0
    goto out;
13654
0
  }
13655
13656
  /* is quadratic non-residue mod prime */
13657
0
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
13658
0
    goto out;
13659
0
  }
13660
0
  if (legendre == -1) {
13661
0
    res = MP_VAL;
13662
0
    goto out;
13663
0
  }
13664
13665
  /* SPECIAL CASE: if prime mod 4 == 3
13666
   * compute directly: res = n^(prime+1)/4 mod prime
13667
   * Handbook of Applied Cryptography algorithm 3.36
13668
   */
13669
0
  res = mp_mod_d(prime, 4, &i);
13670
0
  if (res == MP_OKAY && i == 3) {
13671
0
    res = mp_add_d(prime, 1, t1);
13672
13673
0
    if (res == MP_OKAY)
13674
0
      res = mp_div_2(t1, t1);
13675
0
    if (res == MP_OKAY)
13676
0
      res = mp_div_2(t1, t1);
13677
0
    if (res == MP_OKAY)
13678
0
      res = mp_exptmod(N, t1, prime, ret);
13679
13680
0
    done = 1;
13681
0
  }
13682
13683
  /* NOW: TonelliShanks algorithm */
13684
0
  if (res == MP_OKAY && done == 0) {
13685
13686
    /* factor out powers of 2 from prime-1, defining Q and S
13687
    *                                      as: prime-1 = Q*2^S */
13688
    /* Q = prime - 1 */
13689
0
    res = mp_copy(prime, Q);
13690
0
    if (res == MP_OKAY)
13691
0
      res = mp_sub_d(Q, 1, Q);
13692
13693
    /* S = 0 */
13694
0
    if (res == MP_OKAY)
13695
0
      mp_zero(S);
13696
13697
0
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
13698
      /* Q = Q / 2 */
13699
0
      res = mp_div_2(Q, Q);
13700
13701
      /* S = S + 1 */
13702
0
      if (res == MP_OKAY)
13703
0
        res = mp_add_d(S, 1, S);
13704
0
    }
13705
13706
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
13707
    /* Z = 2 */
13708
0
    if (res == MP_OKAY)
13709
0
      res = mp_set_int(Z, 2);
13710
13711
0
    while (res == MP_OKAY) {
13712
0
      res = mp_jacobi(Z, prime, &legendre);
13713
0
      if (res == MP_OKAY && legendre == -1)
13714
0
        break;
13715
13716
      /* Z = Z + 1 */
13717
0
      if (res == MP_OKAY)
13718
0
        res = mp_add_d(Z, 1, Z);
13719
0
    }
13720
13721
    /* C = Z ^ Q mod prime */
13722
0
    if (res == MP_OKAY)
13723
0
      res = mp_exptmod(Z, Q, prime, C);
13724
13725
    /* t1 = (Q + 1) / 2 */
13726
0
    if (res == MP_OKAY)
13727
0
      res = mp_add_d(Q, 1, t1);
13728
0
    if (res == MP_OKAY)
13729
0
      res = mp_div_2(t1, t1);
13730
13731
    /* R = n ^ ((Q + 1) / 2) mod prime */
13732
0
    if (res == MP_OKAY)
13733
0
      res = mp_exptmod(N, t1, prime, R);
13734
13735
    /* T = n ^ Q mod prime */
13736
0
    if (res == MP_OKAY)
13737
0
      res = mp_exptmod(N, Q, prime, T);
13738
13739
    /* M = S */
13740
0
    if (res == MP_OKAY)
13741
0
      res = mp_copy(S, M);
13742
13743
0
    if (res == MP_OKAY)
13744
0
      res = mp_set_int(two, 2);
13745
13746
0
    while (res == MP_OKAY && done == 0) {
13747
0
      res = mp_copy(T, t1);
13748
13749
      /* reduce to 1 and count */
13750
0
      i = 0;
13751
0
      while (res == MP_OKAY) {
13752
0
        if (mp_cmp_d(t1, 1) == MP_EQ)
13753
0
            break;
13754
0
        res = mp_exptmod(t1, two, prime, t1);
13755
0
        if (res == MP_OKAY)
13756
0
          i++;
13757
0
      }
13758
0
      if (res == MP_OKAY && i == 0) {
13759
0
        res = mp_copy(R, ret);
13760
0
        done = 1;
13761
0
      }
13762
13763
0
      if (done == 0) {
13764
        /* t1 = 2 ^ (M - i - 1) */
13765
0
        if (res == MP_OKAY)
13766
0
          res = mp_sub_d(M, i, t1);
13767
0
        if (res == MP_OKAY)
13768
0
          res = mp_sub_d(t1, 1, t1);
13769
0
        if (res == MP_OKAY)
13770
0
          res = mp_exptmod(two, t1, prime, t1);
13771
13772
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
13773
0
        if (res == MP_OKAY)
13774
0
          res = mp_exptmod(C, t1, prime, t1);
13775
13776
        /* C = (t1 * t1) mod prime */
13777
0
        if (res == MP_OKAY)
13778
0
          res = mp_sqrmod(t1, prime, C);
13779
13780
        /* R = (R * t1) mod prime */
13781
0
        if (res == MP_OKAY)
13782
0
          res = mp_mulmod(R, t1, prime, R);
13783
13784
        /* T = (T * C) mod prime */
13785
0
        if (res == MP_OKAY)
13786
0
          res = mp_mulmod(T, C, prime, T);
13787
13788
        /* M = i */
13789
0
        if (res == MP_OKAY)
13790
0
          res = mp_set(M, i);
13791
0
      }
13792
0
    }
13793
0
  }
13794
13795
0
  out:
13796
13797
0
  RESTORE_VECTOR_REGISTERS();
13798
13799
0
#ifdef WOLFSSL_SMALL_STACK
13800
0
  if (t1) {
13801
0
    if (res != MP_INIT_E)
13802
0
      mp_clear(t1);
13803
0
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13804
0
  }
13805
0
  if (C) {
13806
0
    if (res != MP_INIT_E)
13807
0
      mp_clear(C);
13808
0
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13809
0
  }
13810
0
  if (Q) {
13811
0
    if (res != MP_INIT_E)
13812
0
      mp_clear(Q);
13813
0
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13814
0
  }
13815
0
  if (S) {
13816
0
    if (res != MP_INIT_E)
13817
0
      mp_clear(S);
13818
0
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13819
0
  }
13820
0
  if (Z) {
13821
0
    if (res != MP_INIT_E)
13822
0
      mp_clear(Z);
13823
0
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13824
0
  }
13825
0
  if (M) {
13826
0
    if (res != MP_INIT_E)
13827
0
      mp_clear(M);
13828
0
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13829
0
  }
13830
0
  if (T) {
13831
0
    if (res != MP_INIT_E)
13832
0
      mp_clear(T);
13833
0
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13834
0
  }
13835
0
  if (R) {
13836
0
    if (res != MP_INIT_E)
13837
0
      mp_clear(R);
13838
0
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13839
0
  }
13840
0
  if (N) {
13841
0
    if (res != MP_INIT_E)
13842
0
      mp_clear(N);
13843
0
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13844
0
  }
13845
0
  if (two) {
13846
0
    if (res != MP_INIT_E)
13847
0
      mp_clear(two);
13848
0
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13849
0
  }
13850
#else
13851
  if (res != MP_INIT_E) {
13852
    mp_clear(t1);
13853
    mp_clear(C);
13854
    mp_clear(Q);
13855
    mp_clear(S);
13856
    mp_clear(Z);
13857
    mp_clear(M);
13858
    mp_clear(T);
13859
    mp_clear(R);
13860
    mp_clear(N);
13861
    mp_clear(two);
13862
  }
13863
#endif
13864
13865
0
  return res;
13866
0
#endif
13867
0
}
13868
#endif /* !WOLFSSL_SP_MATH */
13869
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
13870
13871
13872
/* export public ECC key in ANSI X9.63 format compressed */
13873
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
13874
0
{
13875
0
   word32 numlen;
13876
0
   int    ret = MP_OKAY;
13877
13878
0
   if (key == NULL || outLen == NULL)
13879
0
       return BAD_FUNC_ARG;
13880
13881
0
   if (key->type == ECC_PRIVATEKEY_ONLY)
13882
0
       return ECC_PRIVATEONLY_E;
13883
13884
0
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
13885
0
       return ECC_BAD_ARG_E;
13886
0
   }
13887
13888
0
   numlen = key->dp->size;
13889
13890
0
   if (*outLen < (1 + numlen)) {
13891
0
      *outLen = 1 + numlen;
13892
0
      return LENGTH_ONLY_E;
13893
0
   }
13894
13895
0
   if (out == NULL)
13896
0
       return BAD_FUNC_ARG;
13897
13898
0
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
13899
0
       return ECC_BAD_ARG_E;
13900
13901
   /* store first byte */
13902
0
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
13903
13904
   /* pad and store x */
13905
0
   XMEMSET(out+1, 0, numlen);
13906
0
   ret = mp_to_unsigned_bin(key->pubkey.x,
13907
0
                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
13908
0
   *outLen = 1 + numlen;
13909
13910
0
   return ret;
13911
0
}
13912
13913
#endif /* HAVE_COMP_KEY */
13914
13915
13916
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
13917
0
{
13918
0
    int x;
13919
13920
0
    if (oidSum == 0) {
13921
0
        return BAD_FUNC_ARG;
13922
0
    }
13923
13924
    /* find matching OID sum (based on encoded value) */
13925
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
13926
0
        if (ecc_sets[x].oidSum == oidSum) {
13927
0
            int ret;
13928
        #ifdef HAVE_OID_ENCODING
13929
            ret = 0;
13930
            /* check cache */
13931
            oid_cache_t* o = &ecc_oid_cache[x];
13932
            if (o->oidSz == 0) {
13933
                o->oidSz = sizeof(o->oid);
13934
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
13935
                                                            o->oid, &o->oidSz);
13936
            }
13937
            if (oidSz) {
13938
                *oidSz = o->oidSz;
13939
            }
13940
            if (oid) {
13941
                *oid = o->oid;
13942
            }
13943
            /* on success return curve id */
13944
            if (ret == 0) {
13945
                ret = ecc_sets[x].id;
13946
            }
13947
        #else
13948
0
            if (oidSz) {
13949
0
                *oidSz = ecc_sets[x].oidSz;
13950
0
            }
13951
0
            if (oid) {
13952
0
                *oid = ecc_sets[x].oid;
13953
0
            }
13954
0
            ret = ecc_sets[x].id;
13955
0
        #endif
13956
0
            return ret;
13957
0
        }
13958
0
    }
13959
13960
0
    return NOT_COMPILED_IN;
13961
0
}
13962
13963
#ifdef WOLFSSL_CUSTOM_CURVES
13964
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
13965
0
{
13966
0
    if (key == NULL || dp == NULL) {
13967
0
        return BAD_FUNC_ARG;
13968
0
    }
13969
13970
0
    key->idx = ECC_CUSTOM_IDX;
13971
0
    key->dp = dp;
13972
13973
0
    return 0;
13974
0
}
13975
#endif /* WOLFSSL_CUSTOM_CURVES */
13976
13977
#ifdef HAVE_X963_KDF
13978
13979
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
13980
0
{
13981
0
    int i;
13982
13983
    /* in network byte order so start at end and work back */
13984
0
    for (i = 3; i >= 0; i--) {
13985
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
13986
0
            return;
13987
0
    }
13988
0
}
13989
13990
/* ASN X9.63 Key Derivation Function (SEC1) */
13991
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
13992
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
13993
0
{
13994
0
    int ret;
13995
0
    int digestSz, copySz;
13996
0
    int remaining = outSz;
13997
0
    byte* outIdx;
13998
0
    byte  counter[4];
13999
0
    byte  tmp[WC_MAX_DIGEST_SIZE];
14000
14001
0
#ifdef WOLFSSL_SMALL_STACK
14002
0
    wc_HashAlg* hash;
14003
#else
14004
    wc_HashAlg hash[1];
14005
#endif
14006
14007
0
    if (secret == NULL || secretSz == 0 || out == NULL)
14008
0
        return BAD_FUNC_ARG;
14009
14010
    /* X9.63 allowed algos only */
14011
0
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
14012
0
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
14013
0
        type != WC_HASH_TYPE_SHA512)
14014
0
        return BAD_FUNC_ARG;
14015
14016
0
    digestSz = wc_HashGetDigestSize(type);
14017
0
    if (digestSz < 0)
14018
0
        return digestSz;
14019
14020
0
#ifdef WOLFSSL_SMALL_STACK
14021
0
    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
14022
0
                                DYNAMIC_TYPE_HASHES);
14023
0
    if (hash == NULL)
14024
0
        return MEMORY_E;
14025
0
#endif
14026
14027
0
    ret = wc_HashInit(hash, type);
14028
0
    if (ret != 0) {
14029
0
#ifdef WOLFSSL_SMALL_STACK
14030
0
        XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
14031
0
#endif
14032
0
        return ret;
14033
0
    }
14034
14035
0
    outIdx = out;
14036
0
    XMEMSET(counter, 0, sizeof(counter));
14037
14038
0
    while (remaining > 0) {
14039
14040
0
        IncrementX963KdfCounter(counter);
14041
14042
0
        ret = wc_HashUpdate(hash, type, secret, secretSz);
14043
0
        if (ret != 0) {
14044
0
            break;
14045
0
        }
14046
14047
0
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
14048
0
        if (ret != 0) {
14049
0
            break;
14050
0
        }
14051
14052
0
        if (sinfo) {
14053
0
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
14054
0
            if (ret != 0) {
14055
0
                break;
14056
0
            }
14057
0
        }
14058
14059
0
        ret = wc_HashFinal(hash, type, tmp);
14060
0
        if (ret != 0) {
14061
0
            break;
14062
0
        }
14063
14064
0
        copySz = min(remaining, digestSz);
14065
0
        XMEMCPY(outIdx, tmp, copySz);
14066
14067
0
        remaining -= copySz;
14068
0
        outIdx += copySz;
14069
0
    }
14070
14071
0
    wc_HashFree(hash, type);
14072
14073
0
#ifdef WOLFSSL_SMALL_STACK
14074
0
     XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
14075
0
#endif
14076
14077
0
    return ret;
14078
0
}
14079
#endif /* HAVE_X963_KDF */
14080
14081
#ifdef WC_ECC_NONBLOCK
14082
/* Enable ECC support for non-blocking operations */
14083
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
14084
{
14085
    if (key) {
14086
        if (ctx) {
14087
            XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
14088
        }
14089
        key->nb_ctx = ctx;
14090
    }
14091
    return 0;
14092
}
14093
#endif /* WC_ECC_NONBLOCK */
14094
14095
#endif /* HAVE_ECC */