Coverage Report

Created: 2022-08-24 06:26

/src/wolfssl-sp-math/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
    #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
10.5k
#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
7.92k
        mp_int* spec_ints = NULL;                                       \
1340
7.92k
        ecc_curve_spec curve_lcl;                                       \
1341
7.92k
        ecc_curve_spec* curve = &curve_lcl;                             \
1342
7.92k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1343
7.92k
        curve->spec_count = intcount
1344
1345
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1346
7.92k
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1347
7.92k
                            DYNAMIC_TYPE_ECC);                          \
1348
7.92k
        if (spec_ints == NULL)                                          \
1349
7.92k
            (err) = MEMORY_E;                                           \
1350
7.92k
        else                                                            \
1351
7.92k
            curve->spec_ints = spec_ints
1352
    #define FREE_CURVE_SPECS()                                          \
1353
7.92k
        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
26.0k
{
1369
26.0k
    if (item) {
1370
    #ifdef HAVE_WOLF_BIGINT
1371
        wc_bigint_free(&item->raw);
1372
    #endif
1373
26.0k
        mp_clear(item);
1374
26.0k
    }
1375
26.0k
    curve->load_mask &= ~mask;
1376
26.0k
}
1377
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1378
7.90k
{
1379
7.90k
    if (curve == NULL) {
1380
0
        return;
1381
0
    }
1382
1383
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1384
4.59k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1385
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1386
4.59k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1387
7.90k
#ifdef USE_ECC_B_PARAM
1388
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1389
4.59k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1390
7.90k
#endif
1391
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1392
6.14k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1393
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1394
3.06k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1395
7.90k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1396
3.06k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1397
1398
7.90k
    curve->load_mask = 0;
1399
7.90k
}
1400
1401
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1402
7.90k
{
1403
7.90k
    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
7.90k
        wc_ecc_curve_cache_free_spec(curve);
1414
7.90k
    #endif
1415
7.90k
    }
1416
7.90k
}
1417
1418
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1419
    mp_int** dst, byte mask)
1420
26.0k
{
1421
26.0k
    int err;
1422
1423
26.0k
#ifndef ECC_CACHE_CURVE
1424
    /* get mp_int from temp */
1425
26.0k
    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
26.0k
    *dst = &curve->spec_ints[curve->spec_use++];
1430
26.0k
#endif
1431
1432
26.0k
    err = mp_init(*dst);
1433
26.0k
    if (err == MP_OKAY) {
1434
26.0k
        curve->load_mask |= mask;
1435
1436
26.0k
        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
26.0k
    }
1443
26.0k
    return err;
1444
26.0k
}
1445
1446
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1447
    byte load_mask)
1448
7.67k
{
1449
7.67k
    int ret = 0;
1450
7.67k
    ecc_curve_spec* curve;
1451
7.67k
    byte load_items = 0; /* mask of items to load */
1452
#ifdef ECC_CACHE_CURVE
1453
    int x;
1454
#endif
1455
1456
7.67k
    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
7.67k
    curve = *pCurve;
1501
7.67k
#endif /* ECC_CACHE_CURVE */
1502
1503
    /* make sure the curve is initialized */
1504
7.67k
    if (curve->dp != dp) {
1505
7.67k
        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
7.67k
    }
1518
7.67k
    curve->dp = dp; /* set dp info */
1519
1520
    /* determine items to load */
1521
7.67k
    load_items = (((byte)~(word32)curve->load_mask) & load_mask);
1522
7.67k
    curve->load_mask |= load_items;
1523
1524
    /* load items */
1525
7.67k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1526
4.59k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1527
4.59k
            ECC_CURVE_FIELD_PRIME);
1528
7.67k
    if (load_items & ECC_CURVE_FIELD_AF)
1529
4.59k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1530
4.59k
            ECC_CURVE_FIELD_AF);
1531
7.67k
#ifdef USE_ECC_B_PARAM
1532
7.67k
    if (load_items & ECC_CURVE_FIELD_BF)
1533
4.59k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1534
4.59k
            ECC_CURVE_FIELD_BF);
1535
7.67k
#endif
1536
7.67k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1537
6.14k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1538
6.14k
            ECC_CURVE_FIELD_ORDER);
1539
7.67k
    if (load_items & ECC_CURVE_FIELD_GX)
1540
3.06k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1541
3.06k
            ECC_CURVE_FIELD_GX);
1542
7.67k
    if (load_items & ECC_CURVE_FIELD_GY)
1543
3.06k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1544
3.06k
            ECC_CURVE_FIELD_GY);
1545
1546
    /* check for error */
1547
7.67k
    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
7.67k
    return ret;
1557
7.67k
}
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
2.95k
{
1596
2.95k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1597
2.95k
    if (curve_idx == ECC_CURVE_INVALID)
1598
270
        return NULL;
1599
2.68k
    return ecc_sets[curve_idx].name;
1600
2.95k
}
1601
1602
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1603
8.81k
{
1604
8.81k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1605
0
        return BAD_FUNC_ARG;
1606
0
    }
1607
1608
8.81k
    if (keysize > ECC_MAXSIZE) {
1609
57
        return ECC_BAD_ARG_E;
1610
57
    }
1611
1612
    /* handle custom case */
1613
8.76k
    if (key->idx != ECC_CUSTOM_IDX) {
1614
8.76k
        int x;
1615
1616
        /* default values */
1617
8.76k
        key->idx = 0;
1618
8.76k
        key->dp = NULL;
1619
1620
        /* find ecc_set based on curve_id or key size */
1621
16.4k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1622
16.0k
            if (curve_id > ECC_CURVE_DEF) {
1623
16.0k
                if (curve_id == ecc_sets[x].id)
1624
8.32k
                  break;
1625
16.0k
            }
1626
0
            else if (keysize <= ecc_sets[x].size) {
1627
0
                break;
1628
0
            }
1629
16.0k
        }
1630
8.76k
        if (ecc_sets[x].size == 0) {
1631
440
            WOLFSSL_MSG("ECC Curve not found");
1632
440
            return ECC_CURVE_OID_E;
1633
440
        }
1634
1635
8.32k
        key->idx = x;
1636
8.32k
        key->dp  = &ecc_sets[x];
1637
8.32k
    }
1638
1639
8.32k
    return 0;
1640
8.76k
}
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
769
{
1672
#if !defined(WOLFSSL_SP_MATH)
1673
#ifdef WOLFSSL_SMALL_STACK
1674
   mp_int* t1 = NULL;
1675
   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
   mp_int  *x, *y, *z;
1688
   int     err;
1689
1690
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1691
   if (Q == R) {
1692
      ecc_point* tPt  = P;
1693
      P = Q;
1694
      Q = tPt;
1695
   }
1696
1697
#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
   {
1711
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1712
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
1713
       if (t1 == NULL || t2 == NULL) {
1714
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1715
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1716
           return MEMORY_E;
1717
       }
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
   }
1732
#endif /* WOLFSSL_SMALL_STACK */
1733
1734
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
1735
#ifdef WOLFSSL_SMALL_STACK
1736
   #ifdef WOLFSSL_SMALL_STACK_CACHE
1737
       if (R->key == NULL)
1738
   #endif
1739
       {
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
          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1746
          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1747
       }
1748
#endif
1749
      return err;
1750
   }
1751
1752
   /* should we dbl instead? */
1753
   if (err == MP_OKAY) {
1754
#ifdef ECC_TIMING_RESISTANT
1755
       err = mp_submod_ct(modulus, Q->y, modulus, t1);
1756
#else
1757
       err = mp_sub(modulus, Q->y, t1);
1758
#endif
1759
   }
1760
   if (err == MP_OKAY) {
1761
       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
1762
            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
1763
            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
1764
           mp_clear(t1);
1765
           mp_clear(t2);
1766
    #ifdef WOLFSSL_SMALL_STACK
1767
       #ifdef WOLFSSL_SMALL_STACK_CACHE
1768
           if (R->key == NULL)
1769
       #endif
1770
           {
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
               XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1777
               XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1778
           }
1779
        #endif
1780
          return _ecc_projective_dbl_point(P, R, a, modulus, mp);
1781
       }
1782
   }
1783
1784
   if (err != MP_OKAY) {
1785
      goto done;
1786
   }
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
   x = R->x;
1802
   y = R->y;
1803
   z = R->z;
1804
#endif
1805
1806
   if (err == MP_OKAY)
1807
       err = mp_copy(P->x, x);
1808
   if (err == MP_OKAY)
1809
       err = mp_copy(P->y, y);
1810
   if (err == MP_OKAY)
1811
       err = mp_copy(P->z, z);
1812
1813
   /* if Z is one then these are no-operations */
1814
   if (err == MP_OKAY) {
1815
       if (!mp_iszero(Q->z)) {
1816
           /* T1 = Z' * Z' */
1817
           err = mp_sqr(Q->z, t1);
1818
           if (err == MP_OKAY)
1819
               err = mp_montgomery_reduce(t1, modulus, mp);
1820
1821
           /* X = X * T1 */
1822
           if (err == MP_OKAY)
1823
               err = mp_mul(t1, x, x);
1824
           if (err == MP_OKAY)
1825
               err = mp_montgomery_reduce(x, modulus, mp);
1826
1827
           /* T1 = Z' * T1 */
1828
           if (err == MP_OKAY)
1829
               err = mp_mul(Q->z, t1, t1);
1830
           if (err == MP_OKAY)
1831
               err = mp_montgomery_reduce(t1, modulus, mp);
1832
1833
           /* Y = Y * T1 */
1834
           if (err == MP_OKAY)
1835
               err = mp_mul(t1, y, y);
1836
           if (err == MP_OKAY)
1837
               err = mp_montgomery_reduce(y, modulus, mp);
1838
       }
1839
   }
1840
1841
   /* T1 = Z*Z */
1842
   if (err == MP_OKAY)
1843
       err = mp_sqr(z, t1);
1844
   if (err == MP_OKAY)
1845
       err = mp_montgomery_reduce(t1, modulus, mp);
1846
1847
   /* T2 = X' * T1 */
1848
   if (err == MP_OKAY)
1849
       err = mp_mul(Q->x, t1, t2);
1850
   if (err == MP_OKAY)
1851
       err = mp_montgomery_reduce(t2, modulus, mp);
1852
1853
   /* T1 = Z * T1 */
1854
   if (err == MP_OKAY)
1855
       err = mp_mul(z, t1, t1);
1856
   if (err == MP_OKAY)
1857
       err = mp_montgomery_reduce(t1, modulus, mp);
1858
1859
   /* T1 = Y' * T1 */
1860
   if (err == MP_OKAY)
1861
       err = mp_mul(Q->y, t1, t1);
1862
   if (err == MP_OKAY)
1863
       err = mp_montgomery_reduce(t1, modulus, mp);
1864
1865
   /* Y = Y - T1 */
1866
   if (err == MP_OKAY)
1867
       err = mp_submod_ct(y, t1, modulus, y);
1868
   /* T1 = 2T1 */
1869
   if (err == MP_OKAY)
1870
       err = mp_addmod_ct(t1, t1, modulus, t1);
1871
   /* T1 = Y + T1 */
1872
   if (err == MP_OKAY)
1873
       err = mp_addmod_ct(t1, y, modulus, t1);
1874
   /* X = X - T2 */
1875
   if (err == MP_OKAY)
1876
       err = mp_submod_ct(x, t2, modulus, x);
1877
   /* T2 = 2T2 */
1878
   if (err == MP_OKAY)
1879
       err = mp_addmod_ct(t2, t2, modulus, t2);
1880
   /* T2 = X + T2 */
1881
   if (err == MP_OKAY)
1882
       err = mp_addmod_ct(t2, x, modulus, t2);
1883
1884
   if (err == MP_OKAY) {
1885
       if (!mp_iszero(Q->z)) {
1886
           /* Z = Z * Z' */
1887
           err = mp_mul(z, Q->z, z);
1888
           if (err == MP_OKAY)
1889
               err = mp_montgomery_reduce(z, modulus, mp);
1890
       }
1891
   }
1892
1893
   /* Z = Z * X */
1894
   if (err == MP_OKAY)
1895
       err = mp_mul(z, x, z);
1896
   if (err == MP_OKAY)
1897
       err = mp_montgomery_reduce(z, modulus, mp);
1898
1899
   /* T1 = T1 * X  */
1900
   if (err == MP_OKAY)
1901
       err = mp_mul(t1, x, t1);
1902
   if (err == MP_OKAY)
1903
       err = mp_montgomery_reduce(t1, modulus, mp);
1904
1905
   /* X = X * X */
1906
   if (err == MP_OKAY)
1907
       err = mp_sqr(x, x);
1908
   if (err == MP_OKAY)
1909
       err = mp_montgomery_reduce(x, modulus, mp);
1910
1911
   /* T2 = T2 * x */
1912
   if (err == MP_OKAY)
1913
       err = mp_mul(t2, x, t2);
1914
   if (err == MP_OKAY)
1915
       err = mp_montgomery_reduce(t2, modulus, mp);
1916
1917
   /* T1 = T1 * X  */
1918
   if (err == MP_OKAY)
1919
       err = mp_mul(t1, x, t1);
1920
   if (err == MP_OKAY)
1921
       err = mp_montgomery_reduce(t1, modulus, mp);
1922
1923
   /* X = Y*Y */
1924
   if (err == MP_OKAY)
1925
       err = mp_sqr(y, x);
1926
   if (err == MP_OKAY)
1927
       err = mp_montgomery_reduce(x, modulus, mp);
1928
1929
   /* X = X - T2 */
1930
   if (err == MP_OKAY)
1931
       err = mp_submod_ct(x, t2, modulus, x);
1932
   /* T2 = T2 - X */
1933
   if (err == MP_OKAY)
1934
       err = mp_submod_ct(t2, x, modulus, t2);
1935
   /* T2 = T2 - X */
1936
   if (err == MP_OKAY)
1937
       err = mp_submod_ct(t2, x, modulus, t2);
1938
   /* T2 = T2 * Y */
1939
   if (err == MP_OKAY)
1940
       err = mp_mul(t2, y, t2);
1941
   if (err == MP_OKAY)
1942
       err = mp_montgomery_reduce(t2, modulus, mp);
1943
1944
   /* Y = T2 - T1 */
1945
   if (err == MP_OKAY)
1946
       err = mp_submod_ct(t2, t1, modulus, y);
1947
   /* Y = Y/2 */
1948
   if (err == MP_OKAY)
1949
       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
done:
1961
1962
   /* clean up */
1963
   mp_clear(t1);
1964
   mp_clear(t2);
1965
#ifdef WOLFSSL_SMALL_STACK
1966
#ifdef WOLFSSL_SMALL_STACK_CACHE
1967
   if (R->key == NULL)
1968
#endif
1969
   {
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
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
1976
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
1977
   }
1978
#endif
1979
1980
   return err;
1981
#else
1982
769
    int modBits = mp_count_bits(modulus);
1983
1984
769
    (void)a;
1985
769
    (void)mp;
1986
1987
769
#ifndef WOLFSSL_SP_NO_256
1988
769
    if (modBits == 256) {
1989
266
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
1990
266
                                         R->x, R->y, R->z);
1991
266
    }
1992
503
#endif
1993
503
#ifdef WOLFSSL_SP_384
1994
503
    if (modBits == 384) {
1995
304
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
1996
304
                                         R->x, R->y, R->z);
1997
304
    }
1998
199
#endif
1999
199
#ifdef WOLFSSL_SP_521
2000
199
    if (modBits == 521) {
2001
199
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2002
199
                                         R->x, R->y, R->z);
2003
199
    }
2004
0
#endif
2005
0
    return ECC_BAD_ARG_E;
2006
199
#endif
2007
199
}
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
816
{
2012
816
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2013
0
        return ECC_BAD_ARG_E;
2014
0
    }
2015
2016
816
    if (mp_cmp(P->x, modulus) != MP_LT ||
2017
816
        mp_cmp(P->y, modulus) != MP_LT ||
2018
816
        mp_cmp(P->z, modulus) != MP_LT ||
2019
816
        mp_cmp(Q->x, modulus) != MP_LT ||
2020
816
        mp_cmp(Q->y, modulus) != MP_LT ||
2021
816
        mp_cmp(Q->z, modulus) != MP_LT) {
2022
47
        return ECC_OUT_OF_RANGE_E;
2023
47
    }
2024
2025
769
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2026
816
}
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
18
{
2058
#if !defined(WOLFSSL_SP_MATH)
2059
#ifdef WOLFSSL_SMALL_STACK
2060
   mp_int* t1 = NULL;
2061
   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
   mp_int *x, *y, *z;
2074
   int    err;
2075
2076
#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
   {
2090
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2091
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2092
       if (t1 == NULL || t2 == NULL) {
2093
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2094
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2095
           return MEMORY_E;
2096
       }
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
    }
2111
#endif
2112
2113
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
2114
#ifdef WOLFSSL_SMALL_STACK
2115
#ifdef WOLFSSL_SMALL_STACK_CACHE
2116
    if (R->key == NULL)
2117
#endif
2118
    {
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
       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2125
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2126
     }
2127
#endif
2128
      return err;
2129
   }
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
   x = R->x;
2161
   y = R->y;
2162
   z = R->z;
2163
#endif
2164
2165
   if (err == MP_OKAY)
2166
       err = mp_copy(P->x, x);
2167
   if (err == MP_OKAY)
2168
       err = mp_copy(P->y, y);
2169
   if (err == MP_OKAY)
2170
       err = mp_copy(P->z, z);
2171
2172
   /* T1 = Z * Z */
2173
   if (err == MP_OKAY)
2174
       err = mp_sqr(z, t1);
2175
   if (err == MP_OKAY)
2176
       err = mp_montgomery_reduce(t1, modulus, mp);
2177
2178
   /* Z = Y * Z */
2179
   if (err == MP_OKAY)
2180
       err = mp_mul(z, y, z);
2181
   if (err == MP_OKAY)
2182
       err = mp_montgomery_reduce(z, modulus, mp);
2183
2184
   /* Z = 2Z */
2185
   if (err == MP_OKAY)
2186
       err = mp_addmod_ct(z, z, modulus, z);
2187
2188
   /* Determine if curve "a" should be used in calc */
2189
#ifdef WOLFSSL_CUSTOM_CURVES
2190
   if (err == MP_OKAY) {
2191
      /* Use a and prime to determine if a == 3 */
2192
      err = mp_submod(modulus, a, modulus, t2);
2193
   }
2194
   if (err == MP_OKAY && mp_iszero(t2)) {
2195
      /* T2 = X * X */
2196
      if (err == MP_OKAY)
2197
          err = mp_sqr(x, t2);
2198
      if (err == MP_OKAY)
2199
          err = mp_montgomery_reduce(t2, modulus, mp);
2200
      /* T1 = T2 + T1 */
2201
      if (err == MP_OKAY)
2202
          err = mp_addmod_ct(t2, t2, modulus, t1);
2203
      /* T1 = T2 + T1 */
2204
      if (err == MP_OKAY)
2205
          err = mp_addmod_ct(t1, t2, modulus, t1);
2206
   }
2207
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2208
      /* use "a" in calc */
2209
2210
      /* T2 = T1 * T1 */
2211
      if (err == MP_OKAY)
2212
          err = mp_sqr(t1, t2);
2213
      if (err == MP_OKAY)
2214
          err = mp_montgomery_reduce(t2, modulus, mp);
2215
      /* T1 = T2 * a */
2216
      if (err == MP_OKAY)
2217
          err = mp_mulmod(t2, a, modulus, t1);
2218
      /* T2 = X * X */
2219
      if (err == MP_OKAY)
2220
          err = mp_sqr(x, t2);
2221
      if (err == MP_OKAY)
2222
          err = mp_montgomery_reduce(t2, modulus, mp);
2223
      /* T1 = T2 + T1 */
2224
      if (err == MP_OKAY)
2225
          err = mp_addmod_ct(t1, t2, modulus, t1);
2226
      /* T1 = T2 + T1 */
2227
      if (err == MP_OKAY)
2228
          err = mp_addmod_ct(t1, t2, modulus, t1);
2229
      /* T1 = T2 + T1 */
2230
      if (err == MP_OKAY)
2231
          err = mp_addmod_ct(t1, t2, modulus, t1);
2232
   }
2233
   else
2234
#endif /* WOLFSSL_CUSTOM_CURVES */
2235
   {
2236
      /* assumes "a" == 3 */
2237
      (void)a;
2238
2239
      /* T2 = X - T1 */
2240
      if (err == MP_OKAY)
2241
          err = mp_submod_ct(x, t1, modulus, t2);
2242
      /* T1 = X + T1 */
2243
      if (err == MP_OKAY)
2244
          err = mp_addmod_ct(t1, x, modulus, t1);
2245
      /* T2 = T1 * T2 */
2246
      if (err == MP_OKAY)
2247
          err = mp_mul(t1, t2, t2);
2248
      if (err == MP_OKAY)
2249
          err = mp_montgomery_reduce(t2, modulus, mp);
2250
2251
      /* T1 = 2T2 */
2252
      if (err == MP_OKAY)
2253
          err = mp_addmod_ct(t2, t2, modulus, t1);
2254
      /* T1 = T1 + T2 */
2255
      if (err == MP_OKAY)
2256
          err = mp_addmod_ct(t1, t2, modulus, t1);
2257
   }
2258
2259
   /* Y = 2Y */
2260
   if (err == MP_OKAY)
2261
       err = mp_addmod_ct(y, y, modulus, y);
2262
   /* Y = Y * Y */
2263
   if (err == MP_OKAY)
2264
       err = mp_sqr(y, y);
2265
   if (err == MP_OKAY)
2266
       err = mp_montgomery_reduce(y, modulus, mp);
2267
2268
   /* T2 = Y * Y */
2269
   if (err == MP_OKAY)
2270
       err = mp_sqr(y, t2);
2271
   if (err == MP_OKAY)
2272
       err = mp_montgomery_reduce(t2, modulus, mp);
2273
2274
   /* T2 = T2/2 */
2275
   if (err == MP_OKAY)
2276
       err = mp_div_2_mod_ct(t2, modulus, t2);
2277
2278
   /* Y = Y * X */
2279
   if (err == MP_OKAY)
2280
       err = mp_mul(y, x, y);
2281
   if (err == MP_OKAY)
2282
       err = mp_montgomery_reduce(y, modulus, mp);
2283
2284
   /* X = T1 * T1 */
2285
   if (err == MP_OKAY)
2286
       err = mp_sqr(t1, x);
2287
   if (err == MP_OKAY)
2288
       err = mp_montgomery_reduce(x, modulus, mp);
2289
2290
   /* X = X - Y */
2291
   if (err == MP_OKAY)
2292
       err = mp_submod_ct(x, y, modulus, x);
2293
   /* X = X - Y */
2294
   if (err == MP_OKAY)
2295
       err = mp_submod_ct(x, y, modulus, x);
2296
2297
   /* Y = Y - X */
2298
   if (err == MP_OKAY)
2299
       err = mp_submod_ct(y, x, modulus, y);
2300
   /* Y = Y * T1 */
2301
   if (err == MP_OKAY)
2302
       err = mp_mul(y, t1, y);
2303
   if (err == MP_OKAY)
2304
       err = mp_montgomery_reduce(y, modulus, mp);
2305
2306
   /* Y = Y - T2 */
2307
   if (err == MP_OKAY)
2308
       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
   mp_clear(t1);
2321
   mp_clear(t2);
2322
2323
#ifdef WOLFSSL_SMALL_STACK
2324
#ifdef WOLFSSL_SMALL_STACK_CACHE
2325
   if (R->key == NULL)
2326
#endif
2327
   {
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
       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2334
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2335
    }
2336
#endif
2337
2338
   return err;
2339
#else
2340
18
    int modBits = mp_count_bits(modulus);
2341
2342
18
    (void)a;
2343
18
    (void)mp;
2344
2345
18
#ifndef WOLFSSL_SP_NO_256
2346
18
    if (modBits == 256) {
2347
7
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2348
7
    }
2349
11
#endif
2350
11
#ifdef WOLFSSL_SP_384
2351
11
    if (modBits == 384) {
2352
2
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2353
2
    }
2354
9
#endif
2355
9
#ifdef WOLFSSL_SP_521
2356
9
    if (modBits == 521) {
2357
9
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2358
9
    }
2359
0
#endif
2360
0
    return ECC_BAD_ARG_E;
2361
9
#endif
2362
9
}
2363
2364
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2365
                             mp_int* modulus, mp_digit mp)
2366
18
{
2367
18
    if (P == NULL || R == NULL || modulus == NULL)
2368
0
        return ECC_BAD_ARG_E;
2369
2370
18
    if (mp_cmp(P->x, modulus) != MP_LT ||
2371
18
        mp_cmp(P->y, modulus) != MP_LT ||
2372
18
        mp_cmp(P->z, modulus) != MP_LT) {
2373
0
        return ECC_OUT_OF_RANGE_E;
2374
0
    }
2375
2376
18
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2377
18
}
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
763
{
2393
#if !defined(WOLFSSL_SP_MATH)
2394
#ifdef WOLFSSL_SMALL_STACK
2395
   mp_int* t1 = NULL;
2396
   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
   mp_int *x, *y, *z;
2409
   int    err;
2410
2411
   (void)ct;
2412
2413
   if (P == NULL || modulus == NULL)
2414
       return ECC_BAD_ARG_E;
2415
2416
   /* special case for point at infinity */
2417
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2418
       err = mp_set(P->x, 0);
2419
       if (err == MP_OKAY)
2420
           err = mp_set(P->y, 0);
2421
       if (err == MP_OKAY)
2422
           err = mp_set(P->z, 1);
2423
       return err;
2424
   }
2425
2426
#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
   {
2440
       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2441
       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2442
       if (t1 == NULL || t2 == NULL) {
2443
           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2444
           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2445
           return MEMORY_E;
2446
       }
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
   }
2461
#endif /* WOLFSSL_SMALL_STACK */
2462
2463
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
2464
#ifdef WOLFSSL_SMALL_STACK
2465
#ifdef WOLFSSL_SMALL_STACK_CACHE
2466
      if (P->key == NULL)
2467
#endif
2468
      {
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
         XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2475
         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2476
      }
2477
#endif
2478
      return MEMORY_E;
2479
   }
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
   x = P->x;
2504
   y = P->y;
2505
   z = P->z;
2506
#endif
2507
2508
   /* get 1/z */
2509
   if (err == MP_OKAY) {
2510
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2511
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2512
       if (ct) {
2513
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2514
           if (err == MP_OKAY)
2515
               err = mp_montgomery_reduce(t1, modulus, mp);
2516
       }
2517
       else
2518
#endif
2519
       {
2520
           /* first map z back to normal */
2521
           err = mp_montgomery_reduce(z, modulus, mp);
2522
           if (err == MP_OKAY)
2523
               err = mp_invmod(z, modulus, t1);
2524
       }
2525
   }
2526
2527
   /* get 1/z^2 and 1/z^3 */
2528
   if (err == MP_OKAY)
2529
       err = mp_sqr(t1, t2);
2530
   if (err == MP_OKAY)
2531
       err = mp_mod(t2, modulus, t2);
2532
   if (err == MP_OKAY)
2533
       err = mp_mul(t1, t2, t1);
2534
   if (err == MP_OKAY)
2535
       err = mp_mod(t1, modulus, t1);
2536
2537
   /* multiply against x/y */
2538
   if (err == MP_OKAY)
2539
       err = mp_mul(x, t2, x);
2540
   if (err == MP_OKAY)
2541
       err = mp_montgomery_reduce(x, modulus, mp);
2542
   if (err == MP_OKAY)
2543
       err = mp_mul(y, t1, y);
2544
   if (err == MP_OKAY)
2545
       err = mp_montgomery_reduce(y, modulus, mp);
2546
2547
   if (err == MP_OKAY)
2548
       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
   mp_clear(t1);
2564
   mp_clear(t2);
2565
2566
#ifdef WOLFSSL_SMALL_STACK
2567
#ifdef WOLFSSL_SMALL_STACK_CACHE
2568
   if (P->key == NULL)
2569
#endif
2570
   {
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
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
2577
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
2578
   }
2579
#endif
2580
2581
   return err;
2582
#else
2583
763
   if (P == NULL || modulus == NULL)
2584
0
       return ECC_BAD_ARG_E;
2585
2586
763
   (void)mp;
2587
763
   (void)ct;
2588
2589
763
#ifndef WOLFSSL_SP_NO_256
2590
763
   if (mp_count_bits(modulus) == 256) {
2591
264
       return sp_ecc_map_256(P->x, P->y, P->z);
2592
264
   }
2593
499
#endif
2594
499
#ifdef WOLFSSL_SP_384
2595
499
   if (mp_count_bits(modulus) == 384) {
2596
302
       return sp_ecc_map_384(P->x, P->y, P->z);
2597
302
   }
2598
197
#endif
2599
197
#ifdef WOLFSSL_SP_521
2600
197
   if (mp_count_bits(modulus) == 521) {
2601
197
       return sp_ecc_map_521(P->x, P->y, P->z);
2602
197
   }
2603
0
#endif
2604
0
   return ECC_BAD_ARG_E;
2605
197
#endif
2606
197
}
2607
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2608
2609
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2610
763
{
2611
763
    return ecc_map_ex(P, modulus, mp, 0);
2612
763
}
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
{
2774
    int err = MP_OKAY;
2775
#ifdef WOLFSSL_SMALL_STACK
2776
    mp_int*       mu = NULL;
2777
#else
2778
    mp_int        mu[1];
2779
#endif
2780
2781
#ifdef WOLFSSL_SMALL_STACK
2782
    mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
2783
    if (mu == NULL)
2784
        err = MEMORY_E;
2785
#endif
2786
2787
    if (err == MP_OKAY)
2788
        err = mp_init(mu);
2789
    if (err == MP_OKAY)
2790
        err = mp_montgomery_calc_normalization(mu, modulus);
2791
    /* Generate random value to multiply into p->z. */
2792
    if (err == MP_OKAY)
2793
        err = wc_ecc_gen_k(rng, size, ty, modulus);
2794
    /* Convert to montogmery form. */
2795
    if (err == MP_OKAY)
2796
        err = mp_mulmod(ty, mu, modulus, ty);
2797
    /* Multiply random value into p->z. */
2798
    if (err == MP_OKAY)
2799
        err = mp_mul(p->z, ty, p->z);
2800
    if (err == MP_OKAY)
2801
        err = mp_montgomery_reduce(p->z, modulus, mp);
2802
    /* Square random value for X (X' = X / Z^2). */
2803
    if (err == MP_OKAY)
2804
        err = mp_sqr(ty, tx);
2805
    if (err == MP_OKAY)
2806
        err = mp_montgomery_reduce(tx, modulus, mp);
2807
    /* Multiply square of random by random value for Y. */
2808
    if (err == MP_OKAY)
2809
        err = mp_mul(ty, tx, ty);
2810
    if (err == MP_OKAY)
2811
        err = mp_montgomery_reduce(ty, modulus, mp);
2812
    /* Multiply square into X. */
2813
    if (err == MP_OKAY)
2814
        err = mp_mul(p->x, tx, p->x);
2815
    if (err == MP_OKAY)
2816
        err = mp_montgomery_reduce(p->x, modulus, mp);
2817
    /* Multiply cube into Y (Y' = Y / Z^3). */
2818
    if (err == MP_OKAY)
2819
        err = mp_mul(p->y, ty, p->y);
2820
    if (err == MP_OKAY)
2821
        err = mp_montgomery_reduce(p->y, modulus, mp);
2822
2823
#ifdef WOLFSSL_SMALL_STACK
2824
    if (mu != NULL) {
2825
        mp_clear(mu);
2826
        XFREE(mu, NULL, DYNAMIC_TYPE_ECC);
2827
    }
2828
#else
2829
    mp_clear(mu);
2830
#endif
2831
2832
    return err;
2833
}
2834
2835
#ifndef WC_PROTECT_ENCRYPTED_MEM
2836
#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
{
2857
    int      err = MP_OKAY;
2858
    int      bytes = (mp_count_bits(modulus) + 7) / 8;
2859
    int      i;
2860
    int      j = 1;
2861
    int      cnt = DIGIT_BIT;
2862
    int      t = 0;
2863
    mp_digit b;
2864
    mp_digit v = 0;
2865
    mp_int*  kt = R[2]->x;
2866
#ifndef WC_NO_CACHE_RESISTANT
2867
    /* First bit always 1 (fix at end) and swap equals first bit */
2868
    int      swap = 1;
2869
#endif
2870
    int      infinity;
2871
2872
    /* Step 1: R[0] = P; R[1] = P */
2873
    /* R[0] = P */
2874
    if (err == MP_OKAY)
2875
        err = mp_copy(P->x, R[0]->x);
2876
    if (err == MP_OKAY)
2877
        err = mp_copy(P->y, R[0]->y);
2878
    if (err == MP_OKAY)
2879
        err = mp_copy(P->z, R[0]->z);
2880
2881
    /* R[1] = P */
2882
    if (err == MP_OKAY)
2883
        err = mp_copy(P->x, R[1]->x);
2884
    if (err == MP_OKAY)
2885
        err = mp_copy(P->y, R[1]->y);
2886
    if (err == MP_OKAY)
2887
        err = mp_copy(P->z, R[1]->z);
2888
2889
    /* Randomize z ordinates to obfuscate timing. */
2890
    if ((err == MP_OKAY) && (rng != NULL))
2891
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y);
2892
    if ((err == MP_OKAY) && (rng != NULL))
2893
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y);
2894
2895
    if (err == MP_OKAY) {
2896
        /* Order could be one greater than the size of the modulus. */
2897
        t = mp_count_bits(modulus) + 1;
2898
        v = k->dp[0] >> 1;
2899
        if (cnt > t) {
2900
            cnt = t;
2901
        }
2902
        err = mp_copy(k, kt);
2903
    }
2904
    if (err == MP_OKAY) {
2905
        err = mp_grow(kt, modulus->used + 1);
2906
    }
2907
    /* Step 2: for j = 1 to t-1 do */
2908
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
2909
        if (--cnt == 0) {
2910
            v = kt->dp[j++];
2911
            cnt = DIGIT_BIT;
2912
        }
2913
2914
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
2915
        b = v & 1;
2916
        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
        swap ^= b;
2926
        if (err == MP_OKAY)
2927
            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
2928
        if (err == MP_OKAY)
2929
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
2930
        if (err == MP_OKAY)
2931
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
2932
        swap = (int)b;
2933
2934
        if (err == MP_OKAY)
2935
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
2936
        if (err == MP_OKAY) {
2937
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
2938
                                                                 mp, &infinity);
2939
        }
2940
#endif /* WC_NO_CACHE_RESISTANT */
2941
    }
2942
    /* Step 4: end for */
2943
#ifndef WC_NO_CACHE_RESISTANT
2944
    /* Swap back if last bit is 0. */
2945
    swap ^= 1;
2946
    if (err == MP_OKAY)
2947
        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
2948
    if (err == MP_OKAY)
2949
        err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
2950
    if (err == MP_OKAY)
2951
        err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
2952
#endif
2953
2954
    /* Step 5: b = k[0]; R[b] = R[b] - P */
2955
    /* R[2] = -P */
2956
    if (err == MP_OKAY)
2957
        err = mp_copy(P->x, R[2]->x);
2958
    if (err == MP_OKAY)
2959
        err = mp_sub(modulus, P->y, R[2]->y);
2960
    if (err == MP_OKAY)
2961
        err = mp_copy(P->z, R[2]->z);
2962
    /* Subtract point by adding negative. */
2963
    if (err == MP_OKAY) {
2964
        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
        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
2971
        if (err == MP_OKAY)
2972
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
2973
        if (err == MP_OKAY)
2974
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
2975
        if (err == MP_OKAY)
2976
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
2977
                                                                 mp, &infinity);
2978
        /* Swap back if necessary. */
2979
        if (err == MP_OKAY)
2980
            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
2981
        if (err == MP_OKAY)
2982
            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
2983
        if (err == MP_OKAY)
2984
            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
2985
#endif
2986
    }
2987
2988
    /* Step 6: return R[0] */
2989
    if (err == MP_OKAY)
2990
        err = mp_copy(R[0]->x, Q->x);
2991
    if (err == MP_OKAY)
2992
        err = mp_copy(R[0]->y, Q->y);
2993
    if (err == MP_OKAY)
2994
        err = mp_copy(R[0]->z, Q->z);
2995
2996
    return err;
2997
}
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
{
3198
   int err = MP_OKAY;
3199
#ifdef WOLFSSL_SMALL_STACK
3200
   mp_int*       mu = NULL;
3201
#else
3202
   mp_int        mu[1];
3203
#endif
3204
3205
   (void)heap;
3206
3207
#ifdef WOLFSSL_SMALL_STACK
3208
   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3209
   if (mu == NULL)
3210
       err = MEMORY_E;
3211
#endif
3212
   if (err == MP_OKAY)
3213
       err = mp_init(mu);
3214
   if (err == MP_OKAY) {
3215
       err = mp_montgomery_calc_normalization(mu, modulus);
3216
3217
       if (err == MP_OKAY) {
3218
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3219
               err = mp_copy(p->x, r->x);
3220
               if (err == MP_OKAY)
3221
                   err = mp_copy(p->y, r->y);
3222
               if (err == MP_OKAY)
3223
                   err = mp_copy(p->z, r->z);
3224
           }
3225
           else {
3226
               err = mp_mulmod(p->x, mu, modulus, r->x);
3227
               if (err == MP_OKAY)
3228
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3229
               if (err == MP_OKAY)
3230
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3231
           }
3232
       }
3233
3234
       mp_clear(mu);
3235
   }
3236
#ifdef WOLFSSL_SMALL_STACK
3237
   if (mu != NULL)
3238
      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
3239
#endif
3240
   return err;
3241
}
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
{
3309
   ecc_point     *tG, *M[M_POINTS];
3310
#ifdef WOLFSSL_NO_MALLOC
3311
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3312
#endif
3313
   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
   mp_digit      mp;
3318
3319
   /* init variables */
3320
   tG = NULL;
3321
   XMEMSET(M, 0, sizeof(M));
3322
3323
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3324
       err = ECC_BAD_ARG_E;
3325
       goto exit;
3326
   }
3327
3328
   /* k can't have more bits than modulus count plus 1 */
3329
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3330
       err = ECC_OUT_OF_RANGE_E;
3331
       goto exit;
3332
   }
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
  for (i = 0; i < M_POINTS; i++) {
3347
  #ifdef WOLFSSL_NO_MALLOC
3348
      M[i] = &lcl_M[i];
3349
  #endif
3350
      err = wc_ecc_new_point_ex(&M[i], heap);
3351
      if (err != MP_OKAY) {
3352
         goto exit;
3353
      }
3354
#ifdef WOLFSSL_SMALL_STACK_CACHE
3355
      M[i]->key = key;
3356
#endif
3357
  }
3358
3359
   /* make a copy of G in case R==G */
3360
#ifdef WOLFSSL_NO_MALLOC
3361
   tG = &lcl_tG;
3362
#endif
3363
   err = wc_ecc_new_point_ex(&tG, heap);
3364
   if (err != MP_OKAY) {
3365
       goto exit;
3366
   }
3367
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3368
       goto exit;
3369
   }
3370
3371
   /* init montgomery reduction */
3372
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3373
       goto exit;
3374
   }
3375
3376
#ifdef FP_ECC
3377
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3378
#else
3379
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3380
#endif
3381
   /* map R back from projective space */
3382
   if (err == MP_OKAY && map)
3383
       err = ecc_map(R, modulus, mp);
3384
3385
exit:
3386
3387
   /* done */
3388
   wc_ecc_del_point_ex(tG, heap);
3389
   for (i = 0; i < M_POINTS; i++) {
3390
       wc_ecc_del_point_ex(M[i], heap);
3391
   }
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
   return err;
3404
}
3405
#else
3406
751
{
3407
751
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3408
0
       return ECC_BAD_ARG_E;
3409
0
   }
3410
3411
751
   (void)a;
3412
3413
   /* k can't have more bits than modulus count plus 1 */
3414
751
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3415
28
       return ECC_OUT_OF_RANGE_E;
3416
28
   }
3417
723
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3418
723
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3419
723
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3420
55
       return IS_POINT_E;
3421
55
   }
3422
3423
668
#ifdef WOLFSSL_HAVE_SP_ECC
3424
668
#ifndef WOLFSSL_SP_NO_256
3425
668
   if (mp_count_bits(modulus) == 256) {
3426
306
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3427
306
   }
3428
362
#endif
3429
362
#ifdef WOLFSSL_SP_384
3430
362
   if (mp_count_bits(modulus) == 384) {
3431
204
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3432
204
   }
3433
158
#endif
3434
158
#ifdef WOLFSSL_SP_521
3435
158
   if (mp_count_bits(modulus) == 521) {
3436
158
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3437
158
   }
3438
0
#endif
3439
#else
3440
   (void)map;
3441
   (void)map;
3442
   (void)heap;
3443
#endif
3444
0
   return ECC_BAD_ARG_E;
3445
158
}
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
{
3466
   ecc_point     *tG, *M[M_POINTS];
3467
#ifdef WOLFSSL_NO_MALLOC
3468
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3469
#endif
3470
   int           i, err;
3471
#ifdef WOLFSSL_SMALL_STACK_CACHE
3472
   ecc_key       key;
3473
#endif
3474
   mp_digit      mp;
3475
#ifdef ECC_TIMING_RESISTANT
3476
   mp_int t;
3477
#endif
3478
3479
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3480
      return ECC_BAD_ARG_E;
3481
   }
3482
3483
   /* k can't have more bits than order */
3484
   if (mp_count_bits(k) > mp_count_bits(order)) {
3485
      return ECC_OUT_OF_RANGE_E;
3486
   }
3487
3488
   /* init variables */
3489
   tG = NULL;
3490
   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
   for (i = 0; i < M_POINTS; i++) {
3501
   #ifdef WOLFSSL_NO_MALLOC
3502
      M[i] = &lcl_M[i];
3503
   #endif
3504
      err = wc_ecc_new_point_ex(&M[i], heap);
3505
      if (err != MP_OKAY) {
3506
         goto exit;
3507
      }
3508
#ifdef WOLFSSL_SMALL_STACK_CACHE
3509
      M[i]->key = &key;
3510
#endif
3511
  }
3512
3513
   /* make a copy of G in case R==G */
3514
#ifdef WOLFSSL_NO_MALLOC
3515
   tG = &lcl_tG;
3516
#endif
3517
   err = wc_ecc_new_point_ex(&tG, heap);
3518
   if (err != MP_OKAY) {
3519
       goto exit;
3520
   }
3521
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3522
       goto exit;
3523
   }
3524
3525
   /* init montgomery reduction */
3526
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3527
      goto exit;
3528
   }
3529
3530
   /* k can't have more bits than order */
3531
   if (mp_count_bits(k) > mp_count_bits(order)) {
3532
      err = ECC_OUT_OF_RANGE_E;
3533
      goto exit;
3534
   }
3535
3536
3537
#ifdef ECC_TIMING_RESISTANT
3538
   if ((err = mp_init(&t)) != MP_OKAY)
3539
      goto exit;
3540
3541
   if (err == MP_OKAY)
3542
      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
   if (err == MP_OKAY)
3549
      err = mp_sub_d(order, 1, &t);
3550
   if (err == MP_OKAY) {
3551
      int kIsMinusOne = (mp_cmp((mp_int*)k, &t) == MP_EQ);
3552
      err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3553
      if (err == MP_OKAY) {
3554
          err = mp_sub(modulus, tG->y, &t);
3555
      }
3556
      if (err == MP_OKAY) {
3557
          err = mp_cond_copy(&t, kIsMinusOne, R->y);
3558
      }
3559
      if (err == MP_OKAY) {
3560
          err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3561
      }
3562
   }
3563
3564
   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
   if (err == MP_OKAY && map)
3572
      err = ecc_map(R, modulus, mp);
3573
3574
exit:
3575
3576
   /* done */
3577
   wc_ecc_del_point_ex(tG, heap);
3578
   for (i = 0; i < M_POINTS; i++) {
3579
      wc_ecc_del_point_ex(M[i], heap);
3580
   }
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
   return err;
3587
}
3588
#else
3589
0
{
3590
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3591
0
       return ECC_BAD_ARG_E;
3592
0
   }
3593
0
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3594
0
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3595
0
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3596
0
       return IS_POINT_E;
3597
0
   }
3598
3599
0
   (void)a;
3600
0
   (void)order;
3601
0
   (void)rng;
3602
3603
0
#ifdef WOLFSSL_HAVE_SP_ECC
3604
0
#ifndef WOLFSSL_SP_NO_256
3605
0
   if (mp_count_bits(modulus) == 256) {
3606
0
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3607
0
   }
3608
0
#endif
3609
0
#ifdef WOLFSSL_SP_384
3610
0
   if (mp_count_bits(modulus) == 384) {
3611
0
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3612
0
   }
3613
0
#endif
3614
0
#ifdef WOLFSSL_SP_521
3615
0
   if (mp_count_bits(modulus) == 521) {
3616
0
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3617
0
   }
3618
0
#endif
3619
#else
3620
   (void)map;
3621
   (void)heap;
3622
#endif
3623
0
   return ECC_BAD_ARG_E;
3624
0
}
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
8.01k
{
3655
8.01k
   int err = MP_OKAY;
3656
8.01k
   ecc_point* p;
3657
3658
8.01k
   if (point == NULL) {
3659
0
       return BAD_FUNC_ARG;
3660
0
   }
3661
3662
8.01k
   p = *point;
3663
8.01k
#ifndef WOLFSSL_NO_MALLOC
3664
8.01k
   if (p == NULL) {
3665
8.01k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
3666
8.01k
   }
3667
8.01k
#endif
3668
8.01k
   if (p == NULL) {
3669
199
      return MEMORY_E;
3670
199
   }
3671
7.81k
   XMEMSET(p, 0, sizeof(ecc_point));
3672
3673
7.81k
#ifndef ALT_ECC_SIZE
3674
7.81k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
3675
7.81k
   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
7.81k
   *point = p;
3691
7.81k
   (void)heap;
3692
7.81k
   return err;
3693
7.81k
}
3694
ecc_point* wc_ecc_new_point_h(void* heap)
3695
8.01k
{
3696
8.01k
    ecc_point* p = NULL;
3697
8.01k
    (void)wc_ecc_new_point_ex(&p, heap);
3698
8.01k
    return p;
3699
8.01k
}
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
19.8k
{
3712
19.8k
   if (p != NULL) {
3713
7.81k
      mp_clear(p->x);
3714
7.81k
      mp_clear(p->y);
3715
7.81k
      mp_clear(p->z);
3716
7.81k
   #ifndef WOLFSSL_NO_MALLOC
3717
7.81k
      XFREE(p, heap, DYNAMIC_TYPE_ECC);
3718
7.81k
   #endif
3719
7.81k
   }
3720
19.8k
   (void)heap;
3721
19.8k
}
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
19.8k
{
3728
19.8k
    wc_ecc_del_point_ex(p, NULL);
3729
19.8k
}
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
1.66k
{
3747
1.66k
    int ret;
3748
3749
    /* prevents null arguments */
3750
1.66k
    if (p == NULL || r == NULL)
3751
0
        return ECC_BAD_ARG_E;
3752
3753
1.66k
    ret = mp_copy(p->x, r->x);
3754
1.66k
    if (ret != MP_OKAY)
3755
0
        return ret;
3756
1.66k
    ret = mp_copy(p->y, r->y);
3757
1.66k
    if (ret != MP_OKAY)
3758
0
        return ret;
3759
1.66k
    ret = mp_copy(p->z, r->z);
3760
1.66k
    if (ret != MP_OKAY)
3761
0
        return ret;
3762
3763
1.66k
    return MP_OKAY;
3764
1.66k
}
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
834
{
3774
834
    int ret;
3775
3776
    /* prevents null arguments */
3777
834
    if (a == NULL || b == NULL)
3778
0
        return BAD_FUNC_ARG;
3779
3780
834
    ret = mp_cmp(a->x, b->x);
3781
834
    if (ret != MP_EQ)
3782
597
        return ret;
3783
237
    ret = mp_cmp(a->y, b->y);
3784
237
    if (ret != MP_EQ)
3785
148
        return ret;
3786
89
    ret = mp_cmp(a->z, b->z);
3787
89
    if (ret != MP_EQ)
3788
0
        return ret;
3789
3790
89
    return MP_EQ;
3791
89
}
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
7.22k
{
3800
7.22k
   int x;
3801
3802
7.22k
   if (n >= (int)ECC_SET_COUNT)
3803
0
       return 0;
3804
3805
28.9k
   for (x = 0; ecc_sets[x].size != 0; x++)
3806
21.6k
       ;
3807
   /* -1 is a valid index --- indicating that the domain params
3808
      were supplied by the user */
3809
7.22k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
3810
7.22k
      return 1;
3811
7.22k
   }
3812
3813
0
   return 0;
3814
7.22k
}
3815
3816
int wc_ecc_get_curve_idx(int curve_id)
3817
6.84k
{
3818
6.84k
    int curve_idx;
3819
13.1k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
3820
12.7k
        if (curve_id == ecc_sets[curve_idx].id)
3821
6.39k
            break;
3822
12.7k
    }
3823
6.84k
    if (ecc_sets[curve_idx].size == 0) {
3824
450
        return ECC_CURVE_INVALID;
3825
450
    }
3826
6.39k
    return curve_idx;
3827
6.84k
}
3828
3829
int wc_ecc_get_curve_id(int curve_idx)
3830
266
{
3831
266
    if (wc_ecc_is_valid_idx(curve_idx)) {
3832
266
        return ecc_sets[curve_idx].id;
3833
266
    }
3834
0
    return ECC_CURVE_INVALID;
3835
266
}
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
3.31k
{
4160
3.31k
    const ecc_set_type* ecc_set = NULL;
4161
4162
3.31k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4163
3.31k
        ecc_set = &ecc_sets[curve_idx];
4164
3.31k
    }
4165
3.31k
    return ecc_set;
4166
3.31k
}
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
219
{
4226
219
   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
219
   (void)err;
4234
4235
219
   if (private_key == NULL || public_key == NULL || out == NULL ||
4236
219
                                                            outlen == NULL) {
4237
0
       return BAD_FUNC_ARG;
4238
0
   }
4239
4240
219
#ifdef WOLF_CRYPTO_CB
4241
219
    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
219
#endif
4255
4256
219
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
4257
   /* type valid? */
4258
219
   if (private_key->type != ECC_PRIVATEKEY &&
4259
219
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4260
0
      return ECC_BAD_ARG_E;
4261
0
   }
4262
4263
   /* Verify domain params supplied */
4264
219
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4265
219
       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
219
   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
219
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4304
219
#endif /* WOLFSSL_ATECC508A */
4305
219
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
4306
4307
219
   return err;
4308
219
}
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
219
{
4318
219
    int err = MP_OKAY;
4319
219
    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
219
#ifdef WOLFSSL_HAVE_SP_ECC
4352
219
#ifndef WOLFSSL_SP_NO_256
4353
219
    if (private_key->idx != ECC_CUSTOM_IDX &&
4354
219
                               ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4355
173
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4356
173
    }
4357
46
    else
4358
46
#endif
4359
46
#ifdef WOLFSSL_SP_384
4360
46
    if (private_key->idx != ECC_CUSTOM_IDX &&
4361
46
                               ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4362
33
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4363
33
    }
4364
13
    else
4365
13
#endif
4366
13
#ifdef WOLFSSL_SP_521
4367
13
    if (private_key->idx != ECC_CUSTOM_IDX &&
4368
13
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4369
13
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4370
13
    }
4371
0
    else
4372
0
#endif
4373
#else
4374
    (void)point;
4375
    (void)out;
4376
    (void)outlen;
4377
    (void)k;
4378
#endif
4379
0
#if defined(WOLFSSL_SP_MATH)
4380
0
    {
4381
0
        err = WC_KEY_SIZE_E;
4382
0
        goto errout;
4383
0
    }
4384
#else
4385
    {
4386
        ecc_point* result = NULL;
4387
        #ifdef WOLFSSL_NO_MALLOC
4388
        ecc_point  lcl_result;
4389
        #endif
4390
        word32 x = 0;
4391
        mp_digit mp = 0;
4392
        DECLARE_CURVE_SPECS(3);
4393
4394
        /* load curve info */
4395
        ALLOC_CURVE_SPECS(3, err);
4396
        if (err == MP_OKAY) {
4397
            err = wc_ecc_curve_load(private_key->dp, &curve,
4398
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4399
                 ECC_CURVE_FIELD_ORDER));
4400
        }
4401
4402
        if (err != MP_OKAY) {
4403
            FREE_CURVE_SPECS();
4404
            goto errout;
4405
        }
4406
4407
        /* make new point */
4408
    #ifdef WOLFSSL_NO_MALLOC
4409
        result = &lcl_result;
4410
    #endif
4411
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4412
        if (err != MP_OKAY) {
4413
            wc_ecc_curve_free(curve);
4414
            FREE_CURVE_SPECS();
4415
            goto errout;
4416
        }
4417
4418
#ifdef ECC_TIMING_RESISTANT
4419
        if (private_key->rng == NULL) {
4420
            err = MISSING_RNG_E;
4421
        }
4422
#endif
4423
4424
        if (err == MP_OKAY) {
4425
            /* Map in a separate call as this should be constant time */
4426
#ifdef ECC_TIMING_RESISTANT
4427
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4428
                                              curve->order, private_key->rng, 0,
4429
                                              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
        }
4435
        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
            err = mp_montgomery_setup(curve->prime, &mp);
4443
        }
4444
        if (err == MP_OKAY) {
4445
            /* Use constant time map if compiled in */
4446
            err = ecc_map_ex(result, curve->prime, mp, 1);
4447
        }
4448
        if (err == MP_OKAY) {
4449
            x = mp_unsigned_bin_size(curve->prime);
4450
            if (*outlen < x || (int)x < mp_unsigned_bin_size(result->x)) {
4451
                err = BUFFER_E;
4452
            }
4453
        }
4454
4455
        if (err == MP_OKAY) {
4456
            XMEMSET(out, 0, x);
4457
            err = mp_to_unsigned_bin(result->x,out +
4458
                                     (x - mp_unsigned_bin_size(result->x)));
4459
        }
4460
        *outlen = x;
4461
4462
        mp_forcezero(result->x);
4463
        mp_forcezero(result->y);
4464
        wc_ecc_del_point_ex(result, private_key->heap);
4465
4466
        wc_ecc_curve_free(curve);
4467
        FREE_CURVE_SPECS();
4468
    }
4469
#endif
4470
4471
219
  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
219
    return err;
4483
219
}
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
219
{
4575
219
    int err = MP_OKAY;
4576
4577
219
    if (private_key == NULL || point == NULL || out == NULL ||
4578
219
                                                            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
219
    {
4590
219
        err = wc_ecc_shared_secret_gen_sync(private_key, point,
4591
219
            out, outlen);
4592
219
    }
4593
4594
219
    return err;
4595
219
}
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
219
{
4610
219
    int err;
4611
4612
219
    if (private_key == NULL || point == NULL || out == NULL ||
4613
219
                                                            outlen == NULL) {
4614
0
        return BAD_FUNC_ARG;
4615
0
    }
4616
4617
    /* type valid? */
4618
219
    if (private_key->type != ECC_PRIVATEKEY &&
4619
219
            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
219
    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
219
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4631
4632
219
    switch (private_key->state) {
4633
219
        case ECC_STATE_NONE:
4634
219
        case ECC_STATE_SHARED_SEC_GEN:
4635
219
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
4636
4637
219
            err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
4638
219
            if (err < 0) {
4639
20
                break;
4640
20
            }
4641
199
            FALL_THROUGH;
4642
4643
199
        case ECC_STATE_SHARED_SEC_RES:
4644
199
            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
199
            err = 0;
4658
199
            break;
4659
4660
0
        default:
4661
0
            err = BAD_STATE_E;
4662
219
    } /* switch */
4663
4664
219
    RESTORE_VECTOR_REGISTERS();
4665
4666
    /* if async pending then return and skip done cleanup below */
4667
219
    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
219
    private_key->state = ECC_STATE_NONE;
4677
4678
219
    return err;
4679
219
}
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
1.72k
{
4714
1.72k
    int err = MP_OKAY;
4715
1.72k
    DECLARE_CURVE_SPECS(3);
4716
4717
1.72k
    if (p == NULL)
4718
0
        return BAD_FUNC_ARG;
4719
4720
    /* is the IDX valid ?  */
4721
1.72k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
4722
0
       return ECC_BAD_ARG_E;
4723
0
    }
4724
4725
1.72k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4726
4727
1.72k
    ALLOC_CURVE_SPECS(3, err);
4728
1.72k
    if (err == MP_OKAY) {
4729
1.52k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
4730
1.52k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4731
1.52k
                                ECC_CURVE_FIELD_BF);
4732
1.52k
    }
4733
4734
    /* x must be in the range [0, p-1] */
4735
1.72k
    if (err == MP_OKAY) {
4736
1.52k
        if (mp_cmp(p->x, curve->prime) != MP_LT)
4737
47
            err = ECC_OUT_OF_RANGE_E;
4738
1.52k
    }
4739
    /* y must be in the range [0, p-1] */
4740
1.72k
    if (err == MP_OKAY) {
4741
1.48k
        if (mp_cmp(p->y, curve->prime) != MP_LT)
4742
33
            err = ECC_OUT_OF_RANGE_E;
4743
1.48k
    }
4744
    /* z must be 1 */
4745
1.72k
    if (err == MP_OKAY) {
4746
1.44k
        if (!mp_isone(p->z))
4747
0
            err = ECC_BAD_ARG_E;
4748
1.44k
    }
4749
4750
1.72k
    if (err == MP_OKAY) {
4751
1.44k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
4752
1.44k
    }
4753
4754
1.72k
    wc_ecc_curve_free(curve);
4755
1.72k
    FREE_CURVE_SPECS();
4756
4757
1.72k
    RESTORE_VECTOR_REGISTERS();
4758
4759
1.72k
    return err;
4760
1.72k
}
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
8.72k
{
4833
    /* make sure required key variables are reset */
4834
8.72k
    key->state = ECC_STATE_NONE;
4835
8.72k
}
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
3.11k
{
4855
3.11k
    int err = MP_OKAY;
4856
3.11k
#ifdef HAVE_ECC_MAKE_PUB
4857
3.11k
    ecc_point* pub;
4858
3.11k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
4859
3.11k
#endif /* HAVE_ECC_MAKE_PUB */
4860
4861
3.11k
    (void)rng;
4862
4863
3.11k
    if (key == NULL) {
4864
0
        return BAD_FUNC_ARG;
4865
0
    }
4866
4867
3.11k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
4868
4869
3.11k
#ifdef HAVE_ECC_MAKE_PUB
4870
    /* if ecc_point passed in then use it as output for public key point */
4871
3.11k
    if (pubOut != NULL) {
4872
1.72k
        pub = pubOut;
4873
1.72k
    }
4874
1.38k
    else {
4875
        /* caching public key making it a ECC_PRIVATEKEY instead of
4876
           ECC_PRIVATEKEY_ONLY */
4877
1.38k
        pub = &key->pubkey;
4878
1.38k
        key->type = ECC_PRIVATEKEY_ONLY;
4879
1.38k
    }
4880
4881
    /* avoid loading the curve unless it is not passed in */
4882
3.11k
    if (curveIn != NULL) {
4883
0
        curve = curveIn;
4884
0
    }
4885
3.11k
    else {
4886
        /* load curve info */
4887
3.11k
        if (err == MP_OKAY) {
4888
3.11k
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
4889
3.11k
        }
4890
3.11k
        if (err == MP_OKAY) {
4891
3.06k
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
4892
3.06k
        }
4893
3.11k
    }
4894
4895
3.11k
    if ((err == MP_OKAY) && (mp_iszero(&key->k) || mp_isneg(&key->k) ||
4896
3.06k
                                      (mp_cmp(&key->k, curve->order) != MP_LT)))
4897
28
    {
4898
28
        err = ECC_PRIV_KEY_E;
4899
28
    }
4900
4901
3.11k
    if (err == MP_OKAY) {
4902
3.04k
    #ifndef ALT_ECC_SIZE
4903
3.04k
        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
3.04k
    }
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
3.11k
    { /* BEGIN: Software Crypto */
4931
3.11k
#ifdef WOLFSSL_HAVE_SP_ECC
4932
    /* Single-Precision Math (optimized for specific curves) */
4933
3.11k
    if (err != MP_OKAY) {
4934
70
    }
4935
3.04k
    else
4936
3.04k
#ifndef WOLFSSL_SP_NO_256
4937
3.04k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
4938
1.27k
        err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);
4939
1.27k
    }
4940
1.76k
    else
4941
1.76k
#endif
4942
1.76k
#ifdef WOLFSSL_SP_384
4943
1.76k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
4944
827
        err = sp_ecc_mulmod_base_384(&key->k, pub, 1, key->heap);
4945
827
    }
4946
937
    else
4947
937
#endif
4948
937
#ifdef WOLFSSL_SP_521
4949
937
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
4950
937
        err = sp_ecc_mulmod_base_521(&key->k, pub, 1, key->heap);
4951
937
    }
4952
0
    else
4953
0
#endif
4954
0
#endif /* WOLFSSL_HAVE_SP_ECC */
4955
4956
0
#if defined(WOLFSSL_SP_MATH)
4957
0
        err = WC_KEY_SIZE_E;
4958
#else
4959
    if (err == MP_OKAY) {
4960
        /* Multi-Precision Math: compute public curve */
4961
        mp_digit mp = 0;
4962
        ecc_point* base = NULL;
4963
    #ifdef WOLFSSL_NO_MALLOC
4964
        ecc_point  lcl_base;
4965
        base = &lcl_base;
4966
    #endif
4967
        err = wc_ecc_new_point_ex(&base, key->heap);
4968
4969
        /* read in the x/y for this key */
4970
        if (err == MP_OKAY)
4971
            err = mp_copy(curve->Gx, base->x);
4972
        if (err == MP_OKAY)
4973
            err = mp_copy(curve->Gy, base->y);
4974
        if (err == MP_OKAY)
4975
            err = mp_montgomery_setup(curve->prime, &mp);
4976
        if (err == MP_OKAY)
4977
            err = mp_set(base->z, 1);
4978
4979
        /* make the public key */
4980
        if (err == MP_OKAY) {
4981
            /* Map in a separate call as this should be constant time */
4982
            err = wc_ecc_mulmod_ex2(&key->k, base, pub, curve->Af, curve->prime,
4983
                                               curve->order, rng, 0, key->heap);
4984
            if (err == MP_MEM) {
4985
               err = MEMORY_E;
4986
            }
4987
        }
4988
        if (err == MP_OKAY) {
4989
            /* Use constant time map if compiled in */
4990
            err = ecc_map_ex(pub, curve->prime, mp, 1);
4991
        }
4992
4993
        wc_ecc_del_point_ex(base, key->heap);
4994
    }
4995
#endif /* WOLFSSL_SP_MATH */
4996
3.11k
    } /* END: Software Crypto */
4997
4998
3.11k
    if (err != MP_OKAY
4999
    #ifdef WOLFSSL_ASYNC_CRYPT
5000
        && err != WC_PENDING_E
5001
    #endif
5002
3.11k
    ) {
5003
        /* clean up if failed */
5004
129
    #ifndef ALT_ECC_SIZE
5005
129
        mp_clear(pub->x);
5006
129
        mp_clear(pub->y);
5007
129
        mp_clear(pub->z);
5008
129
    #endif
5009
129
    }
5010
5011
    /* free up local curve */
5012
3.11k
    if (curveIn == NULL) {
5013
3.11k
        wc_ecc_curve_free(curve);
5014
3.11k
        FREE_CURVE_SPECS();
5015
3.11k
    }
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
3.11k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5025
1.38k
        key->type = ECC_PRIVATEKEY;
5026
1.38k
    }
5027
5028
3.11k
    RESTORE_VECTOR_REGISTERS();
5029
5030
3.11k
    return err;
5031
3.11k
}
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
1.72k
{
5045
1.72k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5046
5047
1.72k
    return ecc_make_pub_ex(key, NULL, pubOut, NULL);
5048
1.72k
}
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
205
{
5061
205
    WOLFSSL_ENTER("wc_ecc_make_pub");
5062
5063
205
    return ecc_make_pub_ex(key, NULL, pubOut, rng);
5064
205
}
5065
5066
5067
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5068
        int curve_id, int flags)
5069
884
{
5070
884
    int err = 0;
5071
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLFSSL_SP_MATH)
5072
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5073
#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
884
    if (key == NULL || rng == NULL) {
5084
0
        return BAD_FUNC_ARG;
5085
0
    }
5086
5087
    /* make sure required variables are reset */
5088
884
    wc_ecc_reset(key);
5089
5090
884
    err = wc_ecc_set_curve(key, keysize, curve_id);
5091
884
    if (err != 0) {
5092
189
        return err;
5093
189
    }
5094
5095
695
    key->flags = flags;
5096
5097
695
#ifdef WOLF_CRYPTO_CB
5098
695
    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
695
#endif
5114
5115
695
#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
695
#ifdef WOLFSSL_HAVE_SP_ECC
5220
695
#ifndef WOLFSSL_SP_NO_256
5221
695
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5222
238
        err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
5223
238
        if (err == MP_OKAY) {
5224
179
            key->type = ECC_PRIVATEKEY;
5225
179
        }
5226
238
    }
5227
457
    else
5228
457
#endif
5229
457
#ifdef WOLFSSL_SP_384
5230
457
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5231
235
        err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap);
5232
235
        if (err == MP_OKAY) {
5233
176
            key->type = ECC_PRIVATEKEY;
5234
176
        }
5235
235
    }
5236
222
    else
5237
222
#endif
5238
222
#ifdef WOLFSSL_SP_521
5239
222
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5240
222
        err = sp_ecc_make_key_521(rng, &key->k, &key->pubkey, key->heap);
5241
222
        if (err == MP_OKAY) {
5242
174
            key->type = ECC_PRIVATEKEY;
5243
174
        }
5244
222
    }
5245
0
    else
5246
0
#endif
5247
0
#endif /* WOLFSSL_HAVE_SP_ECC */
5248
5249
0
   { /* software key gen */
5250
0
#if defined(WOLFSSL_SP_MATH)
5251
0
        err = WC_KEY_SIZE_E;
5252
#else
5253
5254
        /* setup the key variables */
5255
        err = mp_init(&key->k);
5256
5257
        /* load curve info */
5258
        if (err == MP_OKAY) {
5259
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5260
        }
5261
        if (err == MP_OKAY) {
5262
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5263
        }
5264
5265
        /* generate k */
5266
        if (err == MP_OKAY) {
5267
            err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
5268
        }
5269
5270
        /* generate public key from k */
5271
        if (err == MP_OKAY) {
5272
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5273
        }
5274
5275
        if (err == MP_OKAY
5276
        #ifdef WOLFSSL_ASYNC_CRYPT
5277
            || err == WC_PENDING_E
5278
        #endif
5279
        ) {
5280
            key->type = ECC_PRIVATEKEY;
5281
        }
5282
        else {
5283
            /* cleanup these on failure case only */
5284
            mp_forcezero(&key->k);
5285
        }
5286
5287
        /* cleanup allocations */
5288
        wc_ecc_curve_free(curve);
5289
        FREE_CURVE_SPECS();
5290
#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
695
#endif /* HAVE_ECC_MAKE_PUB */
5305
5306
695
    return err;
5307
695
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5308
695
}
5309
5310
5311
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
5312
                        int flags)
5313
884
{
5314
884
    int err;
5315
5316
884
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5317
5318
884
    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
884
    RESTORE_VECTOR_REGISTERS();
5331
5332
884
    return err;
5333
884
}
5334
5335
WOLFSSL_ABI
5336
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
5337
884
{
5338
884
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
5339
884
}
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
9.42k
{
5402
9.42k
    int devId = INVALID_DEVID;
5403
9.42k
    ecc_key* key;
5404
5405
#ifdef WOLFSSL_QNX_CAAM
5406
    devId = WOLFSSL_CAAM_DEVID;
5407
#endif
5408
9.42k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
5409
9.42k
    if (key) {
5410
8.51k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
5411
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
5412
0
            key = NULL;
5413
0
        }
5414
8.51k
    }
5415
5416
9.42k
    return key;
5417
9.42k
}
5418
5419
5420
WOLFSSL_ABI
5421
void wc_ecc_key_free(ecc_key* key)
5422
27.8k
{
5423
27.8k
    if (key) {
5424
8.51k
        void* heap = key->heap;
5425
5426
8.51k
        wc_ecc_free(key);
5427
8.51k
        ForceZero(key, sizeof(ecc_key));
5428
8.51k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
5429
8.51k
        (void)heap;
5430
8.51k
    }
5431
27.8k
}
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
8.58k
{
5452
8.58k
    int ret = 0;
5453
5454
8.58k
    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
8.58k
    XMEMSET(key, 0, sizeof(ecc_key));
5463
8.58k
    key->state = ECC_STATE_NONE;
5464
5465
8.58k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
5466
8.58k
    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
8.58k
    ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
5489
8.58k
                                                                    NULL, NULL);
5490
8.58k
    if (ret != MP_OKAY) {
5491
0
        return MEMORY_E;
5492
0
    }
5493
8.58k
#endif /* ALT_ECC_SIZE */
5494
8.58k
#endif /* WOLFSSL_ATECC508A */
5495
5496
#ifdef WOLFSSL_HEAP_TEST
5497
    key->heap = (void*)WOLFSSL_HEAP_TEST;
5498
#else
5499
8.58k
    key->heap = heap;
5500
8.58k
#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
8.58k
    return ret;
5521
8.58k
}
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
1.39k
{
5830
1.39k
    int err;
5831
5832
1.39k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
5833
1.39k
#ifdef WOLFSSL_SMALL_STACK
5834
1.39k
    mp_int *r = NULL, *s = NULL;
5835
#else
5836
    mp_int r[1], s[1];
5837
#endif
5838
1.39k
#endif
5839
5840
1.39k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
5841
56
        return ECC_BAD_ARG_E;
5842
56
    }
5843
5844
1.34k
#ifdef WOLF_CRYPTO_CB
5845
1.34k
    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
1.34k
#endif
5859
5860
1.34k
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5861
1.34k
    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
1.34k
#ifdef WOLFSSL_SMALL_STACK
5872
1.34k
    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
5873
1.34k
    if (r == NULL)
5874
10
        return MEMORY_E;
5875
1.33k
    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
5876
1.33k
    if (s == NULL) {
5877
4
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5878
4
        return MEMORY_E;
5879
4
    }
5880
1.32k
#endif
5881
1.32k
    XMEMSET(r, 0, sizeof(mp_int));
5882
1.32k
    XMEMSET(s, 0, sizeof(mp_int));
5883
5884
1.32k
    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
1.32k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
5900
1.32k
#endif
5901
1.32k
    if (err < 0) {
5902
76
        mp_clear(r);
5903
76
        mp_clear(s);
5904
76
    #ifdef WOLFSSL_SMALL_STACK
5905
76
        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
5906
76
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5907
76
    #endif
5908
76
        return err;
5909
76
    }
5910
5911
    /* encoded with DSA header */
5912
1.25k
    err = StoreECC_DSA_Sig(out, outlen, r, s);
5913
5914
    /* cleanup */
5915
1.25k
    mp_clear(r);
5916
1.25k
    mp_clear(s);
5917
5918
1.25k
#ifdef WOLFSSL_SMALL_STACK
5919
1.25k
    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
5920
1.25k
    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
5921
1.25k
#endif
5922
1.25k
#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
1.25k
    return err;
5932
1.32k
}
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
{
6000
    int err = MP_OKAY;
6001
    int loop_check = 0;
6002
#ifdef WOLFSSL_SMALL_STACK
6003
    mp_int* b = NULL;
6004
#else
6005
    mp_int  b[1];
6006
#endif
6007
6008
#ifdef WOLFSSL_SMALL_STACK
6009
    b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
6010
    if (b == NULL)
6011
        err = MEMORY_E;
6012
#endif
6013
6014
    if (err == MP_OKAY) {
6015
        err = mp_init(b);
6016
    }
6017
6018
#ifdef WOLFSSL_CUSTOM_CURVES
6019
    /* if custom curve, apply params to pubkey */
6020
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6021
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6022
    }
6023
#endif
6024
6025
    if (err == MP_OKAY) {
6026
        /* Generate blinding value - non-zero value. */
6027
        do {
6028
            if (++loop_check > 64) {
6029
                 err = RNG_FAILURE_E;
6030
                 break;
6031
            }
6032
6033
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6034
        }
6035
        while (err == MP_ZERO_E);
6036
        loop_check = 0;
6037
    }
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
    for (; err == MP_OKAY;) {
6045
        if (++loop_check > 64) {
6046
             err = RNG_FAILURE_E;
6047
             break;
6048
        }
6049
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6050
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6051
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6052
        if (key->sign_k != NULL) {
6053
            if (loop_check > 1) {
6054
               err = RNG_FAILURE_E;
6055
               break;
6056
            }
6057
6058
            /* use provided sign_k */
6059
            err = mp_copy(key->sign_k, &pubkey->k);
6060
            if (err != MP_OKAY) break;
6061
6062
            /* free sign_k, so only used once */
6063
            mp_forcezero(key->sign_k);
6064
            mp_free(key->sign_k);
6065
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6066
            key->sign_k = NULL;
6067
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6068
            loop_check = 64;
6069
    #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
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6081
        }
6082
        else
6083
#endif
6084
        {
6085
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6086
                    WC_ECC_FLAG_NONE);
6087
        }
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
        if (err != MP_OKAY) break;
6098
6099
        /* find r = x1 mod n */
6100
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
6101
        if (err != MP_OKAY) break;
6102
6103
        if (mp_iszero(r) == MP_NO) {
6104
            mp_int* ep = &pubkey->k;
6105
            mp_int* kp = &pubkey->k;
6106
            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
            err = mp_mulmod(&pubkey->k, b, curve->order, kp);
6113
            if (err != MP_OKAY) break;
6114
6115
            /* k' = 1/k.b
6116
                  = 1/k' */
6117
            err = mp_invmod(kp, curve->order, kp);
6118
            if (err != MP_OKAY) break;
6119
6120
            /* s = x.r */
6121
            err = mp_mulmod(x, r, curve->order, s);
6122
            if (err != MP_OKAY) break;
6123
6124
            /* s = x.r/k.b
6125
                 = k'.s */
6126
            err = mp_mulmod(kp, s, curve->order, s);
6127
            if (err != MP_OKAY) break;
6128
6129
            /* e' = e/k.b
6130
                  = e.k' */
6131
            err = mp_mulmod(kp, e, curve->order, ep);
6132
            if (err != MP_OKAY) break;
6133
6134
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
6135
                 = e' + s */
6136
            err = mp_addmod_ct(ep, s, curve->order, s);
6137
            if (err != MP_OKAY) break;
6138
6139
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
6140
                 = b.s */
6141
            err = mp_mulmod(s, b, curve->order, s);
6142
            if (err != MP_OKAY) break;
6143
6144
            if (mp_iszero(s) == MP_NO) {
6145
                /* sign successful */
6146
                break;
6147
            }
6148
         }
6149
     #ifndef ALT_ECC_SIZE
6150
         mp_clear(pubkey->pubkey.x);
6151
         mp_clear(pubkey->pubkey.y);
6152
         mp_clear(pubkey->pubkey.z);
6153
     #endif
6154
         mp_forcezero(&pubkey->k);
6155
    }
6156
    mp_forcezero(b);
6157
#ifdef WOLFSSL_SMALL_STACK
6158
    XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
6159
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
6160
    mp_memzero_check(b);
6161
#endif
6162
6163
    return err;
6164
}
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
1.32k
{
6179
1.32k
   int    err = 0;
6180
#if !defined(WOLFSSL_SP_MATH)
6181
   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
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6188
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6189
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
6190
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
6191
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
6192
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6193
#else
6194
   DECLARE_CURVE_SPECS(1);
6195
#endif
6196
#endif /* !WOLFSSL_SP_MATH */
6197
6198
1.32k
   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
1.32k
   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
1.32k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
6209
0
      return ECC_BAD_ARG_E;
6210
0
   }
6211
6212
1.32k
#if defined(WOLFSSL_SP_MATH)
6213
1.32k
    if (key->idx == ECC_CUSTOM_IDX || (1
6214
1.32k
    #ifndef WOLFSSL_SP_NO_256
6215
1.32k
         && ecc_sets[key->idx].id != ECC_SECP256R1
6216
1.32k
    #endif
6217
1.32k
    #ifdef WOLFSSL_SP_384
6218
1.32k
         && ecc_sets[key->idx].id != ECC_SECP384R1
6219
1.32k
    #endif
6220
1.32k
    #ifdef WOLFSSL_SP_521
6221
1.32k
         && ecc_sets[key->idx].id != ECC_SECP521R1
6222
1.32k
    #endif
6223
1.32k
        )) {
6224
0
        return WC_KEY_SIZE_E;
6225
0
    }
6226
1.32k
#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
1.32k
#if defined(WOLFSSL_HAVE_SP_ECC)
6240
1.32k
    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
1.32k
    ) {
6245
1.32k
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
6246
1.32k
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6247
1.32k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6248
1.32k
        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
1.32k
    #ifndef WOLFSSL_SP_NO_256
6258
1.32k
        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
503
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6273
503
            {
6274
503
                int ret;
6275
503
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6276
503
                ret = sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, sign_k,
6277
503
                                      key->heap);
6278
503
                RESTORE_VECTOR_REGISTERS();
6279
503
                return ret;
6280
503
            }
6281
503
        #endif
6282
503
        }
6283
824
    #endif
6284
824
    #ifdef WOLFSSL_SP_384
6285
824
        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
389
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6300
389
            {
6301
389
                int ret;
6302
389
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6303
389
                ret = sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, sign_k,
6304
389
                                      key->heap);
6305
389
                RESTORE_VECTOR_REGISTERS();
6306
389
                return ret;
6307
389
            }
6308
389
        #endif
6309
389
        }
6310
435
    #endif
6311
435
    #ifdef WOLFSSL_SP_521
6312
435
        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
435
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
6327
435
            {
6328
435
                int ret;
6329
435
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
6330
435
                ret = sp_ecc_sign_521(in, inlen, rng, &key->k, r, s, sign_k,
6331
435
                                      key->heap);
6332
435
                RESTORE_VECTOR_REGISTERS();
6333
435
                return ret;
6334
435
            }
6335
435
        #endif
6336
435
        }
6337
0
    #endif
6338
0
        (void)sign_k;
6339
0
    }
6340
#else
6341
   (void)inlen;
6342
#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
#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
   e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
6373
   if (e == NULL) {
6374
      return MEMORY_E;
6375
   }
6376
#endif
6377
6378
   /* get the hash and load it as a bignum into 'e' */
6379
   /* init the bignums */
6380
   if ((err = mp_init(e)) != MP_OKAY) {
6381
   #ifdef WOLFSSL_SMALL_STACK
6382
      XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
6383
   #endif
6384
      return err;
6385
   }
6386
6387
   /* load curve info */
6388
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6389
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6390
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6391
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6392
    if (err == MP_OKAY)
6393
        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
   if (err == MP_OKAY) {
6413
       /* we may need to truncate if hash is longer than key size */
6414
       word32 orderBits = mp_count_bits(curve->order);
6415
6416
       /* truncate down to byte size, may be all that's needed */
6417
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
6418
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6419
       err = mp_read_unsigned_bin(e, in, inlen);
6420
6421
       /* may still need bit truncation too */
6422
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
6423
           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
6424
   }
6425
6426
   /* make up a key and export the public copy */
6427
   if (err == MP_OKAY) {
6428
   #ifdef WOLFSSL_SMALL_STACK
6429
       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
   #ifdef WOLFSSL_SMALL_STACK
6509
       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
6510
       if (pubkey == NULL)
6511
           err = MEMORY_E;
6512
   #endif
6513
6514
       /* don't use async for key, since we don't support async return here */
6515
       if (err == MP_OKAY) {
6516
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
6517
           if (err == MP_OKAY) {
6518
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
6519
              wc_ecc_free(pubkey);
6520
           #ifdef WOLFSSL_SMALL_STACK
6521
              XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
6522
           #endif
6523
           }
6524
       }
6525
   }
6526
6527
   mp_clear(e);
6528
   wc_ecc_curve_free(curve);
6529
#ifdef WOLFSSL_SMALL_STACK
6530
   XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
6531
#endif
6532
   FREE_CURVE_SPECS();
6533
#endif /* !WOLFSSL_SP_MATH */
6534
6535
0
   return err;
6536
1.32k
}
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
591
{
6844
591
    int ret = MP_OKAY;
6845
591
    DECLARE_CURVE_SPECS(1);
6846
6847
591
    if (k == NULL || klen == 0 || key == NULL) {
6848
0
        return BAD_FUNC_ARG;
6849
0
    }
6850
6851
591
    ALLOC_CURVE_SPECS(1, ret);
6852
591
    if (ret == MP_OKAY) {
6853
588
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6854
588
    }
6855
6856
591
    if (ret != 0) {
6857
3
        FREE_CURVE_SPECS();
6858
3
        return ret;
6859
3
    }
6860
6861
588
    if (key->sign_k == NULL) {
6862
588
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6863
588
                                                            DYNAMIC_TYPE_ECC);
6864
588
        if (key->sign_k) {
6865
585
            ret = mp_init(key->sign_k);
6866
585
        }
6867
3
        else {
6868
3
            ret = MEMORY_E;
6869
3
        }
6870
588
    }
6871
6872
588
    if (ret == 0) {
6873
585
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
6874
585
    }
6875
588
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
6876
16
        ret = MP_VAL;
6877
16
    }
6878
6879
588
    wc_ecc_curve_free(curve);
6880
588
    FREE_CURVE_SPECS();
6881
588
    return ret;
6882
591
}
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
{
6891
#ifndef WOLFSSL_ECC_CURVE_STATIC
6892
    if (curve->prime != NULL)
6893
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
6894
    if (curve->Af != NULL)
6895
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
6896
    if (curve->Bf != NULL)
6897
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
6898
    if (curve->order != NULL)
6899
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
6900
    if (curve->Gx != NULL)
6901
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
6902
    if (curve->Gy != NULL)
6903
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
6904
#endif
6905
6906
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
6907
6908
    (void)heap;
6909
}
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
8.58k
{
6919
8.58k
    if (key == NULL) {
6920
0
        return 0;
6921
0
    }
6922
6923
8.58k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
6924
8.58k
    if (key->sign_k != NULL) {
6925
585
        mp_forcezero(key->sign_k);
6926
585
        mp_free(key->sign_k);
6927
585
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6928
585
    }
6929
8.58k
#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
8.58k
    mp_clear(key->pubkey.x);
6960
8.58k
    mp_clear(key->pubkey.y);
6961
8.58k
    mp_clear(key->pubkey.z);
6962
6963
8.58k
    mp_forcezero(&key->k);
6964
6965
#ifdef WOLFSSL_CUSTOM_CURVES
6966
    if (key->deallocSet && key->dp != NULL)
6967
        wc_ecc_free_curve(key->dp, key->heap);
6968
#endif
6969
6970
#ifdef WOLFSSL_CHECK_MEM_ZERO
6971
    wc_MemZero_Check(key, sizeof(ecc_key));
6972
#endif
6973
6974
8.58k
    return 0;
6975
8.58k
}
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
{
7005
    int err;
7006
7007
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
7008
        /* A is infinity. */
7009
        err = wc_ecc_copy_point(B, R);
7010
    }
7011
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
7012
        /* B is infinity. */
7013
        err = wc_ecc_copy_point(A, R);
7014
    }
7015
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
7016
        /* x ordinattes the same. */
7017
        if (mp_cmp(A->y, B->y) == MP_EQ) {
7018
            /* A = B */
7019
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
7020
        }
7021
        else {
7022
            /* A = -B */
7023
            err = mp_set(R->x, 0);
7024
            if (err == MP_OKAY)
7025
                err = mp_set(R->y, 0);
7026
            if (err == MP_OKAY)
7027
                err = mp_set(R->z, 1);
7028
            if ((err == MP_OKAY) && (infinity != NULL))
7029
                *infinity = 1;
7030
        }
7031
    }
7032
    else {
7033
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
7034
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
7035
            /* When all zero then should have done a double */
7036
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
7037
                if (mp_iszero(B->z)) {
7038
                    err = wc_ecc_copy_point(B, R);
7039
                    if (err == MP_OKAY) {
7040
                        err = mp_montgomery_calc_normalization(R->z, modulus);
7041
                    }
7042
                    if (err == MP_OKAY) {
7043
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
7044
                    }
7045
                }
7046
                else {
7047
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
7048
                }
7049
            }
7050
            /* When only Z zero then result is infinity */
7051
            else {
7052
                err = mp_set(R->x, 0);
7053
                if (err == MP_OKAY)
7054
                    err = mp_set(R->y, 0);
7055
                if (err == MP_OKAY)
7056
                    err = mp_set(R->z, 1);
7057
                if ((err == MP_OKAY) && (infinity != NULL))
7058
                    *infinity = 1;
7059
            }
7060
        }
7061
    }
7062
7063
    return err;
7064
}
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
{
7074
    int err;
7075
7076
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
7077
        /* P is infinity. */
7078
        err = wc_ecc_copy_point(P, R);
7079
    }
7080
    else {
7081
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
7082
    }
7083
7084
    return err;
7085
}
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
{
7116
#ifdef WOLFSSL_SMALL_STACK_CACHE
7117
  ecc_key        *key = NULL;
7118
#endif
7119
#ifdef WOLFSSL_SMALL_STACK
7120
  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
  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
  unsigned char* tA = NULL;
7133
  unsigned char* tB = NULL;
7134
#endif
7135
  int            err = MP_OKAY, first, x, y;
7136
  mp_digit       mp = 0;
7137
7138
  /* argchks */
7139
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
7140
                                                         modulus == NULL) {
7141
     return ECC_BAD_ARG_E;
7142
  }
7143
7144
#ifndef WOLFSSL_NO_MALLOC
7145
  /* allocate memory */
7146
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7147
  if (tA == NULL) {
7148
     return GEN_MEM_ERR;
7149
  }
7150
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7151
  if (tB == NULL) {
7152
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7153
     return GEN_MEM_ERR;
7154
  }
7155
#endif
7156
7157
#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
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
7167
                                                       DYNAMIC_TYPE_ECC_BUFFER);
7168
  if (precomp == NULL) {
7169
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7170
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
7171
  #ifdef WOLFSSL_SMALL_STACK_CACHE
7172
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
7173
  #endif
7174
     return GEN_MEM_ERR;
7175
  }
7176
#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
  XMEMSET(tA, 0, ECC_BUFSIZE);
7209
  XMEMSET(tB, 0, ECC_BUFSIZE);
7210
#ifndef WOLFSSL_SMALL_STACK
7211
  XMEMSET(precomp, 0, sizeof(precomp));
7212
#else
7213
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
7214
#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
  lenA = mp_unsigned_bin_size(kA);
7222
  lenB = mp_unsigned_bin_size(kB);
7223
  len  = MAX(lenA, lenB);
7224
7225
  /* sanity check */
7226
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
7227
    err = BAD_FUNC_ARG;
7228
  }
7229
7230
  if (err == MP_OKAY) {
7231
    /* extract and justify kA */
7232
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
7233
7234
    /* extract and justify kB */
7235
    if (err == MP_OKAY)
7236
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
7237
7238
    /* allocate the table */
7239
    if (err == MP_OKAY) {
7240
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
7241
        #ifdef WOLFSSL_NO_MALLOC
7242
            precomp[x] = &lcl_precomp[x];
7243
        #endif
7244
            err = wc_ecc_new_point_ex(&precomp[x], heap);
7245
            if (err != MP_OKAY)
7246
                break;
7247
        #ifdef WOLFSSL_SMALL_STACK_CACHE
7248
            precomp[x]->key = key;
7249
        #endif
7250
        }
7251
    }
7252
  }
7253
7254
  if (err == MP_OKAY)
7255
    /* init montgomery reduction */
7256
    err = mp_montgomery_setup(modulus, &mp);
7257
7258
  if (err == MP_OKAY) {
7259
  #ifdef WOLFSSL_SMALL_STACK
7260
    mp_int* mu;
7261
  #else
7262
    mp_int  mu[1];
7263
  #endif
7264
  #ifdef WOLFSSL_SMALL_STACK
7265
    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
7266
    if (mu == NULL)
7267
        err = MEMORY_E;
7268
  #endif
7269
    if (err == MP_OKAY) {
7270
        err = mp_init(mu);
7271
    }
7272
    if (err == MP_OKAY) {
7273
      err = mp_montgomery_calc_normalization(mu, modulus);
7274
7275
      if (err == MP_OKAY)
7276
        /* copy ones ... */
7277
        err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
7278
7279
      if (err == MP_OKAY)
7280
        err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
7281
      if (err == MP_OKAY)
7282
        err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
7283
7284
      if (err == MP_OKAY)
7285
        err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
7286
      if (err == MP_OKAY)
7287
        err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
7288
      if (err == MP_OKAY)
7289
        err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
7290
7291
      /* done with mu */
7292
      mp_clear(mu);
7293
    }
7294
  #ifdef WOLFSSL_SMALL_STACK
7295
    if (mu != NULL) {
7296
      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
7297
    }
7298
  #endif
7299
  }
7300
7301
  if (err == MP_OKAY) {
7302
    /* precomp [i,0](A + B) table */
7303
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
7304
  }
7305
  if (err == MP_OKAY) {
7306
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
7307
                                                          a, modulus, mp, NULL);
7308
  }
7309
7310
  if (err == MP_OKAY) {
7311
    /* precomp [0,i](A + B) table */
7312
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
7313
  }
7314
  if (err == MP_OKAY) {
7315
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
7316
                                                             modulus, mp, NULL);
7317
  }
7318
7319
  if (err == MP_OKAY) {
7320
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
7321
    for (x = 1; x < 4; x++) {
7322
      for (y = 1; y < 4; y++) {
7323
        if (err == MP_OKAY) {
7324
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
7325
                                                  precomp[x+(y<<2)], a, modulus,
7326
                                                  mp, NULL);
7327
        }
7328
      }
7329
    }
7330
  }
7331
7332
  if (err == MP_OKAY) {
7333
    nibble  = 3;
7334
    first   = 1;
7335
    bitbufA = tA[0];
7336
    bitbufB = tB[0];
7337
7338
    /* for every byte of the multiplicands */
7339
    for (x = 0; x < (int)len || nibble != 3; ) {
7340
        /* grab a nibble */
7341
        if (++nibble == 4) {
7342
            if (x == (int)len) break;
7343
            bitbufA = tA[x];
7344
            bitbufB = tB[x];
7345
            nibble  = 0;
7346
            x++;
7347
        }
7348
7349
        /* extract two bits from both, shift/update */
7350
        nA = (bitbufA >> 6) & 0x03;
7351
        nB = (bitbufB >> 6) & 0x03;
7352
        bitbufA = (bitbufA << 2) & 0xFF;
7353
        bitbufB = (bitbufB << 2) & 0xFF;
7354
7355
        /* if both zero, if first, continue */
7356
        if ((nA == 0) && (nB == 0) && (first == 1)) {
7357
            continue;
7358
        }
7359
7360
        /* double twice, only if this isn't the first */
7361
        if (first == 0) {
7362
            /* double twice */
7363
            if (err == MP_OKAY)
7364
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
7365
            if (err == MP_OKAY)
7366
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
7367
            else
7368
                break;
7369
        }
7370
7371
        /* if not both zero */
7372
        if ((nA != 0) || (nB != 0)) {
7373
            int i = nA + (nB<<2);
7374
            if (first == 1) {
7375
                /* if first, copy from table */
7376
                first = 0;
7377
                if (err == MP_OKAY)
7378
                    err = mp_copy(precomp[i]->x, C->x);
7379
7380
                if (err == MP_OKAY)
7381
                    err = mp_copy(precomp[i]->y, C->y);
7382
7383
                if (err == MP_OKAY)
7384
                    err = mp_copy(precomp[i]->z, C->z);
7385
                else
7386
                    break;
7387
            } else {
7388
                /* if not first, add from table */
7389
                if (err == MP_OKAY)
7390
                    err = ecc_projective_add_point_safe(C, precomp[i],
7391
                                                        C, a, modulus, mp,
7392
                                                        &first);
7393
                if (err != MP_OKAY)
7394
                    break;
7395
            }
7396
        }
7397
    }
7398
  }
7399
7400
  /* reduce to affine */
7401
  if (err == MP_OKAY)
7402
    err = ecc_map(C, modulus, mp);
7403
7404
  /* clean up */
7405
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
7406
     wc_ecc_del_point_ex(precomp[x], heap);
7407
  }
7408
7409
  ForceZero(tA, ECC_BUFSIZE);
7410
  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
#ifdef WOLFSSL_SMALL_STACK
7423
  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
7424
#endif
7425
#ifndef WOLFSSL_NO_MALLOC
7426
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
7427
  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
  return err;
7433
}
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
2.54k
{
7466
2.54k
    int err;
7467
7468
2.54k
    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
2.54k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
7478
11
        return ECC_BAD_ARG_E;
7479
11
    }
7480
7481
2.53k
#ifdef WOLF_CRYPTO_CB
7482
2.53k
    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
2.53k
#endif
7496
7497
2.53k
#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
2.53k
    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7511
2.53k
    if (r == NULL)
7512
12
        return MEMORY_E;
7513
2.52k
    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7514
2.52k
    if (s == NULL) {
7515
14
        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7516
14
        return MEMORY_E;
7517
14
    }
7518
2.50k
    #endif
7519
2.50k
    XMEMSET(r, 0, sizeof(mp_int));
7520
2.50k
    XMEMSET(s, 0, sizeof(mp_int));
7521
2.50k
#endif /* WOLFSSL_ASYNC_CRYPT */
7522
7523
2.50k
    switch (key->state) {
7524
2.50k
        case ECC_STATE_NONE:
7525
2.50k
        case ECC_STATE_VERIFY_DECODE:
7526
2.50k
            key->state = ECC_STATE_VERIFY_DECODE;
7527
7528
            /* default to invalid signature */
7529
2.50k
            *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
2.50k
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
7537
2.50k
            if (err < 0) {
7538
8
                break;
7539
8
            }
7540
2.50k
            FALL_THROUGH;
7541
7542
2.50k
        case ECC_STATE_VERIFY_DO:
7543
2.50k
            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
2.50k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
7550
7551
2.50k
        #ifndef WOLFSSL_ASYNC_CRYPT
7552
            /* done with R/S */
7553
2.50k
            mp_clear(r);
7554
2.50k
            mp_clear(s);
7555
2.50k
        #ifdef WOLFSSL_SMALL_STACK
7556
2.50k
            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
7557
2.50k
            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7558
2.50k
            r = NULL;
7559
2.50k
            s = NULL;
7560
2.50k
        #endif
7561
2.50k
        #endif
7562
7563
2.50k
            if (err < 0) {
7564
129
                break;
7565
129
            }
7566
2.37k
            FALL_THROUGH;
7567
7568
2.37k
        case ECC_STATE_VERIFY_RES:
7569
2.37k
            key->state = ECC_STATE_VERIFY_RES;
7570
2.37k
            err = 0;
7571
2.37k
            break;
7572
7573
0
        default:
7574
0
            err = BAD_STATE_E;
7575
2.50k
    }
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
2.50k
    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
7591
2.50k
    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
7592
2.50k
    r = NULL;
7593
2.50k
    s = NULL;
7594
2.50k
#endif
7595
7596
    /* make sure required variables are reset */
7597
2.50k
    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
2.50k
    return err;
7611
2.50k
}
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
2.50k
{
7618
2.50k
    int err = MP_OKAY;
7619
2.50k
    DECLARE_CURVE_SPECS(1);
7620
7621
2.50k
    ALLOC_CURVE_SPECS(1, err);
7622
2.50k
    if (err == MP_OKAY) {
7623
2.48k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7624
2.48k
    }
7625
2.50k
    if (err != 0) {
7626
14
        FREE_CURVE_SPECS();
7627
14
        return err;
7628
14
    }
7629
7630
2.48k
    if (mp_iszero(r) || mp_iszero(s)) {
7631
0
        err = MP_ZERO_E;
7632
0
    }
7633
2.48k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
7634
11
        err = MP_VAL;
7635
11
    }
7636
2.48k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
7637
12
        err = MP_VAL;
7638
12
    }
7639
7640
2.48k
    wc_ecc_curve_free(curve);
7641
2.48k
    FREE_CURVE_SPECS();
7642
2.48k
    return err;
7643
2.50k
}
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
2.50k
{
7670
2.50k
   int           err;
7671
2.50k
   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
   int          did_init = 0;
7687
   ecc_point    *mG = NULL, *mQ = NULL;
7688
   #ifdef WOLFSSL_NO_MALLOC
7689
   ecc_point    lcl_mG, lcl_mQ;
7690
   #endif
7691
   #ifdef WOLFSSL_SMALL_STACK
7692
   mp_int*       v = NULL;
7693
   mp_int*       w = NULL;
7694
   mp_int*       u1 = NULL;
7695
   mp_int*       u2 = NULL;
7696
      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7697
   mp_int*       e_lcl = NULL;
7698
      #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
   mp_int*       e;
7709
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7710
#endif
7711
7712
2.50k
   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
2.50k
   *res = 0;
7717
7718
   /* is the IDX valid ?  */
7719
2.50k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7720
0
      return ECC_BAD_ARG_E;
7721
0
   }
7722
7723
2.50k
   err = wc_ecc_check_r_s_range(key, r, s);
7724
2.50k
   if (err != MP_OKAY) {
7725
37
      return err;
7726
37
   }
7727
7728
2.46k
   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
2.46k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
7812
1.18k
      WOLFSSL_MSG("Verify called with private key, generating public part");
7813
1.18k
      err = ecc_make_pub_ex(key, NULL, NULL, NULL);
7814
1.18k
      if (err != MP_OKAY) {
7815
22
           WOLFSSL_MSG("Unable to extract public key");
7816
22
           return err;
7817
22
      }
7818
1.18k
  }
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
2.44k
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
7832
2.44k
    if (key->idx == ECC_CUSTOM_IDX || (1
7833
2.44k
    #ifndef WOLFSSL_SP_NO_256
7834
2.44k
         && ecc_sets[key->idx].id != ECC_SECP256R1
7835
2.44k
    #endif
7836
2.44k
    #ifdef WOLFSSL_SP_384
7837
2.44k
         && ecc_sets[key->idx].id != ECC_SECP384R1
7838
2.44k
    #endif
7839
2.44k
    #ifdef WOLFSSL_SP_521
7840
2.44k
         && ecc_sets[key->idx].id != ECC_SECP521R1
7841
2.44k
    #endif
7842
2.44k
        )) {
7843
0
        return WC_KEY_SIZE_E;
7844
0
    }
7845
2.44k
#endif
7846
7847
2.44k
#if defined(WOLFSSL_HAVE_SP_ECC)
7848
2.44k
    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
2.44k
    ) {
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
2.44k
    #ifndef WOLFSSL_SP_NO_256
7860
2.44k
        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
885
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7877
885
            {
7878
885
                int ret;
7879
885
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7880
885
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
7881
885
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7882
885
                RESTORE_VECTOR_REGISTERS();
7883
885
                return ret;
7884
885
            }
7885
885
        #endif
7886
885
        }
7887
1.55k
    #endif
7888
1.55k
    #ifdef WOLFSSL_SP_384
7889
1.55k
        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
712
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7906
712
            {
7907
712
                int ret;
7908
712
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7909
712
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
7910
712
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7911
712
                RESTORE_VECTOR_REGISTERS();
7912
712
                return ret;
7913
712
            }
7914
712
        #endif
7915
712
        }
7916
844
    #endif
7917
844
    #ifdef WOLFSSL_SP_521
7918
844
        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
844
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7935
844
            {
7936
844
                int ret;
7937
844
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7938
844
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
7939
844
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
7940
844
                RESTORE_VECTOR_REGISTERS();
7941
844
                return ret;
7942
844
            }
7943
844
        #endif
7944
844
        }
7945
844
    #endif
7946
844
    }
7947
0
#endif
7948
7949
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
7950
   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7951
   if (err != 0) {
7952
      return err;
7953
   }
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
#ifdef WOLFSSL_SMALL_STACK
7964
   e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
7965
   if (e_lcl == NULL) {
7966
       FREE_CURVE_SPECS();
7967
       return MEMORY_E;
7968
   }
7969
#endif
7970
   e = e_lcl;
7971
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
7972
7973
   err = mp_init(e);
7974
   if (err != MP_OKAY) {
7975
      FREE_CURVE_SPECS();
7976
      return MEMORY_E;
7977
   }
7978
7979
   /* read in the specs for this curve */
7980
   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7981
7982
   /* read hash */
7983
   if (err == MP_OKAY) {
7984
       /* we may need to truncate if hash is longer than key size */
7985
       unsigned int orderBits = mp_count_bits(curve->order);
7986
7987
       /* truncate down to byte size, may be all that's needed */
7988
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
7989
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7990
       err = mp_read_unsigned_bin(e, hash, hashlen);
7991
7992
       /* may still need bit truncation too */
7993
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
7994
           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
7995
   }
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
#ifdef WOLFSSL_SMALL_STACK
8035
   if (err == MP_OKAY) {
8036
       v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8037
       if (v == NULL)
8038
           err = MEMORY_E;
8039
   }
8040
   if (err == MP_OKAY) {
8041
       w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8042
       if (w == NULL)
8043
           err = MEMORY_E;
8044
   }
8045
   if (err == MP_OKAY) {
8046
       u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8047
       if (u1 == NULL)
8048
           err = MEMORY_E;
8049
   }
8050
   if (err == MP_OKAY) {
8051
       u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8052
       if (u2 == NULL)
8053
           err = MEMORY_E;
8054
   }
8055
#endif
8056
8057
   /* allocate ints */
8058
   if (err == MP_OKAY) {
8059
       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
8060
          err = MEMORY_E;
8061
       } else {
8062
           did_init = 1;
8063
       }
8064
   }
8065
8066
   /* allocate points */
8067
   if (err == MP_OKAY) {
8068
   #ifdef WOLFSSL_NO_MALLOC
8069
       mG = &lcl_mG;
8070
   #endif
8071
       err = wc_ecc_new_point_ex(&mG, key->heap);
8072
   }
8073
   if (err == MP_OKAY) {
8074
   #ifdef WOLFSSL_NO_MALLOC
8075
       mQ = &lcl_mQ;
8076
   #endif
8077
       err = wc_ecc_new_point_ex(&mQ, key->heap);
8078
   }
8079
8080
   /*  w  = s^-1 mod n */
8081
   if (err == MP_OKAY)
8082
       err = mp_invmod(s, curve->order, w);
8083
8084
   /* u1 = ew */
8085
   if (err == MP_OKAY)
8086
       err = mp_mulmod(e, w, curve->order, u1);
8087
8088
   /* u2 = rw */
8089
   if (err == MP_OKAY)
8090
       err = mp_mulmod(r, w, curve->order, u2);
8091
8092
   /* find mG and mQ */
8093
   if (err == MP_OKAY)
8094
       err = mp_copy(curve->Gx, mG->x);
8095
   if (err == MP_OKAY)
8096
       err = mp_copy(curve->Gy, mG->y);
8097
   if (err == MP_OKAY)
8098
       err = mp_set(mG->z, 1);
8099
8100
   if (err == MP_OKAY)
8101
       err = mp_copy(key->pubkey.x, mQ->x);
8102
   if (err == MP_OKAY)
8103
       err = mp_copy(key->pubkey.y, mQ->y);
8104
   if (err == MP_OKAY)
8105
       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
    if (err == MP_OKAY) {
8155
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
8156
                                                                     key->heap);
8157
    }
8158
#endif /* ECC_SHAMIR */
8159
#endif /* FREESCALE_LTC_ECC */
8160
   /* v = X_x1 mod n */
8161
   if (err == MP_OKAY)
8162
       err = mp_mod(mG->x, curve->order, v);
8163
8164
   /* does v == r */
8165
   if (err == MP_OKAY) {
8166
       if (mp_cmp(v, r) == MP_EQ)
8167
           *res = 1;
8168
   }
8169
8170
   /* cleanup */
8171
   wc_ecc_del_point_ex(mG, key->heap);
8172
   wc_ecc_del_point_ex(mQ, key->heap);
8173
8174
   mp_clear(e);
8175
   if (did_init) {
8176
       mp_clear(v);
8177
       mp_clear(w);
8178
       mp_clear(u1);
8179
       mp_clear(u2);
8180
   }
8181
#ifdef WOLFSSL_SMALL_STACK
8182
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
8183
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
8184
   XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
8185
   XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
8186
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8187
   XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8188
#endif
8189
#endif
8190
8191
   wc_ecc_curve_free(curve);
8192
   FREE_CURVE_SPECS();
8193
8194
#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
2.44k
}
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
58
{
8213
58
    int err = 0;
8214
58
#ifdef HAVE_COMP_KEY
8215
58
    int compressed = 0;
8216
58
#endif
8217
58
    int keysize;
8218
58
    byte pointType;
8219
8220
#ifndef HAVE_COMP_KEY
8221
    (void)shortKeySize;
8222
#endif
8223
8224
58
    if (in == NULL || point == NULL || (curve_idx < 0) ||
8225
58
        (wc_ecc_is_valid_idx(curve_idx) == 0))
8226
0
        return ECC_BAD_ARG_E;
8227
8228
    /* must be odd */
8229
58
    if ((inLen & 1) == 0) {
8230
0
        return ECC_BAD_ARG_E;
8231
0
    }
8232
8233
    /* clear if previously allocated */
8234
58
    mp_clear(point->x);
8235
58
    mp_clear(point->y);
8236
58
    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
58
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
8248
58
#endif
8249
58
    if (err != MP_OKAY)
8250
0
        return MEMORY_E;
8251
8252
58
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
8253
8254
    /* check for point type (4, 2, or 3) */
8255
58
    pointType = in[0];
8256
58
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
8257
58
                                         pointType != ECC_POINT_COMP_ODD) {
8258
0
        err = ASN_PARSE_E;
8259
0
    }
8260
8261
58
    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
58
    inLen -= 1;
8271
58
    in += 1;
8272
8273
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
8274
     * is true */
8275
58
#ifdef HAVE_COMP_KEY
8276
58
    keysize = compressed && !shortKeySize ? inLen : inLen>>1;
8277
#else
8278
    keysize = inLen>>1;
8279
#endif
8280
8281
    /* read data */
8282
58
    if (err == MP_OKAY)
8283
58
        err = mp_read_unsigned_bin(point->x, in, keysize);
8284
8285
58
#ifdef HAVE_COMP_KEY
8286
58
    if (err == MP_OKAY && compressed == 1) {   /* build y */
8287
0
    #if defined(WOLFSSL_HAVE_SP_ECC)
8288
0
        #ifndef WOLFSSL_SP_NO_256
8289
0
        if (curve_idx != ECC_CUSTOM_IDX &&
8290
0
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
8291
0
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
8292
0
        }
8293
0
        else
8294
0
        #endif
8295
0
        #ifdef WOLFSSL_SP_384
8296
0
        if (curve_idx != ECC_CUSTOM_IDX &&
8297
0
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
8298
0
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
8299
0
        }
8300
0
        else
8301
0
        #endif
8302
0
        #ifdef WOLFSSL_SP_521
8303
0
        if (curve_idx != ECC_CUSTOM_IDX &&
8304
0
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
8305
0
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
8306
0
        }
8307
0
        else
8308
0
        #endif
8309
0
    #endif
8310
    #if !defined(WOLFSSL_SP_MATH)
8311
        {
8312
            int did_init = 0;
8313
        #ifdef WOLFSSL_SMALL_STACK
8314
            mp_int* t1 = NULL;
8315
            mp_int* t2 = NULL;
8316
        #else
8317
            mp_int t1[1], t2[1];
8318
        #endif
8319
            DECLARE_CURVE_SPECS(3);
8320
8321
            ALLOC_CURVE_SPECS(3, err);
8322
8323
        #ifdef WOLFSSL_SMALL_STACK
8324
            if (err == MP_OKAY) {
8325
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
8326
                                      DYNAMIC_TYPE_BIGINT);
8327
                if (t1 == NULL) {
8328
                    err = MEMORY_E;
8329
                }
8330
            }
8331
            if (err == MP_OKAY) {
8332
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
8333
                                      DYNAMIC_TYPE_BIGINT);
8334
                if (t2 == NULL) {
8335
                    err = MEMORY_E;
8336
                }
8337
            }
8338
        #endif
8339
8340
            if (err == MP_OKAY) {
8341
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
8342
                    err = MEMORY_E;
8343
                else
8344
                    did_init = 1;
8345
            }
8346
8347
            /* load curve info */
8348
            if (err == MP_OKAY)
8349
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
8350
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
8351
                        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
            if (err == MP_OKAY)
8366
                err = mp_sqr(point->x, t1);
8367
            if (err == MP_OKAY)
8368
                err = mp_mulmod(t1, point->x, curve->prime, t1);
8369
8370
            /* compute x^3 + a*x */
8371
            if (err == MP_OKAY)
8372
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
8373
            if (err == MP_OKAY)
8374
                err = mp_add(t1, t2, t1);
8375
8376
            /* compute x^3 + a*x + b */
8377
            if (err == MP_OKAY)
8378
                err = mp_add(t1, curve->Bf, t1);
8379
8380
            /* compute sqrt(x^3 + a*x + b) */
8381
            if (err == MP_OKAY)
8382
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
8383
8384
            /* adjust y */
8385
            if (err == MP_OKAY) {
8386
                if ((mp_isodd(t2) == MP_YES &&
8387
                                            pointType == ECC_POINT_COMP_ODD) ||
8388
                    (mp_isodd(t2) == MP_NO &&
8389
                                            pointType == ECC_POINT_COMP_EVEN)) {
8390
                    err = mp_mod(t2, curve->prime, point->y);
8391
                }
8392
                else {
8393
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
8394
                }
8395
            }
8396
8397
            if (did_init) {
8398
                mp_clear(t2);
8399
                mp_clear(t1);
8400
            }
8401
8402
        #ifdef WOLFSSL_SMALL_STACK
8403
            if (t1 != NULL) {
8404
                XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
8405
            }
8406
            if (t2 != NULL) {
8407
                XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
8408
            }
8409
        #endif
8410
8411
            wc_ecc_curve_free(curve);
8412
            FREE_CURVE_SPECS();
8413
        }
8414
    #else
8415
0
        {
8416
0
            err = WC_KEY_SIZE_E;
8417
0
        }
8418
0
    #endif
8419
0
    }
8420
58
#endif
8421
8422
58
    if (err == MP_OKAY) {
8423
58
#ifdef HAVE_COMP_KEY
8424
58
        if (compressed == 0)
8425
58
#endif
8426
58
            err = mp_read_unsigned_bin(point->y, in + keysize, keysize);
8427
58
    }
8428
58
    if (err == MP_OKAY)
8429
58
        err = mp_set(point->z, 1);
8430
8431
58
    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
58
    RESTORE_VECTOR_REGISTERS();
8438
8439
58
    return err;
8440
58
}
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
58
{
8446
58
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
8447
58
}
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
132
{
8469
132
    int    ret = MP_OKAY;
8470
132
    word32 numlen;
8471
132
#ifdef WOLFSSL_SMALL_STACK
8472
132
    byte*  buf;
8473
#else
8474
    byte   buf[ECC_BUFSIZE];
8475
#endif
8476
8477
132
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
8478
0
        return ECC_BAD_ARG_E;
8479
8480
132
    numlen = ecc_sets[curve_idx].size;
8481
8482
    /* return length needed only */
8483
132
    if (point != NULL && out == NULL && outLen != NULL) {
8484
5
        *outLen = 1 + 2*numlen;
8485
5
        return LENGTH_ONLY_E;
8486
5
    }
8487
8488
127
    if (point == NULL || out == NULL || outLen == NULL)
8489
0
        return ECC_BAD_ARG_E;
8490
8491
127
    if (*outLen < (1 + 2*numlen)) {
8492
2
        *outLen = 1 + 2*numlen;
8493
2
        return BUFFER_E;
8494
2
    }
8495
8496
    /* Sanity check the ordinates' sizes. */
8497
125
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
8498
125
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
8499
31
        return ECC_BAD_ARG_E;
8500
31
    }
8501
8502
    /* store byte point type */
8503
94
    out[0] = ECC_POINT_UNCOMP;
8504
8505
94
#ifdef WOLFSSL_SMALL_STACK
8506
94
    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8507
94
    if (buf == NULL)
8508
36
        return MEMORY_E;
8509
58
#endif
8510
8511
    /* pad and store x */
8512
58
    XMEMSET(buf, 0, ECC_BUFSIZE);
8513
58
    ret = mp_to_unsigned_bin(point->x, buf +
8514
58
                                 (numlen - mp_unsigned_bin_size(point->x)));
8515
58
    if (ret != MP_OKAY)
8516
0
        goto done;
8517
58
    XMEMCPY(out+1, buf, numlen);
8518
8519
    /* pad and store y */
8520
58
    XMEMSET(buf, 0, ECC_BUFSIZE);
8521
58
    ret = mp_to_unsigned_bin(point->y, buf +
8522
58
                                 (numlen - mp_unsigned_bin_size(point->y)));
8523
58
    if (ret != MP_OKAY)
8524
0
        goto done;
8525
58
    XMEMCPY(out+1+numlen, buf, numlen);
8526
8527
58
    *outLen = 1 + 2*numlen;
8528
8529
58
done:
8530
58
#ifdef WOLFSSL_SMALL_STACK
8531
58
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8532
58
#endif
8533
8534
58
    return ret;
8535
58
}
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
1.48k
{
8611
1.48k
   int    ret = MP_OKAY;
8612
1.48k
   word32 numlen;
8613
1.48k
#ifdef WOLFSSL_SMALL_STACK
8614
1.48k
   byte*  buf;
8615
#else
8616
   byte   buf[ECC_BUFSIZE];
8617
#endif
8618
1.48k
   word32 pubxlen, pubylen;
8619
8620
   /* return length needed only */
8621
1.48k
   if (key != NULL && out == NULL && outLen != NULL) {
8622
      /* if key hasn't been setup assume max bytes for size estimation */
8623
668
      numlen = key->dp ? key->dp->size : MAX_ECC_BYTES;
8624
668
      *outLen = 1 + 2*numlen;
8625
668
      return LENGTH_ONLY_E;
8626
668
   }
8627
8628
816
   if (key == NULL || out == NULL || outLen == NULL)
8629
0
      return ECC_BAD_ARG_E;
8630
8631
816
   if (key->type == ECC_PRIVATEKEY_ONLY)
8632
156
       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
660
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
8651
282
       return ECC_BAD_ARG_E;
8652
282
   }
8653
8654
378
   numlen = key->dp->size;
8655
8656
    /* verify room in out buffer */
8657
378
   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
378
   pubxlen = mp_unsigned_bin_size(key->pubkey.x);
8664
378
   pubylen = mp_unsigned_bin_size(key->pubkey.y);
8665
378
   if ((pubxlen > numlen) || (pubylen > numlen)) {
8666
10
      WOLFSSL_MSG("Public key x/y invalid!");
8667
10
      return BUFFER_E;
8668
10
   }
8669
8670
   /* store byte point type */
8671
368
   out[0] = ECC_POINT_UNCOMP;
8672
8673
368
#ifdef WOLFSSL_SMALL_STACK
8674
368
   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8675
368
   if (buf == NULL)
8676
60
      return MEMORY_E;
8677
308
#endif
8678
8679
   /* pad and store x */
8680
308
   XMEMSET(buf, 0, ECC_BUFSIZE);
8681
308
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
8682
308
   if (ret != MP_OKAY)
8683
0
      goto done;
8684
308
   XMEMCPY(out+1, buf, numlen);
8685
8686
   /* pad and store y */
8687
308
   XMEMSET(buf, 0, ECC_BUFSIZE);
8688
308
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
8689
308
   if (ret != MP_OKAY)
8690
0
      goto done;
8691
308
   XMEMCPY(out+1+numlen, buf, numlen);
8692
8693
308
   *outLen = 1 + 2*numlen;
8694
8695
308
done:
8696
308
#ifdef WOLFSSL_SMALL_STACK
8697
308
   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
8698
308
#endif
8699
8700
308
   return ret;
8701
308
}
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
1.84k
{
8710
1.84k
    if (compressed == 0)
8711
1.48k
        return wc_ecc_export_x963(key, out, outLen);
8712
358
#ifdef HAVE_COMP_KEY
8713
358
    else
8714
358
        return wc_ecc_export_x963_compressed(key, out, outLen);
8715
#else
8716
    return NOT_COMPILED_IN;
8717
#endif
8718
1.84k
}
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
1.44k
{
8729
#if !defined(WOLFSSL_SP_MATH)
8730
   int err;
8731
#ifdef WOLFSSL_SMALL_STACK
8732
   mp_int* t1;
8733
   mp_int* t2;
8734
#else
8735
   mp_int  t1[1], t2[1];
8736
#endif
8737
8738
#ifdef WOLFSSL_SMALL_STACK
8739
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
8740
   if (t1 == NULL)
8741
       return MEMORY_E;
8742
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
8743
   if (t2 == NULL) {
8744
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8745
       return MEMORY_E;
8746
   }
8747
#endif
8748
8749
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
8750
   #ifdef WOLFSSL_SMALL_STACK
8751
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
8752
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8753
   #endif
8754
      return err;
8755
   }
8756
8757
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
8758
8759
   /* compute y^2 */
8760
   if (err == MP_OKAY)
8761
       err = mp_sqr(ecp->y, t1);
8762
8763
   /* compute x^3 */
8764
   if (err == MP_OKAY)
8765
       err = mp_sqr(ecp->x, t2);
8766
   if (err == MP_OKAY)
8767
       err = mp_mod(t2, prime, t2);
8768
   if (err == MP_OKAY)
8769
       err = mp_mul(ecp->x, t2, t2);
8770
8771
   /* compute y^2 - x^3 */
8772
   if (err == MP_OKAY)
8773
       err = mp_submod(t1, t2, prime, t1);
8774
8775
   /* Determine if curve "a" should be used in calc */
8776
#ifdef WOLFSSL_CUSTOM_CURVES
8777
   if (err == MP_OKAY) {
8778
      /* Use a and prime to determine if a == 3 */
8779
      err = mp_set(t2, 0);
8780
      if (err == MP_OKAY)
8781
          err = mp_submod(prime, a, prime, t2);
8782
   }
8783
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
8784
      /* compute y^2 - x^3 + a*x */
8785
      if (err == MP_OKAY)
8786
          err = mp_mulmod(t2, ecp->x, prime, t2);
8787
      if (err == MP_OKAY)
8788
          err = mp_addmod(t1, t2, prime, t1);
8789
   }
8790
   else
8791
#endif /* WOLFSSL_CUSTOM_CURVES */
8792
   {
8793
      /* assumes "a" == 3 */
8794
      (void)a;
8795
8796
      /* compute y^2 - x^3 + 3x */
8797
      if (err == MP_OKAY)
8798
          err = mp_add(t1, ecp->x, t1);
8799
      if (err == MP_OKAY)
8800
          err = mp_add(t1, ecp->x, t1);
8801
      if (err == MP_OKAY)
8802
          err = mp_add(t1, ecp->x, t1);
8803
      if (err == MP_OKAY)
8804
          err = mp_mod(t1, prime, t1);
8805
  }
8806
8807
   /* adjust range (0, prime) */
8808
   while (err == MP_OKAY && mp_isneg(t1)) {
8809
      err = mp_add(t1, prime, t1);
8810
   }
8811
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
8812
      err = mp_sub(t1, prime, t1);
8813
   }
8814
8815
   /* compare to b */
8816
   if (err == MP_OKAY) {
8817
       if (mp_cmp(t1, b) != MP_EQ) {
8818
          err = IS_POINT_E;
8819
       } else {
8820
          err = MP_OKAY;
8821
       }
8822
   }
8823
8824
   mp_clear(t1);
8825
   mp_clear(t2);
8826
8827
   RESTORE_VECTOR_REGISTERS();
8828
8829
#ifdef WOLFSSL_SMALL_STACK
8830
   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
8831
   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
8832
#endif
8833
8834
   return err;
8835
#else
8836
1.44k
   (void)a;
8837
1.44k
   (void)b;
8838
8839
1.44k
#ifdef WOLFSSL_HAVE_SP_ECC
8840
1.44k
#ifndef WOLFSSL_SP_NO_256
8841
1.44k
   if (mp_count_bits(prime) == 256) {
8842
602
       return sp_ecc_is_point_256(ecp->x, ecp->y);
8843
602
   }
8844
847
#endif
8845
847
#ifdef WOLFSSL_SP_384
8846
847
   if (mp_count_bits(prime) == 384) {
8847
481
       return sp_ecc_is_point_384(ecp->x, ecp->y);
8848
481
   }
8849
366
#endif
8850
366
#ifdef WOLFSSL_SP_521
8851
366
   if (mp_count_bits(prime) == 521) {
8852
366
       return sp_ecc_is_point_521(ecp->x, ecp->y);
8853
366
   }
8854
0
#endif
8855
#else
8856
   (void)ecp;
8857
   (void)prime;
8858
#endif
8859
0
   return WC_KEY_SIZE_E;
8860
366
#endif
8861
366
}
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
{
9103
    ecc_point* inf = NULL;
9104
#ifdef WOLFSSL_NO_MALLOC
9105
    ecc_point  lcl_inf;
9106
#endif
9107
    int err;
9108
9109
    if (key == NULL)
9110
        return BAD_FUNC_ARG;
9111
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
9112
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
9113
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
9114
       return IS_POINT_E;
9115
   }
9116
9117
#ifdef WOLFSSL_NO_MALLOC
9118
    inf = &lcl_inf;
9119
#endif
9120
    err = wc_ecc_new_point_ex(&inf, key->heap);
9121
    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
#if !defined(WOLFSSL_SP_MATH)
9146
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
9147
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
9148
            err = ECC_INF_E;
9149
#else
9150
        {
9151
            (void)a;
9152
            (void)prime;
9153
9154
            err = WC_KEY_SIZE_E;
9155
        }
9156
#endif
9157
    }
9158
9159
    wc_ecc_del_point_ex(inf, key->heap);
9160
9161
    return err;
9162
}
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
{
9170
    int err = MP_OKAY;
9171
    DECLARE_CURVE_SPECS(2);
9172
9173
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
9174
        return BAD_FUNC_ARG;
9175
9176
    ALLOC_CURVE_SPECS(2, err);
9177
9178
    if (err == MP_OKAY)
9179
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9180
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
9181
    if (err == MP_OKAY)
9182
        err = mp_copy(curve->Gx, ecp->x);
9183
    if (err == MP_OKAY)
9184
        err = mp_copy(curve->Gy, ecp->y);
9185
    if (err == MP_OKAY)
9186
        err = mp_set(ecp->z, 1);
9187
9188
    wc_ecc_curve_free(curve);
9189
    FREE_CURVE_SPECS();
9190
9191
    return err;
9192
}
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
2.99k
{
9204
2.99k
    int err = MP_OKAY;
9205
#ifndef WOLFSSL_SP_MATH
9206
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
9207
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
9208
    !defined(WOLFSSL_SE050) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
9209
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9210
    mp_int* b = NULL;
9211
    #ifdef USE_ECC_B_PARAM
9212
        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
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
9220
          !WOLFSSL_CRYPTOCELL && !WOLFSSL_SILABS_SE_ACCEL && !WOLFSSL_SE050 */
9221
#endif /* !WOLFSSL_SP_MATH */
9222
9223
2.99k
    ASSERT_SAVED_VECTOR_REGISTERS();
9224
9225
2.99k
    if (key == NULL)
9226
0
        return BAD_FUNC_ARG;
9227
9228
2.99k
#ifdef WOLFSSL_HAVE_SP_ECC
9229
2.99k
#ifndef WOLFSSL_SP_NO_256
9230
2.99k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
9231
1.29k
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
9232
1.29k
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9233
1.29k
    }
9234
1.70k
#endif
9235
1.70k
#ifdef WOLFSSL_SP_384
9236
1.70k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
9237
787
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
9238
787
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9239
787
    }
9240
919
#endif
9241
919
#ifdef WOLFSSL_SP_521
9242
919
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
9243
919
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
9244
919
            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
9245
919
    }
9246
0
#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
0
#endif
9254
9255
#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
    #ifdef USE_ECC_B_PARAM
9269
        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
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
9301
    #ifdef WOLFSSL_SMALL_STACK
9302
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
9303
    #endif
9304
        FREE_CURVE_SPECS();
9305
        return ECC_INF_E;
9306
    }
9307
9308
    /* load curve info */
9309
    if (err == MP_OKAY)
9310
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
9311
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
9312
#ifdef USE_ECC_B_PARAM
9313
            | ECC_CURVE_FIELD_BF
9314
#endif
9315
    ));
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
    if (err == MP_OKAY)
9325
        b = curve->Bf;
9326
#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
    if (err == MP_OKAY) {
9332
        if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
9333
            err = ECC_OUT_OF_RANGE_E;
9334
    }
9335
9336
    /* Qy must be in the range [0, p-1] */
9337
    if (err == MP_OKAY) {
9338
        if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
9339
            err = ECC_OUT_OF_RANGE_E;
9340
    }
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
    if (err == MP_OKAY)
9346
        err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
9347
9348
    if (!partial) {
9349
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
9350
        /* pubkey * order must be at infinity */
9351
        if (err == MP_OKAY)
9352
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
9353
                    curve->prime, curve->order);
9354
    }
9355
9356
    if (priv) {
9357
        /* SP 800-56Ar3, section 5.6.2.1.2 */
9358
        /* private keys must be in the range [1, n-1] */
9359
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
9360
            (mp_iszero(&key->k) || mp_isneg(&key->k) ||
9361
            (mp_cmp(&key->k, curve->order) != MP_LT))
9362
        #ifdef WOLFSSL_KCAPI_ECC
9363
            && key->handle == NULL
9364
        #endif
9365
        ) {
9366
            err = ECC_PRIV_KEY_E;
9367
        }
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
    }
9376
9377
    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
    FREE_CURVE_SPECS();
9387
#endif /* HW Based Crypto */
9388
#else
9389
0
    err = WC_KEY_SIZE_E;
9390
0
#endif /* !WOLFSSL_SP_MATH */
9391
0
    (void)partial;
9392
0
    (void)priv;
9393
0
    return err;
9394
919
}
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
2.99k
{
9401
2.99k
    int ret;
9402
2.99k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9403
2.99k
    ret = _ecc_validate_public_key(key, 0, 1);
9404
2.99k
    RESTORE_VECTOR_REGISTERS();
9405
2.99k
    return ret;
9406
2.99k
}
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
336
{
9414
336
    int err = MP_OKAY;
9415
336
#ifdef HAVE_COMP_KEY
9416
336
    int compressed = 0;
9417
336
#endif
9418
336
    int keysize = 0;
9419
336
    byte pointType;
9420
#ifdef WOLFSSL_CRYPTOCELL
9421
    const CRYS_ECPKI_Domain_t* pDomain;
9422
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
9423
#endif
9424
336
    if (in == NULL || key == NULL)
9425
0
        return BAD_FUNC_ARG;
9426
9427
    /* must be odd */
9428
336
    if ((inLen & 1) == 0) {
9429
0
        return ECC_BAD_ARG_E;
9430
0
    }
9431
9432
    /* make sure required variables are reset */
9433
336
    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
336
        err = mp_init_multi(&key->k,
9446
336
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
9447
336
    #endif
9448
336
    if (err != MP_OKAY)
9449
0
        return MEMORY_E;
9450
9451
336
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9452
9453
    /* check for point type (4, 2, or 3) */
9454
336
    pointType = in[0];
9455
336
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9456
336
                                         pointType != ECC_POINT_COMP_ODD) {
9457
14
        err = ASN_PARSE_E;
9458
14
    }
9459
9460
336
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9461
146
    #ifdef HAVE_COMP_KEY
9462
146
        compressed = 1;
9463
    #else
9464
        err = NOT_COMPILED_IN;
9465
    #endif
9466
146
    }
9467
9468
    /* adjust to skip first byte */
9469
336
    inLen -= 1;
9470
336
    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
336
    if (err == MP_OKAY) {
9485
322
    #ifdef HAVE_COMP_KEY
9486
        /* adjust inLen if compressed */
9487
322
        if (compressed)
9488
146
            inLen = inLen*2 + 1;  /* used uncompressed len */
9489
322
    #endif
9490
9491
        /* determine key size */
9492
322
        keysize = (inLen>>1);
9493
322
        err = wc_ecc_set_curve(key, keysize, curve_id);
9494
322
        key->type = ECC_PUBLICKEY;
9495
322
    }
9496
9497
    /* read data */
9498
336
    if (err == MP_OKAY)
9499
322
        err = mp_read_unsigned_bin(key->pubkey.x, in, keysize);
9500
9501
336
#ifdef HAVE_COMP_KEY
9502
336
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9503
#if !defined(WOLFSSL_SP_MATH)
9504
    #ifdef WOLFSSL_SMALL_STACK
9505
        mp_int* t1 = NULL;
9506
        mp_int* t2 = NULL;
9507
    #else
9508
        mp_int t1[1], t2[1];
9509
    #endif
9510
        int did_init = 0;
9511
9512
        DECLARE_CURVE_SPECS(3);
9513
        ALLOC_CURVE_SPECS(3, err);
9514
9515
        #ifdef WOLFSSL_SMALL_STACK
9516
        if (err == MP_OKAY) {
9517
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
9518
            if (t1 == NULL) {
9519
                err = MEMORY_E;
9520
            }
9521
        }
9522
        if (err == MP_OKAY) {
9523
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
9524
            if (t2 == NULL) {
9525
                err = MEMORY_E;
9526
            }
9527
        }
9528
        #endif
9529
        if (err == MP_OKAY) {
9530
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9531
                err = MEMORY_E;
9532
            else
9533
                did_init = 1;
9534
        }
9535
9536
        /* load curve info */
9537
        if (err == MP_OKAY)
9538
            err = wc_ecc_curve_load(key->dp, &curve,
9539
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9540
                 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
        if (err == MP_OKAY)
9555
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
9556
        if (err == MP_OKAY)
9557
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
9558
9559
        /* compute x^3 + a*x */
9560
        if (err == MP_OKAY)
9561
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
9562
        if (err == MP_OKAY)
9563
            err = mp_add(t1, t2, t1);
9564
9565
        /* compute x^3 + a*x + b */
9566
        if (err == MP_OKAY)
9567
            err = mp_add(t1, curve->Bf, t1);
9568
9569
        /* compute sqrt(x^3 + a*x + b) */
9570
        if (err == MP_OKAY)
9571
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
9572
9573
        /* adjust y */
9574
        if (err == MP_OKAY) {
9575
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
9576
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
9577
                err = mp_mod(t2, curve->prime, t2);
9578
            }
9579
            else {
9580
                err = mp_submod(curve->prime, t2, curve->prime, t2);
9581
            }
9582
            if (err == MP_OKAY)
9583
                err = mp_copy(t2, key->pubkey.y);
9584
        }
9585
9586
        if (did_init) {
9587
            mp_clear(t2);
9588
            mp_clear(t1);
9589
        }
9590
    #ifdef WOLFSSL_SMALL_STACK
9591
        if (t1 != NULL) {
9592
            XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
9593
        }
9594
        if (t2 != NULL) {
9595
            XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
9596
        }
9597
    #endif
9598
9599
        wc_ecc_curve_free(curve);
9600
        FREE_CURVE_SPECS();
9601
#else
9602
146
    #ifndef WOLFSSL_SP_NO_256
9603
146
        if (key->dp->id == ECC_SECP256R1) {
9604
73
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
9605
73
                key->pubkey.y);
9606
73
        }
9607
73
        else
9608
73
    #endif
9609
73
    #ifdef WOLFSSL_SP_384
9610
73
        if (key->dp->id == ECC_SECP384R1) {
9611
45
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
9612
45
                key->pubkey.y);
9613
45
        }
9614
28
        else
9615
28
    #endif
9616
28
    #ifdef WOLFSSL_SP_521
9617
28
        if (key->dp->id == ECC_SECP521R1) {
9618
28
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
9619
28
                key->pubkey.y);
9620
28
        }
9621
0
        else
9622
0
    #endif
9623
0
        {
9624
0
            err = WC_KEY_SIZE_E;
9625
0
        }
9626
146
#endif
9627
146
    }
9628
336
#endif /* HAVE_COMP_KEY */
9629
9630
336
    if (err == MP_OKAY) {
9631
269
    #ifdef HAVE_COMP_KEY
9632
269
        if (compressed == 0)
9633
176
    #endif
9634
176
        {
9635
176
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize, keysize);
9636
176
        }
9637
269
    }
9638
336
    if (err == MP_OKAY)
9639
269
        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
336
    if (err != MP_OKAY) {
9666
67
        mp_clear(key->pubkey.x);
9667
67
        mp_clear(key->pubkey.y);
9668
67
        mp_clear(key->pubkey.z);
9669
67
        mp_clear(&key->k);
9670
67
    }
9671
9672
336
    RESTORE_VECTOR_REGISTERS();
9673
9674
336
    return err;
9675
336
}
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
2.31k
{
9834
2.31k
    int ret;
9835
#ifdef WOLFSSL_CRYPTOCELL
9836
    const CRYS_ECPKI_Domain_t* pDomain;
9837
#endif
9838
2.31k
    if (key == NULL || priv == NULL)
9839
0
        return BAD_FUNC_ARG;
9840
9841
    /* public optional, NULL if only importing private */
9842
2.31k
    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
2.31k
    else {
9855
        /* make sure required variables are reset */
9856
2.31k
        wc_ecc_reset(key);
9857
9858
        /* set key size */
9859
2.31k
        ret = wc_ecc_set_curve(key, privSz, curve_id);
9860
2.31k
        key->type = ECC_PRIVATEKEY_ONLY;
9861
2.31k
    }
9862
9863
2.31k
    if (ret != 0)
9864
57
        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
2.25k
    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
2.25k
#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
2.25k
    return ret;
10010
2.31k
}
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
1.40k
{
10034
1.40k
    int err;
10035
1.40k
#ifdef WOLFSSL_SMALL_STACK
10036
1.40k
    mp_int* rtmp = NULL;
10037
1.40k
    mp_int* stmp = NULL;
10038
#else
10039
    mp_int  rtmp[1];
10040
    mp_int  stmp[1];
10041
#endif
10042
10043
1.40k
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
10044
1
        return ECC_BAD_ARG_E;
10045
10046
1.40k
#ifdef WOLFSSL_SMALL_STACK
10047
1.40k
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10048
1.40k
    if (rtmp == NULL)
10049
18
        return MEMORY_E;
10050
1.39k
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10051
1.39k
    if (stmp == NULL) {
10052
12
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
10053
12
        return MEMORY_E;
10054
12
    }
10055
1.37k
#endif
10056
10057
1.37k
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
10058
1.37k
    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
1.37k
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
10067
1.37k
    if (err == MP_OKAY)
10068
1.36k
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
10069
10070
1.37k
    if (err == MP_OKAY) {
10071
1.36k
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
10072
21
            err = MP_ZERO_E;
10073
1.36k
    }
10074
1.37k
    if (err == MP_OKAY) {
10075
1.34k
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
10076
0
            err = MP_READ_E;
10077
0
        }
10078
1.34k
    }
10079
10080
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
10081
1.37k
    if (err == MP_OKAY)
10082
1.34k
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
10083
10084
1.37k
    mp_clear(rtmp);
10085
1.37k
    mp_clear(stmp);
10086
1.37k
#ifdef WOLFSSL_SMALL_STACK
10087
1.37k
    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
10088
1.37k
    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
10089
1.37k
#endif
10090
10091
1.37k
    return err;
10092
1.37k
}
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
2.68k
{
10138
2.68k
    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
2.68k
    if (key == NULL || qx == NULL || qy == NULL) {
10153
0
        return BAD_FUNC_ARG;
10154
0
    }
10155
10156
    /* make sure required variables are reset */
10157
2.68k
    wc_ecc_reset(key);
10158
10159
    /* set curve type and index */
10160
2.68k
    err = wc_ecc_set_curve(key, 0, curve_id);
10161
2.68k
    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
2.68k
    err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10176
2.68k
                                                                  NULL, NULL);
10177
2.68k
#endif
10178
2.68k
    if (err != MP_OKAY)
10179
0
        return MEMORY_E;
10180
10181
    /* read Qx */
10182
2.68k
    if (err == MP_OKAY) {
10183
2.68k
        if (encType == WC_TYPE_HEX_STR)
10184
2.68k
            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
2.68k
        if (mp_isneg(key->pubkey.x)) {
10190
0
            WOLFSSL_MSG("Invalid Qx");
10191
0
            err = BAD_FUNC_ARG;
10192
0
        }
10193
2.68k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
10194
0
            err = BAD_FUNC_ARG;
10195
0
        }
10196
2.68k
    }
10197
10198
    /* read Qy */
10199
2.68k
    if (err == MP_OKAY) {
10200
2.64k
        if (encType == WC_TYPE_HEX_STR)
10201
2.64k
            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
2.64k
        if (mp_isneg(key->pubkey.y)) {
10207
0
            WOLFSSL_MSG("Invalid Qy");
10208
0
            err = BAD_FUNC_ARG;
10209
0
        }
10210
2.64k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
10211
11
            err = BAD_FUNC_ARG;
10212
11
        }
10213
2.64k
    }
10214
10215
2.68k
    if (err == MP_OKAY) {
10216
2.60k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
10217
56
            WOLFSSL_MSG("Invalid Qx and Qy");
10218
56
            err = ECC_INF_E;
10219
56
        }
10220
2.60k
    }
10221
10222
2.68k
    if (err == MP_OKAY)
10223
2.55k
        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
2.68k
    if (err == MP_OKAY) {
10286
2.55k
        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
2.55k
        } else {
10343
2.55k
            key->type = ECC_PUBLICKEY;
10344
2.55k
        }
10345
2.55k
    }
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
2.68k
    if (err != MP_OKAY) {
10362
135
        mp_clear(key->pubkey.x);
10363
135
        mp_clear(key->pubkey.y);
10364
135
        mp_clear(key->pubkey.z);
10365
135
        mp_clear(&key->k);
10366
135
    }
10367
10368
2.68k
    return err;
10369
2.68k
}
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
2.68k
{
10411
2.68k
    int err, x;
10412
10413
    /* if d is NULL, only import as public key using Qx,Qy */
10414
2.68k
    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
4.68k
    for (x = 0; ecc_sets[x].size != 0; x++) {
10420
4.68k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
10421
4.68k
                     XSTRLEN(curveName)) == 0) {
10422
2.68k
            break;
10423
2.68k
        }
10424
4.68k
    }
10425
10426
2.68k
    if (ecc_sets[x].size == 0) {
10427
0
        WOLFSSL_MSG("ecc_set curve name not found");
10428
0
        err = ASN_PARSE_E;
10429
2.68k
    } else {
10430
2.68k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
10431
2.68k
            WC_TYPE_HEX_STR);
10432
2.68k
    }
10433
10434
0
    return err;
10435
2.68k
}
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
110
{
10442
110
    if (key == NULL || key->dp == NULL)
10443
0
        return BAD_FUNC_ARG;
10444
10445
    /* 'Uncompressed' | x | y */
10446
110
    *sz = 1 + 2 * key->dp->size;
10447
10448
110
    return 0;
10449
110
}
10450
#endif
10451
10452
/* key size in octets */
10453
WOLFSSL_ABI
10454
int wc_ecc_size(ecc_key* key)
10455
218
{
10456
218
    if (key == NULL || key->dp == NULL)
10457
0
        return 0;
10458
10459
218
    return key->dp->size;
10460
218
}
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
820
{
12354
820
    int err = 0;
12355
12356
820
    if (key == NULL) {
12357
0
        err = BAD_FUNC_ARG;
12358
0
    }
12359
820
    else {
12360
820
        key->rng = rng;
12361
820
    }
12362
12363
820
    return err;
12364
820
}
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
328
{
12556
328
    if (ctx) {
12557
328
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
12558
12559
328
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12560
328
        #ifdef WOLFSSL_AES_128
12561
328
            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
328
        ctx->kdfAlgo  = ecHKDF_SHA256;
12575
328
        ctx->macAlgo  = ecHMAC_SHA256;
12576
328
        ctx->protocol = (byte)flags;
12577
328
        ctx->rng      = rng;
12578
12579
328
        if (flags == REQ_RESP_CLIENT)
12580
0
            ctx->cliSt = ecCLI_INIT;
12581
328
        if (flags == REQ_RESP_SERVER)
12582
0
            ctx->srvSt = ecSRV_INIT;
12583
328
    }
12584
328
}
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
328
{
12643
328
    if (ctx) {
12644
328
        switch (ctx->encAlgo) {
12645
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12646
328
            case ecAES_128_CBC:
12647
328
                *encKeySz = KEY_SIZE_128;
12648
328
                *ivSz     = IV_SIZE_128;
12649
328
                *blockSz  = AES_BLOCK_SIZE;
12650
328
                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
328
        }
12672
12673
328
        switch (ctx->macAlgo) {
12674
328
            case ecHMAC_SHA256:
12675
328
                *digestSz = WC_SHA256_DIGEST_SIZE;
12676
328
                break;
12677
0
            default:
12678
0
                return BAD_FUNC_ARG;
12679
328
        }
12680
328
    } else
12681
0
        return BAD_FUNC_ARG;
12682
12683
#ifdef WOLFSSL_ECIES_OLD
12684
    *keysLen  = *encKeySz + *ivSz + *digestSz;
12685
#else
12686
328
    *keysLen  = *encKeySz + *digestSz;
12687
328
#endif
12688
12689
328
    return 0;
12690
328
}
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
236
{
12700
236
    int          ret = 0;
12701
236
    word32       blockSz = 0;
12702
236
#ifndef WOLFSSL_ECIES_OLD
12703
236
#ifndef WOLFSSL_ECIES_GEN_IV
12704
236
    byte         iv[ECC_MAX_IV_SIZE];
12705
236
#endif
12706
236
    word32       pubKeySz = 0;
12707
236
#endif
12708
236
    word32       digestSz = 0;
12709
236
    ecEncCtx     localCtx;
12710
236
#ifdef WOLFSSL_SMALL_STACK
12711
236
    byte*        sharedSecret;
12712
236
    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
236
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
12722
236
    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
236
    int          keysLen = 0;
12728
236
    int          encKeySz = 0;
12729
236
    int          ivSz = 0;
12730
236
    int          offset = 0;         /* keys offset if doing msg exchange */
12731
236
    byte*        encKey = NULL;
12732
236
    byte*        encIv = NULL;
12733
236
    byte*        macKey = NULL;
12734
12735
236
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
12736
236
                           outSz  == NULL)
12737
18
        return BAD_FUNC_ARG;
12738
12739
218
    if (ctx == NULL) {  /* use defaults */
12740
218
        ecc_ctx_init(&localCtx, 0, NULL);
12741
218
        ctx = &localCtx;
12742
218
    }
12743
12744
218
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
12745
218
                            &blockSz);
12746
218
    if (ret != 0)
12747
0
        return ret;
12748
12749
218
#ifndef WOLFSSL_ECIES_OLD
12750
218
    if (!compressed) {
12751
218
        pubKeySz = 1 + wc_ecc_size(privKey) * 2;
12752
218
    }
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
218
    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
218
    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
218
    if (keysLen > ECC_BUFSIZE) /* keys size */
12777
0
        return BUFFER_E;
12778
12779
218
    if ((msgSz % blockSz) != 0)
12780
10
        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
208
    if (*outSz < (pubKeySz + msgSz + digestSz))
12790
3
        return BUFFER_E;
12791
205
#endif
12792
12793
205
#ifdef ECC_TIMING_RESISTANT
12794
205
    if (ctx->rng != NULL && privKey->rng == NULL)
12795
0
        privKey->rng = ctx->rng;
12796
205
#endif
12797
12798
205
#ifndef WOLFSSL_ECIES_OLD
12799
205
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
12800
205
#ifdef ECC_TIMING_RESISTANT
12801
205
        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
205
        if (ret != 0)
12806
57
            return ret;
12807
205
    }
12808
148
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
12809
148
    if (ret != 0)
12810
15
        return ret;
12811
133
    out += pubKeySz;
12812
133
#endif
12813
12814
133
#ifdef WOLFSSL_SMALL_STACK
12815
133
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12816
133
    if (sharedSecret == NULL)
12817
7
        return MEMORY_E;
12818
12819
126
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12820
126
    if (keys == NULL) {
12821
4
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
12822
4
        return MEMORY_E;
12823
4
    }
12824
122
#endif
12825
12826
122
    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
122
    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
122
    #ifndef WOLFSSL_ECIES_ISO18033
12840
122
        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
122
    } while (ret == WC_PENDING_E);
12846
122
    if (ret == 0) {
12847
    #ifdef WOLFSSL_ECIES_ISO18033
12848
        /* KDF data is encoded public key and secret. */
12849
        sharedSz += pubKeySz;
12850
    #endif
12851
110
        switch (ctx->kdfAlgo) {
12852
110
            case ecHKDF_SHA256 :
12853
110
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
12854
110
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
12855
110
                           keys, keysLen);
12856
110
                break;
12857
12858
0
            default:
12859
0
                ret = BAD_FUNC_ARG;
12860
0
                break;
12861
110
        }
12862
110
    }
12863
12864
122
    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
78
        XMEMSET(iv, 0, ivSz);
12877
78
        encKey = keys + offset;
12878
78
        encIv  = iv;
12879
78
        macKey = encKey + encKeySz;
12880
78
    #endif
12881
78
    }
12882
12883
122
    if (ret == 0) {
12884
78
       switch (ctx->encAlgo) {
12885
78
            case ecAES_128_CBC:
12886
78
            case ecAES_256_CBC:
12887
78
            {
12888
78
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
12889
78
            #ifdef WOLFSSL_SMALL_STACK
12890
78
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
12891
78
                                          DYNAMIC_TYPE_AES);
12892
78
                if (aes == NULL) {
12893
4
                    ret = MEMORY_E;
12894
4
                    break;
12895
4
                }
12896
            #else
12897
                Aes aes[1];
12898
            #endif
12899
74
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12900
74
                if (ret == 0) {
12901
74
                    ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
12902
74
                                                                AES_ENCRYPTION);
12903
74
                    if (ret == 0) {
12904
74
                        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
74
                    }
12911
74
                    wc_AesFree(aes);
12912
74
                }
12913
74
            #ifdef WOLFSSL_SMALL_STACK
12914
74
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
12915
74
            #endif
12916
        #else
12917
                ret = NOT_COMPILED_IN;
12918
        #endif
12919
74
                break;
12920
78
            }
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
78
        }
12968
78
    }
12969
12970
122
    if (ret == 0) {
12971
74
        switch (ctx->macAlgo) {
12972
74
            case ecHMAC_SHA256:
12973
74
            {
12974
74
            #ifdef WOLFSSL_SMALL_STACK
12975
74
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
12976
74
                                             DYNAMIC_TYPE_HMAC);
12977
74
                if (hmac == NULL) {
12978
3
                    ret = MEMORY_E;
12979
3
                    break;
12980
3
                }
12981
            #else
12982
                Hmac hmac[1];
12983
            #endif
12984
71
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
12985
71
                if (ret == 0) {
12986
71
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
12987
71
                                                         WC_SHA256_DIGEST_SIZE);
12988
71
                    if (ret == 0) {
12989
71
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
12990
71
                        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
71
                    }
12996
71
                    if (ret == 0)
12997
61
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
12998
71
                    if (ret == 0)
12999
61
                        ret = wc_HmacFinal(hmac, out+msgSz);
13000
71
                    wc_HmacFree(hmac);
13001
71
                }
13002
71
            #ifdef WOLFSSL_SMALL_STACK
13003
71
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
13004
71
            #endif
13005
71
                break;
13006
74
            }
13007
13008
0
            default:
13009
0
                ret = BAD_FUNC_ARG;
13010
0
                break;
13011
74
        }
13012
74
    }
13013
13014
122
    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
55
        *outSz = pubKeySz + msgSz + digestSz;
13021
55
#endif
13022
55
    }
13023
13024
122
    RESTORE_VECTOR_REGISTERS();
13025
13026
122
#ifdef WOLFSSL_SMALL_STACK
13027
122
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13028
122
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13029
122
#endif
13030
13031
122
    return ret;
13032
122
}
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
236
{
13042
236
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
13043
236
}
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
112
{
13052
112
    int          ret = 0;
13053
112
    word32       blockSz = 0;
13054
112
#ifndef WOLFSSL_ECIES_OLD
13055
112
#ifndef WOLFSSL_ECIES_GEN_IV
13056
112
    byte         iv[ECC_MAX_IV_SIZE];
13057
112
#endif
13058
112
    word32       pubKeySz = 0;
13059
112
#ifdef WOLFSSL_SMALL_STACK
13060
112
    ecc_key*     peerKey = NULL;
13061
#else
13062
    ecc_key      peerKey[1];
13063
#endif
13064
112
#endif
13065
112
    word32       digestSz = 0;
13066
112
    ecEncCtx     localCtx;
13067
112
#ifdef WOLFSSL_SMALL_STACK
13068
112
    byte*        sharedSecret;
13069
112
    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
112
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
13079
112
    word32       sharedSz = ECC_MAXSIZE;
13080
#else
13081
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
13082
#endif
13083
112
    int          keysLen = 0;
13084
112
    int          encKeySz = 0;
13085
112
    int          ivSz = 0;
13086
112
    int          offset = 0;       /* in case using msg exchange */
13087
112
    byte*        encKey = NULL;
13088
112
    const byte*  encIv = NULL;
13089
112
    byte*        macKey = NULL;
13090
13091
13092
112
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
13093
2
        return BAD_FUNC_ARG;
13094
#ifdef WOLFSSL_ECIES_OLD
13095
    if (pubKey == NULL)
13096
        return BAD_FUNC_ARG;
13097
#endif
13098
13099
110
    if (ctx == NULL) {  /* use defaults */
13100
110
        ecc_ctx_init(&localCtx, 0, NULL);
13101
110
        ctx = &localCtx;
13102
110
    }
13103
13104
110
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
13105
110
                            &blockSz);
13106
110
    if (ret != 0)
13107
0
        return ret;
13108
13109
110
#ifndef WOLFSSL_ECIES_OLD
13110
110
    ret = ecc_public_key_size(privKey, &pubKeySz);
13111
110
    if (ret != 0)
13112
0
        return ret;
13113
110
#ifdef HAVE_COMP_KEY
13114
110
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
13115
70
        pubKeySz = (pubKeySz / 2) + 1;
13116
70
    }
13117
110
#endif /* HAVE_COMP_KEY */
13118
110
#endif /* WOLFSSL_ECIES_OLD */
13119
13120
110
    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
110
    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
110
    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
110
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
13155
23
        return BAD_PADDING_E;
13156
13157
87
    if (msgSz < pubKeySz + blockSz + digestSz)
13158
4
        return BAD_FUNC_ARG;
13159
83
    if (*outSz < (msgSz - digestSz - pubKeySz))
13160
1
        return BUFFER_E;
13161
82
#endif
13162
13163
82
#ifdef ECC_TIMING_RESISTANT
13164
82
    if (ctx->rng != NULL && privKey->rng == NULL)
13165
0
        privKey->rng = ctx->rng;
13166
82
#endif
13167
13168
82
#ifdef WOLFSSL_SMALL_STACK
13169
82
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13170
82
    if (sharedSecret == NULL) {
13171
4
    #ifndef WOLFSSL_ECIES_OLD
13172
4
        if (pubKey == peerKey)
13173
0
            wc_ecc_free(peerKey);
13174
4
    #endif
13175
4
        return MEMORY_E;
13176
4
    }
13177
13178
78
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13179
78
    if (keys == NULL) {
13180
8
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13181
8
    #ifndef WOLFSSL_ECIES_OLD
13182
8
        if (pubKey == peerKey)
13183
0
            wc_ecc_free(peerKey);
13184
8
    #endif
13185
8
        return MEMORY_E;
13186
8
    }
13187
70
#endif
13188
13189
70
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
13190
13191
70
#ifndef WOLFSSL_ECIES_OLD
13192
70
    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
70
    else {
13202
        /* if a public key was passed in we should free it here before init
13203
         * and import */
13204
70
        wc_ecc_free(pubKey);
13205
70
    }
13206
70
    if (ret == 0) {
13207
70
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
13208
70
    }
13209
70
    if (ret == 0) {
13210
70
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
13211
70
    }
13212
70
    if (ret == 0) {
13213
        /* Point is not MACed. */
13214
50
        msg += pubKeySz;
13215
50
        msgSz -= pubKeySz;
13216
50
    }
13217
70
#endif
13218
13219
70
    if (ret == 0) {
13220
    #ifdef WOLFSSL_ECIES_ISO18033
13221
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
13222
        sharedSz -= pubKeySz;
13223
    #endif
13224
13225
50
        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
50
        #ifndef WOLFSSL_ECIES_ISO18033
13233
50
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
13234
50
                                                                    &sharedSz);
13235
        #else
13236
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
13237
                                                          pubKeySz, &sharedSz);
13238
        #endif
13239
50
        } while (ret == WC_PENDING_E);
13240
50
    }
13241
70
    if (ret == 0) {
13242
    #ifdef WOLFSSL_ECIES_ISO18033
13243
        /* KDF data is encoded public key and secret. */
13244
        sharedSz += pubKeySz;
13245
    #endif
13246
46
        switch (ctx->kdfAlgo) {
13247
46
            case ecHKDF_SHA256 :
13248
46
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
13249
46
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
13250
46
                           keys, keysLen);
13251
46
                break;
13252
13253
0
            default:
13254
0
                ret = BAD_FUNC_ARG;
13255
0
                break;
13256
46
         }
13257
46
    }
13258
13259
70
    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
44
        XMEMSET(iv, 0, ivSz);
13272
44
        encKey = keys + offset;
13273
44
        encIv  = iv;
13274
44
        macKey = encKey + encKeySz;
13275
44
    #endif
13276
13277
44
        switch (ctx->macAlgo) {
13278
44
            case ecHMAC_SHA256:
13279
44
            {
13280
44
                byte verify[WC_SHA256_DIGEST_SIZE];
13281
44
            #ifdef WOLFSSL_SMALL_STACK
13282
44
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
13283
44
                                             DYNAMIC_TYPE_HMAC);
13284
44
                if (hmac == NULL) {
13285
1
                    ret = MEMORY_E;
13286
1
                    break;
13287
1
                }
13288
            #else
13289
                Hmac hmac[1];
13290
            #endif
13291
43
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
13292
43
                if (ret == 0) {
13293
43
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
13294
43
                                                         WC_SHA256_DIGEST_SIZE);
13295
43
                    if (ret == 0)
13296
43
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
13297
43
                        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
43
                    if (ret == 0)
13303
39
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
13304
13305
43
                    if (ret == 0)
13306
39
                        ret = wc_HmacFinal(hmac, verify);
13307
43
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
13308
39
                                                              digestSz) != 0)) {
13309
37
                        ret = -1;
13310
37
                    }
13311
13312
43
                    wc_HmacFree(hmac);
13313
43
                }
13314
43
            #ifdef WOLFSSL_SMALL_STACK
13315
43
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
13316
43
            #endif
13317
43
                break;
13318
44
            }
13319
13320
0
            default:
13321
0
                ret = BAD_FUNC_ARG;
13322
0
                break;
13323
44
        }
13324
44
    }
13325
13326
70
    if (ret == 0) {
13327
2
        switch (ctx->encAlgo) {
13328
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13329
2
            case ecAES_128_CBC:
13330
2
            case ecAES_256_CBC:
13331
2
            {
13332
2
            #ifdef WOLFSSL_SMALL_STACK
13333
2
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
13334
2
                                          DYNAMIC_TYPE_AES);
13335
2
                if (aes == NULL) {
13336
0
                    ret = MEMORY_E;
13337
0
                    break;
13338
0
                }
13339
            #else
13340
                Aes aes[1];
13341
            #endif
13342
2
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13343
2
                if (ret == 0) {
13344
2
                    ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
13345
2
                                                                AES_DECRYPTION);
13346
2
                    if (ret == 0) {
13347
2
                        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
2
                    }
13354
2
                    wc_AesFree(aes);
13355
2
                }
13356
2
            #ifdef WOLFSSL_SMALL_STACK
13357
2
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
13358
2
            #endif
13359
2
                break;
13360
2
            }
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
2
        }
13405
2
    }
13406
13407
70
    if (ret == 0)
13408
2
       *outSz = msgSz - digestSz;
13409
13410
70
    RESTORE_VECTOR_REGISTERS();
13411
13412
70
#ifndef WOLFSSL_ECIES_OLD
13413
70
    if (pubKey == peerKey)
13414
0
        wc_ecc_free(peerKey);
13415
70
#endif
13416
70
#ifdef WOLFSSL_SMALL_STACK
13417
70
#ifndef WOLFSSL_ECIES_OLD
13418
70
    if (peerKey != NULL) {
13419
0
        XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13420
0
    }
13421
70
#endif
13422
70
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13423
70
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
13424
70
#endif
13425
13426
70
    return ret;
13427
70
}
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
{
13442
#ifdef WOLFSSL_SMALL_STACK
13443
    mp_int*  a1 = NULL;
13444
    mp_int*  n1 = NULL;
13445
#else
13446
    mp_int   a1[1], n1[1];
13447
#endif
13448
    int      res;
13449
    int      s = 1;
13450
    int      k;
13451
    mp_int*  t[2];
13452
    mp_int*  ts;
13453
    mp_digit residue;
13454
13455
    if (mp_isneg(a) == MP_YES) {
13456
        return MP_VAL;
13457
    }
13458
    if (mp_isneg(n) == MP_YES) {
13459
        return MP_VAL;
13460
    }
13461
    if (mp_iseven(n) == MP_YES) {
13462
        return MP_VAL;
13463
    }
13464
13465
#ifdef WOLFSSL_SMALL_STACK
13466
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
13467
    if (a1 == NULL) {
13468
        return MP_MEM;
13469
    }
13470
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
13471
    if (n1 == NULL) {
13472
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13473
        return MP_MEM;
13474
    }
13475
#endif
13476
13477
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
13478
#ifdef WOLFSSL_SMALL_STACK
13479
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13480
        XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
13481
#endif
13482
        return res;
13483
    }
13484
13485
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
13486
13487
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
13488
        goto done;
13489
    }
13490
13491
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
13492
        goto done;
13493
    }
13494
13495
    t[0] = a1;
13496
    t[1] = n1;
13497
13498
    /* Keep reducing until first number is 0. */
13499
    while (!mp_iszero(t[0])) {
13500
        /* Divide by 2 until odd. */
13501
        k = mp_cnt_lsb(t[0]);
13502
        if (k > 0) {
13503
            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
            residue = t[1]->dp[0] & 7;
13509
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
13510
                s = -s;
13511
            }
13512
        }
13513
13514
        /* Swap t[0] and t[1]. */
13515
        ts   = t[0];
13516
        t[0] = t[1];
13517
        t[1] = ts;
13518
13519
        /* Negate s if both numbers == 3 mod 4. */
13520
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
13521
             s = -s;
13522
        }
13523
13524
        /* Reduce first number modulo second. */
13525
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
13526
            res = mp_sub(t[0], t[1], t[0]);
13527
        }
13528
        else {
13529
            res = mp_mod(t[0], t[1], t[0]);
13530
        }
13531
        if (res != MP_OKAY) {
13532
            goto done;
13533
        }
13534
    }
13535
13536
    /* When the two numbers have divisors in common. */
13537
    if (!mp_isone(t[1])) {
13538
        s = 0;
13539
    }
13540
    *c = s;
13541
13542
done:
13543
13544
    RESTORE_VECTOR_REGISTERS();
13545
13546
    /* cleanup */
13547
    mp_clear(n1);
13548
    mp_clear(a1);
13549
13550
#ifdef WOLFSSL_SMALL_STACK
13551
    XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
13552
    XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
13553
#endif
13554
13555
  return res;
13556
}
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
{
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
  int res, legendre, done = 0;
13588
  mp_digit i;
13589
#ifdef WOLFSSL_SMALL_STACK
13590
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13591
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13592
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13593
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13594
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13595
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13596
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13597
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13598
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
13599
  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
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
13605
13606
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
13607
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
13608
    res = MP_INIT_E;
13609
    goto out;
13610
  }
13611
13612
#ifdef WOLFSSL_SMALL_STACK
13613
  if ((t1 == NULL) ||
13614
      (C == NULL) ||
13615
      (Q == NULL) ||
13616
      (S == NULL) ||
13617
      (Z == NULL) ||
13618
      (M == NULL) ||
13619
      (T == NULL) ||
13620
      (R == NULL) ||
13621
      (N == NULL) ||
13622
      (two == NULL)) {
13623
    res = MP_MEM;
13624
    goto out;
13625
  }
13626
#endif
13627
13628
  /* first handle the simple cases n = 0 or n = 1 */
13629
  if (mp_cmp_d(n, 0) == MP_EQ) {
13630
    mp_zero(ret);
13631
    res = MP_OKAY;
13632
    goto out;
13633
  }
13634
  if (mp_cmp_d(n, 1) == MP_EQ) {
13635
    res = mp_set(ret, 1);
13636
    goto out;
13637
  }
13638
13639
  /* prime must be odd */
13640
  if (mp_cmp_d(prime, 2) == MP_EQ) {
13641
    res = MP_VAL;
13642
    goto out;
13643
  }
13644
13645
  /* reduce n to less than prime */
13646
  res = mp_mod(n, prime, N);
13647
  if (res != MP_OKAY) {
13648
    goto out;
13649
  }
13650
  /* when N is zero, sqrt is zero */
13651
  if (mp_iszero(N)) {
13652
    mp_set(ret, 0);
13653
    goto out;
13654
  }
13655
13656
  /* is quadratic non-residue mod prime */
13657
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
13658
    goto out;
13659
  }
13660
  if (legendre == -1) {
13661
    res = MP_VAL;
13662
    goto out;
13663
  }
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
  res = mp_mod_d(prime, 4, &i);
13670
  if (res == MP_OKAY && i == 3) {
13671
    res = mp_add_d(prime, 1, t1);
13672
13673
    if (res == MP_OKAY)
13674
      res = mp_div_2(t1, t1);
13675
    if (res == MP_OKAY)
13676
      res = mp_div_2(t1, t1);
13677
    if (res == MP_OKAY)
13678
      res = mp_exptmod(N, t1, prime, ret);
13679
13680
    done = 1;
13681
  }
13682
13683
  /* NOW: TonelliShanks algorithm */
13684
  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
    res = mp_copy(prime, Q);
13690
    if (res == MP_OKAY)
13691
      res = mp_sub_d(Q, 1, Q);
13692
13693
    /* S = 0 */
13694
    if (res == MP_OKAY)
13695
      mp_zero(S);
13696
13697
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
13698
      /* Q = Q / 2 */
13699
      res = mp_div_2(Q, Q);
13700
13701
      /* S = S + 1 */
13702
      if (res == MP_OKAY)
13703
        res = mp_add_d(S, 1, S);
13704
    }
13705
13706
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
13707
    /* Z = 2 */
13708
    if (res == MP_OKAY)
13709
      res = mp_set_int(Z, 2);
13710
13711
    while (res == MP_OKAY) {
13712
      res = mp_jacobi(Z, prime, &legendre);
13713
      if (res == MP_OKAY && legendre == -1)
13714
        break;
13715
13716
      /* Z = Z + 1 */
13717
      if (res == MP_OKAY)
13718
        res = mp_add_d(Z, 1, Z);
13719
    }
13720
13721
    /* C = Z ^ Q mod prime */
13722
    if (res == MP_OKAY)
13723
      res = mp_exptmod(Z, Q, prime, C);
13724
13725
    /* t1 = (Q + 1) / 2 */
13726
    if (res == MP_OKAY)
13727
      res = mp_add_d(Q, 1, t1);
13728
    if (res == MP_OKAY)
13729
      res = mp_div_2(t1, t1);
13730
13731
    /* R = n ^ ((Q + 1) / 2) mod prime */
13732
    if (res == MP_OKAY)
13733
      res = mp_exptmod(N, t1, prime, R);
13734
13735
    /* T = n ^ Q mod prime */
13736
    if (res == MP_OKAY)
13737
      res = mp_exptmod(N, Q, prime, T);
13738
13739
    /* M = S */
13740
    if (res == MP_OKAY)
13741
      res = mp_copy(S, M);
13742
13743
    if (res == MP_OKAY)
13744
      res = mp_set_int(two, 2);
13745
13746
    while (res == MP_OKAY && done == 0) {
13747
      res = mp_copy(T, t1);
13748
13749
      /* reduce to 1 and count */
13750
      i = 0;
13751
      while (res == MP_OKAY) {
13752
        if (mp_cmp_d(t1, 1) == MP_EQ)
13753
            break;
13754
        res = mp_exptmod(t1, two, prime, t1);
13755
        if (res == MP_OKAY)
13756
          i++;
13757
      }
13758
      if (res == MP_OKAY && i == 0) {
13759
        res = mp_copy(R, ret);
13760
        done = 1;
13761
      }
13762
13763
      if (done == 0) {
13764
        /* t1 = 2 ^ (M - i - 1) */
13765
        if (res == MP_OKAY)
13766
          res = mp_sub_d(M, i, t1);
13767
        if (res == MP_OKAY)
13768
          res = mp_sub_d(t1, 1, t1);
13769
        if (res == MP_OKAY)
13770
          res = mp_exptmod(two, t1, prime, t1);
13771
13772
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
13773
        if (res == MP_OKAY)
13774
          res = mp_exptmod(C, t1, prime, t1);
13775
13776
        /* C = (t1 * t1) mod prime */
13777
        if (res == MP_OKAY)
13778
          res = mp_sqrmod(t1, prime, C);
13779
13780
        /* R = (R * t1) mod prime */
13781
        if (res == MP_OKAY)
13782
          res = mp_mulmod(R, t1, prime, R);
13783
13784
        /* T = (T * C) mod prime */
13785
        if (res == MP_OKAY)
13786
          res = mp_mulmod(T, C, prime, T);
13787
13788
        /* M = i */
13789
        if (res == MP_OKAY)
13790
          res = mp_set(M, i);
13791
      }
13792
    }
13793
  }
13794
13795
  out:
13796
13797
  RESTORE_VECTOR_REGISTERS();
13798
13799
#ifdef WOLFSSL_SMALL_STACK
13800
  if (t1) {
13801
    if (res != MP_INIT_E)
13802
      mp_clear(t1);
13803
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13804
  }
13805
  if (C) {
13806
    if (res != MP_INIT_E)
13807
      mp_clear(C);
13808
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13809
  }
13810
  if (Q) {
13811
    if (res != MP_INIT_E)
13812
      mp_clear(Q);
13813
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13814
  }
13815
  if (S) {
13816
    if (res != MP_INIT_E)
13817
      mp_clear(S);
13818
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13819
  }
13820
  if (Z) {
13821
    if (res != MP_INIT_E)
13822
      mp_clear(Z);
13823
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13824
  }
13825
  if (M) {
13826
    if (res != MP_INIT_E)
13827
      mp_clear(M);
13828
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13829
  }
13830
  if (T) {
13831
    if (res != MP_INIT_E)
13832
      mp_clear(T);
13833
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13834
  }
13835
  if (R) {
13836
    if (res != MP_INIT_E)
13837
      mp_clear(R);
13838
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13839
  }
13840
  if (N) {
13841
    if (res != MP_INIT_E)
13842
      mp_clear(N);
13843
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13844
  }
13845
  if (two) {
13846
    if (res != MP_INIT_E)
13847
      mp_clear(two);
13848
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13849
  }
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
  return res;
13866
#endif
13867
}
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
358
{
13875
358
   word32 numlen;
13876
358
   int    ret = MP_OKAY;
13877
13878
358
   if (key == NULL || outLen == NULL)
13879
0
       return BAD_FUNC_ARG;
13880
13881
358
   if (key->type == ECC_PRIVATEKEY_ONLY)
13882
23
       return ECC_PRIVATEONLY_E;
13883
13884
335
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
13885
149
       return ECC_BAD_ARG_E;
13886
149
   }
13887
13888
186
   numlen = key->dp->size;
13889
13890
186
   if (*outLen < (1 + numlen)) {
13891
93
      *outLen = 1 + numlen;
13892
93
      return LENGTH_ONLY_E;
13893
93
   }
13894
13895
93
   if (out == NULL)
13896
0
       return BAD_FUNC_ARG;
13897
13898
93
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
13899
2
       return ECC_BAD_ARG_E;
13900
13901
   /* store first byte */
13902
91
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
13903
13904
   /* pad and store x */
13905
91
   XMEMSET(out+1, 0, numlen);
13906
91
   ret = mp_to_unsigned_bin(key->pubkey.x,
13907
91
                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
13908
91
   *outLen = 1 + numlen;
13909
13910
91
   return ret;
13911
93
}
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
{
13966
    if (key == NULL || dp == NULL) {
13967
        return BAD_FUNC_ARG;
13968
    }
13969
13970
    key->idx = ECC_CUSTOM_IDX;
13971
    key->dp = dp;
13972
13973
    return 0;
13974
}
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 */