Coverage Report

Created: 2026-01-06 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-normal-math/wolfcrypt/src/ecc.c
Line
Count
Source
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2025 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 3 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
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
25
#undef WOLFSSL_SMALL_STACK
26
#undef WOLFSSL_SMALL_STACK_CACHE
27
#endif
28
29
/*
30
Possible ECC enable options:
31
 * HAVE_ECC:            Overall control of ECC                  default: on
32
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
33
 * HAVE_ECC_SIGN:       ECC sign                                default: on
34
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
35
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
36
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
37
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
38
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
39
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
40
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
41
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
42
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
43
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
44
 *                        Includes the curve "a" variable in calculation
45
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
46
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
47
 *                                                              default: off
48
 * FP_ECC:              ECC Fixed Point Cache                   default: off
49
 *                      FP cache is not supported for SECP160R1, SECP160R2,
50
 *                      SECP160K1 and SECP224K1. These do not work with scalars
51
 *                      that are the length of the order when the order is
52
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
53
 * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
54
 *                      (on for HAVE_COMP_KEY)
55
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
56
 *                      For the ECC curve parameters `ecc_set_type` use fixed
57
 *                      array for hex string
58
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
59
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
60
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
61
 *                      normal blocking API's
62
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
63
 *                      signing. If the value is invalid, a new random 'k' is
64
 *                      generated in the loop. (For testing)
65
 *                                                              default: off
66
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
67
 *                      Enables the setting of the 'k' value to use during ECDSA
68
 *                      signing. If the value is invalid then an error is
69
 *                      returned rather than generating a new 'k'. (For testing)
70
 *                                                              default: off
71
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
72
 *                      deterministic ECC signatures. The following function
73
 *                      can be used to set the deterministic signing flag in the
74
 *                      ecc key structure.
75
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
76
 *                                                              default: off
77
 *
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
79
 *                      hash directly instead of doing bits2octets(H(m)), when
80
 *                      the variant macro is used the bits2octets operation on
81
 *                      the hash is removed.
82
 *                                                              default: off
83
 *
84
 * WC_PROTECT_ENCRYPTED_MEM:
85
 *                      Enables implementations that protect data that is in
86
 *                      encrypted memory.
87
 *                                                              default: off
88
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
89
 *                      Enables generation of scalar (private key and ECDSA
90
 *                      nonce) to be performed using reject sampling algorithm.
91
 *                      Use this when CPU state can be closely observed by
92
 *                      attacker.
93
 *                                                              default: off
94
 * WOLFSSL_ECC_BLIND_K
95
 *                      Blind the private key k by using a random mask.
96
 *                      The private key is never stored unprotected but an
97
 *                      unmasked copy is computed and stored each time it is
98
 *                      needed.
99
 *                                                              default: off
100
 * WOLFSSL_CHECK_VER_FAULTS
101
 *                      Sanity check on verification steps in case of faults.
102
 *                                                              default: off
103
 */
104
105
/*
106
ECC Curve Types:
107
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
108
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
109
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
110
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
111
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
112
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
113
 */
114
115
/*
116
ECC Curve Sizes:
117
 * ECC_USER_CURVES: Allows custom combination of key sizes below
118
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
119
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
120
 * HAVE_ECC112: 112 bit key
121
 * HAVE_ECC128: 128 bit key
122
 * HAVE_ECC160: 160 bit key
123
 * HAVE_ECC192: 192 bit key
124
 * HAVE_ECC224: 224 bit key
125
 * HAVE_ECC239: 239 bit key
126
 * NO_ECC256: Disables 256 bit key (on by default)
127
 * HAVE_ECC320: 320 bit key
128
 * HAVE_ECC384: 384 bit key
129
 * HAVE_ECC512: 512 bit key
130
 * HAVE_ECC521: 521 bit key
131
 */
132
133
134
#ifdef HAVE_ECC
135
136
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
137
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
138
    !defined(WOLFSSL_CUSTOM_CURVES)
139
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
140
#endif
141
142
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
143
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
144
    #define FIPS_NO_WRAPPERS
145
146
    #ifdef USE_WINDOWS_API
147
        #pragma code_seg(".fipsA$f")
148
        #pragma const_seg(".fipsB$f")
149
    #endif
150
#endif
151
152
/* public ASN interface */
153
#include <wolfssl/wolfcrypt/asn_public.h>
154
155
#include <wolfssl/wolfcrypt/ecc.h>
156
#include <wolfssl/wolfcrypt/asn.h>
157
158
#ifdef WOLFSSL_HAVE_SP_ECC
159
#include <wolfssl/wolfcrypt/sp.h>
160
#endif
161
162
#ifdef HAVE_ECC_ENCRYPT
163
    #include <wolfssl/wolfcrypt/kdf.h>
164
    #include <wolfssl/wolfcrypt/aes.h>
165
#endif
166
167
#ifdef HAVE_X963_KDF
168
    #include <wolfssl/wolfcrypt/hash.h>
169
#endif
170
171
#ifdef WOLF_CRYPTO_CB
172
    #include <wolfssl/wolfcrypt/cryptocb.h>
173
#endif
174
175
#ifdef NO_INLINE
176
    #include <wolfssl/wolfcrypt/misc.h>
177
#else
178
    #define WOLFSSL_MISC_INCLUDED
179
    #include <wolfcrypt/src/misc.c>
180
#endif
181
182
#if FIPS_VERSION3_GE(6,0,0)
183
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
184
                                                     { 0x1a2b3c4d, 0x00000005 };
185
    int wolfCrypt_FIPS_ECC_sanity(void)
186
    {
187
        return 0;
188
    }
189
#endif
190
191
#if defined(FREESCALE_LTC_ECC)
192
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
193
#endif
194
195
#if defined(WOLFSSL_STM32_PKA)
196
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
197
#endif
198
199
#if defined(WOLFSSL_PSOC6_CRYPTO)
200
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
201
#endif
202
203
#if defined(WOLFSSL_CAAM)
204
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
205
#endif
206
207
#if defined(WOLFSSL_KCAPI_ECC)
208
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
209
#endif
210
211
#ifdef WOLFSSL_SE050
212
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
213
#endif
214
215
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
216
    #include <xsecure_ellipticclient.h>
217
#endif
218
219
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
220
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
221
    #include <wolfssl/wolfcrypt/hmac.h>
222
#endif
223
224
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WOLFSSL_SP_ASM)
225
    /* force off unneeded vector register save/restore. */
226
    #undef SAVE_VECTOR_REGISTERS
227
    #define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
228
    #undef RESTORE_VECTOR_REGISTERS
229
    #define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
230
#endif
231
232
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
233
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
234
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
235
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) && \
236
    !defined(WOLFSSL_PSOC6_CRYPTO)
237
    #undef  HAVE_ECC_VERIFY_HELPER
238
    #define HAVE_ECC_VERIFY_HELPER
239
#endif
240
241
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
242
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
243
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
244
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
245
    #undef  HAVE_ECC_MAKE_PUB
246
    #define HAVE_ECC_MAKE_PUB
247
#endif
248
249
250
/* macro guard for ecc_check_pubkey_order functionality */
251
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
252
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
253
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
254
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
255
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
256
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
257
258
    /* CAAM builds use public key validation as a means to check if an
259
     * imported private key is an encrypted black key or not */
260
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
261
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
262
#endif
263
264
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
265
#define MAX_ECC_BITS_USE    SP_INT_BITS
266
#else
267
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
268
#endif
269
270
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
271
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
272
273
#define ECC_KEY_MAX_BITS(key)                                       \
274
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
275
        ((unsigned)((key)->dp->size * 8)))
276
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
277
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
278
        ((unsigned)((key)->dp->size * 8)))
279
280
#else
281
282
/* Add one bit for cases when order is a bit greater than prime. */
283
#define ECC_KEY_MAX_BITS(key)                                       \
284
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
285
        ((unsigned)((key)->dp->size * 8 + 1)))
286
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
287
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
288
        ((unsigned)((key)->dp->size * 8 + 1)))
289
290
#endif
291
292
#ifdef WOLFSSL_ECC_BLIND_K
293
mp_int* ecc_get_k(ecc_key* key)
294
{
295
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
296
    return key->ku;
297
}
298
void ecc_blind_k(ecc_key* key, mp_int* b)
299
{
300
    mp_xor_ct(key->k, b, key->dp->size, key->k);
301
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
302
}
303
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
304
{
305
    int ret = 0;
306
    WC_RNG local_rng;
307
308
#ifdef ECC_TIMING_RESISTANT
309
    if (rng == NULL) {
310
        rng = key->rng;
311
    }
312
#endif
313
    if (rng == NULL) {
314
        ret = wc_InitRng(&local_rng);
315
        if (ret == 0) {
316
            rng = &local_rng;
317
        }
318
    }
319
    if (ret == 0) {
320
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
321
            sizeof(mp_digit), rng);
322
        if (ret == 0) {
323
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
324
        }
325
    }
326
327
    if (rng == &local_rng) {
328
        wc_FreeRng(&local_rng);
329
    }
330
    return ret;
331
}
332
333
mp_int* wc_ecc_key_get_priv(ecc_key* key)
334
{
335
    return ecc_get_k(key);
336
}
337
#endif
338
339
/* forward declarations */
340
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
341
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
342
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
343
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
344
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
345
#endif
346
347
/* internal ECC states */
348
enum {
349
    ECC_STATE_NONE = 0,
350
351
    ECC_STATE_SHARED_SEC_GEN,
352
    ECC_STATE_SHARED_SEC_RES,
353
354
    ECC_STATE_SIGN_DO,
355
    ECC_STATE_SIGN_ENCODE,
356
357
    ECC_STATE_VERIFY_DECODE,
358
    ECC_STATE_VERIFY_DO,
359
    ECC_STATE_VERIFY_RES
360
};
361
362
363
/* map
364
   ptmul -> mulmod
365
*/
366
367
/* 256-bit curve on by default whether user curves or not */
368
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
369
    #define ECC112
370
#endif
371
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
372
    #define ECC128
373
#endif
374
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
375
    #define ECC160
376
#endif
377
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
378
    #define ECC192
379
#endif
380
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
381
    #define ECC224
382
#endif
383
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
384
    #define ECC239
385
#endif
386
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
387
    #define ECC256
388
#endif
389
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
390
    #define ECC320
391
#endif
392
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
393
    #define ECC384
394
#endif
395
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
396
    #define ECC512
397
#endif
398
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
399
    #define ECC521
400
#endif
401
402
/* The encoded OID's for ECC curves */
403
#ifdef ECC112
404
    #ifndef NO_ECC_SECP
405
        #ifdef HAVE_OID_ENCODING
406
            #define CODED_SECP112R1    {1,3,132,0,6}
407
            #define CODED_SECP112R1_SZ 5
408
        #else
409
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
410
            #define CODED_SECP112R1_SZ 5
411
        #endif
412
        #ifndef WOLFSSL_ECC_CURVE_STATIC
413
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
414
        #else
415
            #define ecc_oid_secp112r1 CODED_SECP112R1
416
        #endif
417
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
418
    #endif /* !NO_ECC_SECP */
419
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
420
        #ifdef HAVE_OID_ENCODING
421
            #define CODED_SECP112R2    {1,3,132,0,7}
422
            #define CODED_SECP112R2_SZ 5
423
        #else
424
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
425
            #define CODED_SECP112R2_SZ 5
426
        #endif
427
        #ifndef WOLFSSL_ECC_CURVE_STATIC
428
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
429
        #else
430
            #define ecc_oid_secp112r2 CODED_SECP112R2
431
        #endif
432
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
433
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
434
#endif /* ECC112 */
435
#ifdef ECC128
436
    #ifndef NO_ECC_SECP
437
        #ifdef HAVE_OID_ENCODING
438
            #define CODED_SECP128R1    {1,3,132,0,28}
439
            #define CODED_SECP128R1_SZ 5
440
        #else
441
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
442
            #define CODED_SECP128R1_SZ 5
443
        #endif
444
        #ifndef WOLFSSL_ECC_CURVE_STATIC
445
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
446
        #else
447
            #define ecc_oid_secp128r1 CODED_SECP128R1
448
        #endif
449
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
450
    #endif /* !NO_ECC_SECP */
451
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
452
        #ifdef HAVE_OID_ENCODING
453
            #define CODED_SECP128R2    {1,3,132,0,29}
454
            #define CODED_SECP128R2_SZ 5
455
        #else
456
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
457
            #define CODED_SECP128R2_SZ 5
458
        #endif
459
        #ifndef WOLFSSL_ECC_CURVE_STATIC
460
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
461
        #else
462
            #define ecc_oid_secp128r2 CODED_SECP128R2
463
        #endif
464
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
465
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
466
#endif /* ECC128 */
467
#ifdef ECC160
468
#ifndef FP_ECC
469
    #ifndef NO_ECC_SECP
470
        #ifdef HAVE_OID_ENCODING
471
            #define CODED_SECP160R1    {1,3,132,0,8}
472
            #define CODED_SECP160R1_SZ 5
473
        #else
474
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
475
            #define CODED_SECP160R1_SZ 5
476
        #endif
477
        #ifndef WOLFSSL_ECC_CURVE_STATIC
478
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
479
        #else
480
            #define ecc_oid_secp160r1 CODED_SECP160R1
481
        #endif
482
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
483
    #endif /* !NO_ECC_SECP */
484
    #ifdef HAVE_ECC_SECPR2
485
        #ifdef HAVE_OID_ENCODING
486
            #define CODED_SECP160R2    {1,3,132,0,30}
487
            #define CODED_SECP160R2_SZ 5
488
        #else
489
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
490
            #define CODED_SECP160R2_SZ 5
491
        #endif
492
        #ifndef WOLFSSL_ECC_CURVE_STATIC
493
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
494
        #else
495
            #define ecc_oid_secp160r2 CODED_SECP160R2
496
        #endif
497
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
498
    #endif /* HAVE_ECC_SECPR2 */
499
    #ifdef HAVE_ECC_KOBLITZ
500
        #ifdef HAVE_OID_ENCODING
501
            #define CODED_SECP160K1    {1,3,132,0,9}
502
            #define CODED_SECP160K1_SZ 5
503
        #else
504
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
505
            #define CODED_SECP160K1_SZ 5
506
        #endif
507
        #ifndef WOLFSSL_ECC_CURVE_STATIC
508
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
509
        #else
510
            #define ecc_oid_secp160k1 CODED_SECP160K1
511
        #endif
512
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
513
    #endif /* HAVE_ECC_KOBLITZ */
514
#endif /* !FP_ECC */
515
    #ifdef HAVE_ECC_BRAINPOOL
516
        #ifdef HAVE_OID_ENCODING
517
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
518
            #define CODED_BRAINPOOLP160R1_SZ 10
519
        #else
520
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
521
            #define CODED_BRAINPOOLP160R1_SZ 9
522
        #endif
523
        #ifndef WOLFSSL_ECC_CURVE_STATIC
524
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
525
        #else
526
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
527
        #endif
528
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
529
    #endif /* HAVE_ECC_BRAINPOOL */
530
#endif /* ECC160 */
531
#ifdef ECC192
532
    #ifndef NO_ECC_SECP
533
        #ifdef HAVE_OID_ENCODING
534
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
535
            #define CODED_SECP192R1_SZ 7
536
        #else
537
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
538
            #define CODED_SECP192R1_SZ 8
539
        #endif
540
        #ifndef WOLFSSL_ECC_CURVE_STATIC
541
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
542
        #else
543
            #define ecc_oid_secp192r1 CODED_SECP192R1
544
        #endif
545
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
546
    #endif /* !NO_ECC_SECP */
547
    #ifdef HAVE_ECC_SECPR2
548
        #ifdef HAVE_OID_ENCODING
549
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
550
            #define CODED_PRIME192V2_SZ 7
551
        #else
552
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
553
            #define CODED_PRIME192V2_SZ 8
554
        #endif
555
        #ifndef WOLFSSL_ECC_CURVE_STATIC
556
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
557
        #else
558
            #define ecc_oid_prime192v2 CODED_PRIME192V2
559
        #endif
560
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
561
    #endif /* HAVE_ECC_SECPR2 */
562
    #ifdef HAVE_ECC_SECPR3
563
        #ifdef HAVE_OID_ENCODING
564
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
565
            #define CODED_PRIME192V3_SZ 7
566
        #else
567
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
568
            #define CODED_PRIME192V3_SZ 8
569
        #endif
570
        #ifndef WOLFSSL_ECC_CURVE_STATIC
571
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
572
        #else
573
            #define ecc_oid_prime192v3 CODED_PRIME192V3
574
        #endif
575
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
576
    #endif /* HAVE_ECC_SECPR3 */
577
    #ifdef HAVE_ECC_KOBLITZ
578
        #ifdef HAVE_OID_ENCODING
579
            #define CODED_SECP192K1    {1,3,132,0,31}
580
            #define CODED_SECP192K1_SZ 5
581
        #else
582
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
583
            #define CODED_SECP192K1_SZ 5
584
        #endif
585
        #ifndef WOLFSSL_ECC_CURVE_STATIC
586
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
587
        #else
588
            #define ecc_oid_secp192k1 CODED_SECP192K1
589
        #endif
590
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
591
    #endif /* HAVE_ECC_KOBLITZ */
592
    #ifdef HAVE_ECC_BRAINPOOL
593
        #ifdef HAVE_OID_ENCODING
594
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
595
            #define CODED_BRAINPOOLP192R1_SZ 10
596
        #else
597
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
598
            #define CODED_BRAINPOOLP192R1_SZ 9
599
        #endif
600
        #ifndef WOLFSSL_ECC_CURVE_STATIC
601
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
602
        #else
603
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
604
        #endif
605
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
606
    #endif /* HAVE_ECC_BRAINPOOL */
607
#endif /* ECC192 */
608
#ifdef ECC224
609
    #ifndef NO_ECC_SECP
610
        #ifdef HAVE_OID_ENCODING
611
            #define CODED_SECP224R1    {1,3,132,0,33}
612
            #define CODED_SECP224R1_SZ 5
613
        #else
614
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
615
            #define CODED_SECP224R1_SZ 5
616
        #endif
617
        #ifndef WOLFSSL_ECC_CURVE_STATIC
618
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
619
        #else
620
            #define ecc_oid_secp224r1 CODED_SECP224R1
621
        #endif
622
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
623
    #endif /* !NO_ECC_SECP */
624
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
625
        #ifdef HAVE_OID_ENCODING
626
            #define CODED_SECP224K1    {1,3,132,0,32}
627
            #define CODED_SECP224K1_SZ 5
628
        #else
629
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
630
            #define CODED_SECP224K1_SZ 5
631
        #endif
632
        #ifndef WOLFSSL_ECC_CURVE_STATIC
633
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
634
        #else
635
            #define ecc_oid_secp224k1 CODED_SECP224K1
636
        #endif
637
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
638
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
639
    #ifdef HAVE_ECC_BRAINPOOL
640
        #ifdef HAVE_OID_ENCODING
641
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
642
            #define CODED_BRAINPOOLP224R1_SZ 10
643
        #else
644
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
645
            #define CODED_BRAINPOOLP224R1_SZ 9
646
        #endif
647
        #ifndef WOLFSSL_ECC_CURVE_STATIC
648
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
649
        #else
650
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
651
        #endif
652
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
653
    #endif /* HAVE_ECC_BRAINPOOL */
654
#endif /* ECC224 */
655
#ifdef ECC239
656
    #ifndef NO_ECC_SECP
657
        #ifdef HAVE_OID_ENCODING
658
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
659
            #define CODED_PRIME239V1_SZ 7
660
        #else
661
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
662
            #define CODED_PRIME239V1_SZ 8
663
        #endif
664
        #ifndef WOLFSSL_ECC_CURVE_STATIC
665
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
666
        #else
667
            #define ecc_oid_prime239v1 CODED_PRIME239V1
668
        #endif
669
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
670
    #endif /* !NO_ECC_SECP */
671
    #ifdef HAVE_ECC_SECPR2
672
        #ifdef HAVE_OID_ENCODING
673
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
674
            #define CODED_PRIME239V2_SZ 7
675
        #else
676
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
677
            #define CODED_PRIME239V2_SZ 8
678
        #endif
679
        #ifndef WOLFSSL_ECC_CURVE_STATIC
680
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
681
        #else
682
            #define ecc_oid_prime239v2 CODED_PRIME239V2
683
        #endif
684
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
685
    #endif /* HAVE_ECC_SECPR2 */
686
    #ifdef HAVE_ECC_SECPR3
687
        #ifdef HAVE_OID_ENCODING
688
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
689
            #define CODED_PRIME239V3_SZ 7
690
        #else
691
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
692
            #define CODED_PRIME239V3_SZ 8
693
        #endif
694
        #ifndef WOLFSSL_ECC_CURVE_STATIC
695
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
696
        #else
697
            #define ecc_oid_prime239v3 CODED_PRIME239V3
698
        #endif
699
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
700
    #endif /* HAVE_ECC_SECPR3 */
701
#endif /* ECC239 */
702
#ifdef ECC256
703
    #ifndef NO_ECC_SECP
704
        #ifdef HAVE_OID_ENCODING
705
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
706
            #define CODED_SECP256R1_SZ 7
707
        #else
708
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
709
            #define CODED_SECP256R1_SZ 8
710
        #endif
711
        #ifndef WOLFSSL_ECC_CURVE_STATIC
712
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
713
        #else
714
            #define ecc_oid_secp256r1 CODED_SECP256R1
715
        #endif
716
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
717
    #endif /* !NO_ECC_SECP */
718
    #ifdef HAVE_ECC_KOBLITZ
719
        #ifdef HAVE_OID_ENCODING
720
            #define CODED_SECP256K1    {1,3,132,0,10}
721
            #define CODED_SECP256K1_SZ 5
722
        #else
723
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
724
            #define CODED_SECP256K1_SZ 5
725
        #endif
726
        #ifndef WOLFSSL_ECC_CURVE_STATIC
727
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
728
        #else
729
            #define ecc_oid_secp256k1 CODED_SECP256K1
730
        #endif
731
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
732
    #endif /* HAVE_ECC_KOBLITZ */
733
    #ifdef HAVE_ECC_BRAINPOOL
734
        #ifdef HAVE_OID_ENCODING
735
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
736
            #define CODED_BRAINPOOLP256R1_SZ 10
737
        #else
738
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
739
            #define CODED_BRAINPOOLP256R1_SZ 9
740
        #endif
741
        #ifndef WOLFSSL_ECC_CURVE_STATIC
742
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
743
        #else
744
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
745
        #endif
746
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
747
    #endif /* HAVE_ECC_BRAINPOOL */
748
#endif /* ECC256 */
749
    #if defined(WOLFSSL_SM2)
750
        #ifdef HAVE_OID_ENCODING
751
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
752
            #define CODED_SM2P256V1_SZ 6
753
        #else
754
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
755
            #define CODED_SM2P256V1_SZ 8
756
        #endif
757
        #ifndef WOLFSSL_ECC_CURVE_STATIC
758
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
759
        #else
760
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
761
        #endif
762
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
763
    #endif /* WOLFSSL_SM2 */
764
#ifdef ECC320
765
    #ifdef HAVE_ECC_BRAINPOOL
766
        #ifdef HAVE_OID_ENCODING
767
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
768
            #define CODED_BRAINPOOLP320R1_SZ 10
769
        #else
770
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
771
            #define CODED_BRAINPOOLP320R1_SZ 9
772
        #endif
773
        #ifndef WOLFSSL_ECC_CURVE_STATIC
774
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
775
        #else
776
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
777
        #endif
778
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
779
    #endif /* HAVE_ECC_BRAINPOOL */
780
#endif /* ECC320 */
781
#ifdef ECC384
782
    #ifndef NO_ECC_SECP
783
        #ifdef HAVE_OID_ENCODING
784
            #define CODED_SECP384R1    {1,3,132,0,34}
785
            #define CODED_SECP384R1_SZ 5
786
        #else
787
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
788
            #define CODED_SECP384R1_SZ 5
789
        #endif
790
        #ifndef WOLFSSL_ECC_CURVE_STATIC
791
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
792
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
793
        #else
794
            #define ecc_oid_secp384r1 CODED_SECP384R1
795
        #endif
796
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
797
    #endif /* !NO_ECC_SECP */
798
    #ifdef HAVE_ECC_BRAINPOOL
799
        #ifdef HAVE_OID_ENCODING
800
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
801
            #define CODED_BRAINPOOLP384R1_SZ 10
802
        #else
803
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
804
            #define CODED_BRAINPOOLP384R1_SZ 9
805
        #endif
806
        #ifndef WOLFSSL_ECC_CURVE_STATIC
807
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
808
        #else
809
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
810
        #endif
811
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
812
    #endif /* HAVE_ECC_BRAINPOOL */
813
#endif /* ECC384 */
814
#ifdef ECC512
815
    #ifdef HAVE_ECC_BRAINPOOL
816
        #ifdef HAVE_OID_ENCODING
817
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
818
            #define CODED_BRAINPOOLP512R1_SZ 10
819
        #else
820
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
821
            #define CODED_BRAINPOOLP512R1_SZ 9
822
        #endif
823
        #ifndef WOLFSSL_ECC_CURVE_STATIC
824
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
825
        #else
826
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
827
        #endif
828
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
829
    #endif /* HAVE_ECC_BRAINPOOL */
830
#endif /* ECC512 */
831
#ifdef ECC521
832
    #ifndef NO_ECC_SECP
833
        #ifdef HAVE_OID_ENCODING
834
            #define CODED_SECP521R1     {1,3,132,0,35}
835
            #define CODED_SECP521R1_SZ 5
836
        #else
837
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
838
            #define CODED_SECP521R1_SZ 5
839
        #endif
840
        #ifndef WOLFSSL_ECC_CURVE_STATIC
841
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
842
        #else
843
            #define ecc_oid_secp521r1 CODED_SECP521R1
844
        #endif
845
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
846
    #endif /* !NO_ECC_SECP */
847
#endif /* ECC521 */
848
849
850
/* This holds the key settings.
851
   ***MUST*** be organized by size from smallest to largest. */
852
853
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
854
    #undef ecc_sets
855
    #undef ecc_sets_count
856
#endif
857
858
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
859
static
860
#endif
861
const ecc_set_type ecc_sets[] = {
862
#ifdef ECC112
863
    #ifndef NO_ECC_SECP
864
    {
865
        14,                             /* size/bytes */
866
        ECC_SECP112R1,                  /* ID         */
867
        "SECP112R1",                    /* curve name */
868
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
869
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
870
        "659EF8BA043916EEDE8911702B22", /* B          */
871
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
872
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
873
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
874
        ecc_oid_secp112r1,              /* oid/oidSz  */
875
        ecc_oid_secp112r1_sz,
876
        ECC_SECP112R1_OID,              /* oid sum    */
877
        1,                              /* cofactor   */
878
    },
879
    #endif /* !NO_ECC_SECP */
880
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
881
    {
882
        14,                             /* size/bytes */
883
        ECC_SECP112R2,                  /* ID         */
884
        "SECP112R2",                    /* curve name */
885
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
886
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
887
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
888
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
889
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
890
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
891
        ecc_oid_secp112r2,              /* oid/oidSz  */
892
        ecc_oid_secp112r2_sz,
893
        ECC_SECP112R2_OID,              /* oid sum    */
894
        4,                              /* cofactor   */
895
    },
896
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
897
#endif /* ECC112 */
898
#ifdef ECC128
899
    #ifndef NO_ECC_SECP
900
    {
901
        16,                                 /* size/bytes */
902
        ECC_SECP128R1,                      /* ID         */
903
        "SECP128R1",                        /* curve name */
904
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
905
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
906
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
907
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
908
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
909
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
910
        ecc_oid_secp128r1,                  /* oid/oidSz  */
911
        ecc_oid_secp128r1_sz,
912
        ECC_SECP128R1_OID,                  /* oid sum    */
913
        1,                                  /* cofactor   */
914
    },
915
    #endif /* !NO_ECC_SECP */
916
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
917
    {
918
        16,                                 /* size/bytes */
919
        ECC_SECP128R2,                      /* ID         */
920
        "SECP128R2",                        /* curve name */
921
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
922
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
923
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
924
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
925
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
926
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
927
        ecc_oid_secp128r2,                  /* oid/oidSz  */
928
        ecc_oid_secp128r2_sz,
929
        ECC_SECP128R2_OID,                  /* oid sum    */
930
        4,                                  /* cofactor   */
931
    },
932
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
933
#endif /* ECC128 */
934
#ifdef ECC160
935
#ifndef FP_ECC
936
    #ifndef NO_ECC_SECP
937
    {
938
        20,                                         /* size/bytes */
939
        ECC_SECP160R1,                              /* ID         */
940
        "SECP160R1",                                /* curve name */
941
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
942
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
943
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
944
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
945
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
946
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
947
        ecc_oid_secp160r1,                          /* oid/oidSz  */
948
        ecc_oid_secp160r1_sz,
949
        ECC_SECP160R1_OID,                          /* oid sum    */
950
        1,                                          /* cofactor   */
951
    },
952
    #endif /* !NO_ECC_SECP */
953
    #ifdef HAVE_ECC_SECPR2
954
    {
955
        20,                                         /* size/bytes */
956
        ECC_SECP160R2,                              /* ID         */
957
        "SECP160R2",                                /* curve name */
958
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
959
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
960
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
961
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
962
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
963
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
964
        ecc_oid_secp160r2,                          /* oid/oidSz  */
965
        ecc_oid_secp160r2_sz,
966
        ECC_SECP160R2_OID,                          /* oid sum    */
967
        1,                                          /* cofactor   */
968
    },
969
    #endif /* HAVE_ECC_SECPR2 */
970
    #ifdef HAVE_ECC_KOBLITZ
971
    {
972
        20,                                         /* size/bytes */
973
        ECC_SECP160K1,                              /* ID         */
974
        "SECP160K1",                                /* curve name */
975
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
976
        "0000000000000000000000000000000000000000", /* A          */
977
        "0000000000000000000000000000000000000007", /* B          */
978
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
979
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
980
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
981
        ecc_oid_secp160k1,                          /* oid/oidSz  */
982
        ecc_oid_secp160k1_sz,
983
        ECC_SECP160K1_OID,                          /* oid sum    */
984
        1,                                          /* cofactor   */
985
    },
986
    #endif /* HAVE_ECC_KOBLITZ */
987
#endif /* !FP_ECC */
988
    #ifdef HAVE_ECC_BRAINPOOL
989
    {
990
        20,                                         /* size/bytes */
991
        ECC_BRAINPOOLP160R1,                        /* ID         */
992
        "BRAINPOOLP160R1",                          /* curve name */
993
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
994
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
995
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
996
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
997
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
998
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
999
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1000
        ecc_oid_brainpoolp160r1_sz,
1001
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1002
        1,                                          /* cofactor   */
1003
    },
1004
    #endif /* HAVE_ECC_BRAINPOOL */
1005
#endif /* ECC160 */
1006
#ifdef ECC192
1007
    #ifndef NO_ECC_SECP
1008
    {
1009
        24,                                                 /* size/bytes */
1010
        ECC_SECP192R1,                                      /* ID         */
1011
        "SECP192R1",                                        /* curve name */
1012
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1013
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1014
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1015
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1016
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1017
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1018
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1019
        ecc_oid_secp192r1_sz,
1020
        ECC_SECP192R1_OID,                                  /* oid sum    */
1021
        1,                                                  /* cofactor   */
1022
    },
1023
    #endif /* !NO_ECC_SECP */
1024
    #ifdef HAVE_ECC_SECPR2
1025
    {
1026
        24,                                                 /* size/bytes */
1027
        ECC_PRIME192V2,                                     /* ID         */
1028
        "PRIME192V2",                                       /* curve name */
1029
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1030
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1031
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1032
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1033
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1034
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1035
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1036
        ecc_oid_prime192v2_sz,
1037
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1038
        1,                                                  /* cofactor   */
1039
    },
1040
    #endif /* HAVE_ECC_SECPR2 */
1041
    #ifdef HAVE_ECC_SECPR3
1042
    {
1043
        24,                                                 /* size/bytes */
1044
        ECC_PRIME192V3,                                     /* ID         */
1045
        "PRIME192V3",                                       /* curve name */
1046
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1047
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1048
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1049
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1050
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1051
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1052
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1053
        ecc_oid_prime192v3_sz,
1054
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1055
        1,                                                  /* cofactor   */
1056
    },
1057
    #endif /* HAVE_ECC_SECPR3 */
1058
    #ifdef HAVE_ECC_KOBLITZ
1059
    {
1060
        24,                                                 /* size/bytes */
1061
        ECC_SECP192K1,                                      /* ID         */
1062
        "SECP192K1",                                        /* curve name */
1063
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1064
        "000000000000000000000000000000000000000000000000", /* A          */
1065
        "000000000000000000000000000000000000000000000003", /* B          */
1066
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1067
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1068
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1069
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1070
        ecc_oid_secp192k1_sz,
1071
        ECC_SECP192K1_OID,                                  /* oid sum    */
1072
        1,                                                  /* cofactor   */
1073
    },
1074
    #endif /* HAVE_ECC_KOBLITZ */
1075
    #ifdef HAVE_ECC_BRAINPOOL
1076
    {
1077
        24,                                                 /* size/bytes */
1078
        ECC_BRAINPOOLP192R1,                                /* ID         */
1079
        "BRAINPOOLP192R1",                                  /* curve name */
1080
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1081
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1082
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1083
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1084
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1085
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1086
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1087
        ecc_oid_brainpoolp192r1_sz,
1088
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1089
        1,                                                  /* cofactor   */
1090
    },
1091
    #endif /* HAVE_ECC_BRAINPOOL */
1092
#endif /* ECC192 */
1093
#ifdef ECC224
1094
    #ifndef NO_ECC_SECP
1095
    {
1096
        28,                                                         /* size/bytes */
1097
        ECC_SECP224R1,                                              /* ID         */
1098
        "SECP224R1",                                                /* curve name */
1099
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1100
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1101
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1102
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1103
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1104
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1105
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1106
        ecc_oid_secp224r1_sz,
1107
        ECC_SECP224R1_OID,                                          /* oid sum    */
1108
        1,                                                          /* cofactor   */
1109
    },
1110
    #endif /* !NO_ECC_SECP */
1111
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1112
    {
1113
        28,                                                         /* size/bytes */
1114
        ECC_SECP224K1,                                              /* ID         */
1115
        "SECP224K1",                                                /* curve name */
1116
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1117
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1118
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1119
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1120
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1121
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1122
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1123
        ecc_oid_secp224k1_sz,
1124
        ECC_SECP224K1_OID,                                          /* oid sum    */
1125
        1,                                                          /* cofactor   */
1126
    },
1127
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1128
    #ifdef HAVE_ECC_BRAINPOOL
1129
    {
1130
        28,                                                         /* size/bytes */
1131
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1132
        "BRAINPOOLP224R1",                                          /* curve name */
1133
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1134
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1135
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1136
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1137
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1138
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1139
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1140
        ecc_oid_brainpoolp224r1_sz,
1141
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1142
        1,                                                          /* cofactor   */
1143
    },
1144
    #endif /* HAVE_ECC_BRAINPOOL */
1145
#endif /* ECC224 */
1146
#ifdef ECC239
1147
    #ifndef NO_ECC_SECP
1148
    {
1149
        30,                                                             /* size/bytes */
1150
        ECC_PRIME239V1,                                                 /* ID         */
1151
        "PRIME239V1",                                                   /* curve name */
1152
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1153
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1154
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1155
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1156
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1157
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1158
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1159
        ecc_oid_prime239v1_sz,
1160
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1161
        1,                                                              /* cofactor   */
1162
    },
1163
    #endif /* !NO_ECC_SECP */
1164
    #ifdef HAVE_ECC_SECPR2
1165
    {
1166
        30,                                                             /* size/bytes */
1167
        ECC_PRIME239V2,                                                 /* ID         */
1168
        "PRIME239V2",                                                   /* curve name */
1169
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1170
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1171
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1172
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1173
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1174
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1175
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1176
        ecc_oid_prime239v2_sz,
1177
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1178
        1,                                                              /* cofactor   */
1179
    },
1180
    #endif /* HAVE_ECC_SECPR2 */
1181
    #ifdef HAVE_ECC_SECPR3
1182
    {
1183
        30,                                                             /* size/bytes */
1184
        ECC_PRIME239V3,                                                 /* ID         */
1185
        "PRIME239V3",                                                   /* curve name */
1186
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1187
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1188
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1189
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1190
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1191
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1192
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1193
        ecc_oid_prime239v3_sz,
1194
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1195
        1,                                                              /* cofactor   */
1196
    },
1197
    #endif /* HAVE_ECC_SECPR3 */
1198
#endif /* ECC239 */
1199
#ifdef ECC256
1200
    #ifndef NO_ECC_SECP
1201
    {
1202
        32,                                                                 /* size/bytes */
1203
        ECC_SECP256R1,                                                      /* ID         */
1204
        "SECP256R1",                                                        /* curve name */
1205
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1206
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1207
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1208
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1209
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1210
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1211
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1212
        ecc_oid_secp256r1_sz,
1213
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1214
        1,                                                                  /* cofactor   */
1215
    },
1216
    #endif /* !NO_ECC_SECP */
1217
    #ifdef HAVE_ECC_KOBLITZ
1218
    {
1219
        32,                                                                 /* size/bytes */
1220
        ECC_SECP256K1,                                                      /* ID         */
1221
        "SECP256K1",                                                        /* curve name */
1222
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1223
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1224
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1225
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1226
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1227
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1228
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1229
        ecc_oid_secp256k1_sz,
1230
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1231
        1,                                                                  /* cofactor   */
1232
    },
1233
    #endif /* HAVE_ECC_KOBLITZ */
1234
    #ifdef HAVE_ECC_BRAINPOOL
1235
    {
1236
        32,                                                                 /* size/bytes */
1237
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1238
        "BRAINPOOLP256R1",                                                  /* curve name */
1239
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1240
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1241
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1242
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1243
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1244
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1245
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1246
        ecc_oid_brainpoolp256r1_sz,
1247
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1248
        1,                                                                  /* cofactor   */
1249
    },
1250
    #endif /* HAVE_ECC_BRAINPOOL */
1251
#endif /* ECC256 */
1252
    #if defined(WOLFSSL_SM2)
1253
    {
1254
        32,                                                     /* size/bytes */
1255
        ECC_SM2P256V1,                                          /* ID         */
1256
        "SM2P256V1",                                            /* curve name */
1257
1258
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1259
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1260
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1261
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1262
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1263
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1264
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1265
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1266
        ecc_oid_sm2p256v1_sz,
1267
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1268
        1,                                                      /* cofactor   */
1269
    },
1270
    #endif /* WOLFSSL_SM2 */
1271
#ifdef ECC320
1272
    #ifdef HAVE_ECC_BRAINPOOL
1273
    {
1274
        40,                                                                                 /* size/bytes */
1275
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1276
        "BRAINPOOLP320R1",                                                                  /* curve name */
1277
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1278
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1279
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1280
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1281
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1282
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1283
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1284
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1285
        1,                                                                                  /* cofactor   */
1286
    },
1287
    #endif /* HAVE_ECC_BRAINPOOL */
1288
#endif /* ECC320 */
1289
#ifdef ECC384
1290
    #ifndef NO_ECC_SECP
1291
    {
1292
        48,                                                                                                 /* size/bytes */
1293
        ECC_SECP384R1,                                                                                      /* ID         */
1294
        "SECP384R1",                                                                                        /* curve name */
1295
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1296
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1297
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1298
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1299
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1300
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1301
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1302
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1303
        1,                                                                                                  /* cofactor   */
1304
    },
1305
    #endif /* !NO_ECC_SECP */
1306
    #ifdef HAVE_ECC_BRAINPOOL
1307
    {
1308
        48,                                                                                                 /* size/bytes */
1309
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1310
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1311
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1312
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1313
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1314
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1315
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1316
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1317
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1318
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1319
        1,                                                                                                  /* cofactor   */
1320
    },
1321
    #endif /* HAVE_ECC_BRAINPOOL */
1322
#endif /* ECC384 */
1323
#ifdef ECC512
1324
    #ifdef HAVE_ECC_BRAINPOOL
1325
    {
1326
        64,                                                                                                                                 /* size/bytes */
1327
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1328
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1329
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1330
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1331
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1332
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1333
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1334
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1335
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1336
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1337
        1,                                                                                                                                  /* cofactor   */
1338
    },
1339
    #endif /* HAVE_ECC_BRAINPOOL */
1340
#endif /* ECC512 */
1341
#ifdef ECC521
1342
    #ifndef NO_ECC_SECP
1343
    {
1344
        66,                                                                                                                                    /* size/bytes */
1345
        ECC_SECP521R1,                                                                                                                         /* ID         */
1346
        "SECP521R1",                                                                                                                           /* curve name */
1347
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1348
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1349
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1350
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1351
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1352
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1353
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1354
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1355
        1,                                                                                                                                     /* cofactor   */
1356
    },
1357
    #endif /* !NO_ECC_SECP */
1358
#endif /* ECC521 */
1359
#ifdef WOLFCRYPT_HAVE_SAKKE
1360
    {
1361
        128,
1362
        ECC_SAKKE_1,
1363
        "SAKKE1",
1364
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1365
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1366
        "0",
1367
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1368
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1369
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1370
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1371
            NULL, 0,
1372
        #else
1373
            {0}, 0,
1374
        #endif
1375
        0,
1376
        4,
1377
    },
1378
#endif
1379
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1380
    /* place holder for custom curve index for cache */
1381
    {
1382
        1, /* non-zero */
1383
        ECC_CURVE_CUSTOM,
1384
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1385
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1386
        #else
1387
            {0},{0},{0},{0},{0},{0},{0},{0},
1388
        #endif
1389
        0, 0, 0
1390
    },
1391
#endif
1392
    {
1393
        0,
1394
        ECC_CURVE_INVALID,
1395
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1396
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1397
        #else
1398
            {0},{0},{0},{0},{0},{0},{0},{0},
1399
        #endif
1400
        0, 0, 0
1401
    }
1402
};
1403
78.1k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1404
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1405
static
1406
#endif
1407
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1408
1409
220k
const ecc_set_type *wc_ecc_get_sets(void) {
1410
220k
    return ecc_sets;
1411
220k
}
1412
0
size_t wc_ecc_get_sets_count(void) {
1413
0
    return ecc_sets_count;
1414
0
}
1415
1416
#ifdef HAVE_OID_ENCODING
1417
    /* encoded OID cache */
1418
    typedef struct {
1419
        word32 oidSz;
1420
        byte oid[ECC_MAX_OID_LEN];
1421
    } oid_cache_t;
1422
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1423
1424
    static wolfSSL_Mutex ecc_oid_cache_lock
1425
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1426
#ifndef WOLFSSL_MUTEX_INITIALIZER
1427
    static volatile int eccOidLockInit = 0;
1428
#endif
1429
#endif /* HAVE_OID_ENCODING */
1430
1431
/* Forward declarations */
1432
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1433
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1434
#endif
1435
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1436
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1437
    mp_int* prime, mp_int* order);
1438
#endif
1439
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1440
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1441
    !defined(WOLFSSL_KCAPI_ECC)
1442
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1443
#endif
1444
1445
1446
#ifdef HAVE_COMP_KEY
1447
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1448
    !defined(WOLFSSL_CRYPTOCELL)
1449
1450
#ifndef WOLFSSL_SP_MATH
1451
#if !defined(SQRTMOD_USE_MOD_EXP)
1452
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1453
#endif
1454
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1455
#endif
1456
#endif
1457
#endif
1458
1459
1460
/* Curve Specs */
1461
typedef struct ecc_curve_spec {
1462
    const ecc_set_type* dp;
1463
1464
    mp_int* prime;
1465
    mp_int* Af;
1466
    #ifdef USE_ECC_B_PARAM
1467
        mp_int* Bf;
1468
    #endif
1469
    mp_int* order;
1470
    mp_int* Gx;
1471
    mp_int* Gy;
1472
1473
#ifdef ECC_CACHE_CURVE
1474
    mp_int prime_lcl;
1475
    mp_int Af_lcl;
1476
    #ifdef USE_ECC_B_PARAM
1477
        mp_int Bf_lcl;
1478
    #endif
1479
    mp_int order_lcl;
1480
    mp_int Gx_lcl;
1481
    mp_int Gy_lcl;
1482
#else
1483
#ifdef WOLFSSL_SP_MATH_ALL
1484
    unsigned char* spec_ints;
1485
#else
1486
    mp_int* spec_ints;
1487
#endif
1488
    word32 spec_count;
1489
    word32 spec_use;
1490
#endif
1491
1492
    byte load_mask;
1493
} ecc_curve_spec;
1494
1495
    #define ECC_CURVE_FIELD_NONE    0x00
1496
265k
    #define ECC_CURVE_FIELD_PRIME   0x01
1497
265k
    #define ECC_CURVE_FIELD_AF      0x02
1498
#ifdef USE_ECC_B_PARAM
1499
262k
    #define ECC_CURVE_FIELD_BF      0x04
1500
#endif
1501
239k
    #define ECC_CURVE_FIELD_ORDER   0x08
1502
196k
    #define ECC_CURVE_FIELD_GX      0x10
1503
196k
    #define ECC_CURVE_FIELD_GY      0x20
1504
#ifdef USE_ECC_B_PARAM
1505
20.9k
    #define ECC_CURVE_FIELD_ALL     0x3F
1506
    #define ECC_CURVE_FIELD_COUNT   6
1507
#else
1508
    #define ECC_CURVE_FIELD_ALL     0x3B
1509
    #define ECC_CURVE_FIELD_COUNT   5
1510
#endif
1511
1512
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1513
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1514
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1515
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1516
};
1517
1518
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1519
{
1520
    word32 up, down;
1521
    up = 0;
1522
    down = len - 1;
1523
    while (up < len)
1524
        outbuf[up++] = inbuf[down--];
1525
}
1526
1527
static int xil_mpi_import(mp_int *mpi,
1528
                          const byte *inbuf,
1529
                          word32 len,
1530
                          void* heap)
1531
{
1532
    int err;
1533
#ifdef WOLFSSL_SMALL_STACK
1534
    byte* buf = NULL;
1535
#else
1536
    byte buf[MAX_ECC_BYTES];
1537
1538
    if (len > MAX_ECC_BYTES)
1539
        return BUFFER_E;
1540
#endif
1541
1542
    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
1543
        return MEMORY_E);
1544
    buf_reverse(buf, inbuf, len);
1545
1546
    err = mp_read_unsigned_bin(mpi, buf, len);
1547
    ForceZero(buf, len);
1548
    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1549
    return err;
1550
}
1551
#endif
1552
1553
#ifdef ECC_CACHE_CURVE
1554
    /* cache (mp_int) of the curve parameters */
1555
    #ifdef WOLFSSL_NO_MALLOC
1556
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1557
    #else
1558
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1559
    #endif
1560
    #ifndef SINGLE_THREADED
1561
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1562
    #endif
1563
1564
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1565
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1566
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1567
#elif defined(WOLFSSL_SMALL_STACK)
1568
#ifdef WOLFSSL_SP_MATH_ALL
1569
    #define DECLARE_CURVE_SPECS(intcount)                               \
1570
40.0k
        unsigned char* spec_ints = NULL;                                \
1571
40.0k
        ecc_curve_spec curve_lcl;                                       \
1572
40.0k
        ecc_curve_spec* curve = &curve_lcl;                             \
1573
40.0k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1574
40.0k
        curve->spec_count = intcount
1575
1576
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1577
39.9k
    do {                                                                \
1578
39.9k
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1579
39.9k
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1580
39.9k
            DYNAMIC_TYPE_ECC);                                          \
1581
39.9k
        if (spec_ints == NULL)                                          \
1582
39.9k
            (err) = MEMORY_E;                                           \
1583
39.9k
        else {                                                          \
1584
39.2k
            curve->spec_ints = spec_ints;                               \
1585
39.2k
            (err) = MP_OKAY;                                            \
1586
39.2k
        }                                                               \
1587
39.9k
    } while (0)
1588
#else
1589
    #define DECLARE_CURVE_SPECS(intcount)                               \
1590
        mp_int* spec_ints = NULL;                                       \
1591
        ecc_curve_spec curve_lcl;                                       \
1592
        ecc_curve_spec* curve = &curve_lcl;                             \
1593
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1594
        curve->spec_count = intcount
1595
1596
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1597
    do {                                                                \
1598
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1599
                            DYNAMIC_TYPE_ECC);                          \
1600
        if (spec_ints == NULL)                                          \
1601
            (err) = MEMORY_E;                                           \
1602
        else {                                                          \
1603
            curve->spec_ints = spec_ints;                               \
1604
            (err) = MP_OKAY;                                            \
1605
        }                                                               \
1606
    } while (0)
1607
#endif
1608
    #define FREE_CURVE_SPECS()                                          \
1609
39.9k
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1610
#else
1611
#ifdef WOLFSSL_SP_MATH_ALL
1612
    #define DECLARE_CURVE_SPECS(intcount)                               \
1613
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1614
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1615
        ecc_curve_spec curve_lcl;                                       \
1616
        ecc_curve_spec* curve = &curve_lcl;                             \
1617
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1618
        curve->spec_ints = spec_ints;                                   \
1619
        curve->spec_count = (intcount)
1620
#else
1621
    #define DECLARE_CURVE_SPECS(intcount)                               \
1622
        mp_int spec_ints[(intcount)];                                   \
1623
        ecc_curve_spec curve_lcl;                                       \
1624
        ecc_curve_spec* curve = &curve_lcl;                             \
1625
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1626
        curve->spec_ints = spec_ints;                                   \
1627
        curve->spec_count = (intcount)
1628
#endif
1629
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1630
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1631
#endif /* ECC_CACHE_CURVE */
1632
1633
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1634
    byte mask)
1635
286k
{
1636
286k
    if (item) {
1637
    #ifdef HAVE_WOLF_BIGINT
1638
        wc_bigint_free(&item->raw);
1639
    #endif
1640
286k
        mp_clear(item);
1641
286k
    }
1642
286k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1643
286k
}
1644
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1645
69.3k
{
1646
69.3k
    if (curve == NULL) {
1647
0
        return;
1648
0
    }
1649
1650
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1651
57.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1652
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1653
57.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1654
69.3k
#ifdef USE_ECC_B_PARAM
1655
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1656
55.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1657
69.3k
#endif
1658
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1659
47.9k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1660
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1661
29.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1662
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1663
29.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1664
1665
69.3k
    curve->load_mask = 0;
1666
69.3k
}
1667
1668
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1669
71.8k
{
1670
71.8k
    if (curve) {
1671
    #ifdef ECC_CACHE_CURVE
1672
        #ifdef WOLFSSL_CUSTOM_CURVES
1673
        /* only free custom curves (rest are globally cached) */
1674
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1675
            wc_ecc_curve_cache_free_spec(curve);
1676
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1677
        }
1678
        #endif
1679
    #else
1680
71.8k
        wc_ecc_curve_cache_free_spec(curve);
1681
71.8k
    #endif
1682
71.8k
    }
1683
71.8k
}
1684
1685
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1686
    mp_int** dst, byte mask)
1687
202k
{
1688
202k
    int err;
1689
1690
202k
#ifndef ECC_CACHE_CURVE
1691
    /* get mp_int from temp */
1692
202k
    if (curve->spec_use >= curve->spec_count) {
1693
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1694
0
        return ECC_BAD_ARG_E;
1695
0
    }
1696
202k
#ifdef WOLFSSL_SP_MATH_ALL
1697
202k
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1698
202k
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1699
#else
1700
    *dst = &curve->spec_ints[curve->spec_use++];
1701
#endif
1702
202k
#endif
1703
1704
202k
#ifdef WOLFSSL_SP_MATH_ALL
1705
202k
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1706
#else
1707
    err = mp_init(*dst);
1708
#endif
1709
202k
    if (err == MP_OKAY) {
1710
202k
        curve->load_mask |= mask;
1711
1712
202k
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1713
1714
    #ifdef HAVE_WOLF_BIGINT
1715
        if (err == MP_OKAY)
1716
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1717
    #endif
1718
202k
    }
1719
202k
    return err;
1720
202k
}
1721
1722
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1723
    byte load_mask)
1724
67.7k
{
1725
67.7k
    int ret = 0;
1726
67.7k
    ecc_curve_spec* curve;
1727
67.7k
    byte load_items = 0; /* mask of items to load */
1728
#ifdef ECC_CACHE_CURVE
1729
    int x;
1730
#endif
1731
1732
67.7k
    if (dp == NULL || pCurve == NULL)
1733
0
        return BAD_FUNC_ARG;
1734
1735
#ifdef ECC_CACHE_CURVE
1736
    x = wc_ecc_get_curve_idx(dp->id);
1737
    if (x == ECC_CURVE_INVALID)
1738
        return ECC_BAD_ARG_E;
1739
1740
#if !defined(SINGLE_THREADED)
1741
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1742
    if (ret != 0) {
1743
        return ret;
1744
    }
1745
#endif
1746
1747
#ifdef WOLFSSL_NO_MALLOC
1748
    curve = &ecc_curve_spec_cache[x];
1749
#else
1750
    /* make sure cache has been allocated */
1751
    if (ecc_curve_spec_cache[x] == NULL
1752
    #ifdef WOLFSSL_CUSTOM_CURVES
1753
        || dp->id == ECC_CURVE_CUSTOM
1754
    #endif
1755
    ) {
1756
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1757
        if (curve == NULL) {
1758
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1759
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1760
        #endif
1761
            return MEMORY_E;
1762
        }
1763
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1764
1765
        /* set curve pointer to cache */
1766
    #ifdef WOLFSSL_CUSTOM_CURVES
1767
        if (dp->id != ECC_CURVE_CUSTOM)
1768
    #endif
1769
        {
1770
            ecc_curve_spec_cache[x] = curve;
1771
        }
1772
    }
1773
    else {
1774
        curve = ecc_curve_spec_cache[x];
1775
    }
1776
#endif /* WOLFSSL_NO_MALLOC */
1777
1778
    /* return new or cached curve */
1779
    *pCurve = curve;
1780
#else
1781
67.7k
    curve = *pCurve;
1782
67.7k
#endif /* ECC_CACHE_CURVE */
1783
1784
    /* make sure the curve is initialized */
1785
67.7k
    if (curve->dp != dp) {
1786
67.7k
        curve->load_mask = 0;
1787
1788
    #ifdef ECC_CACHE_CURVE
1789
        curve->prime = &curve->prime_lcl;
1790
        curve->Af = &curve->Af_lcl;
1791
        #ifdef USE_ECC_B_PARAM
1792
            curve->Bf = &curve->Bf_lcl;
1793
        #endif
1794
        curve->order = &curve->order_lcl;
1795
        curve->Gx = &curve->Gx_lcl;
1796
        curve->Gy = &curve->Gy_lcl;
1797
    #endif
1798
67.7k
    }
1799
67.7k
    curve->dp = dp; /* set dp info */
1800
1801
    /* determine items to load */
1802
67.7k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1803
67.7k
    curve->load_mask |= load_items;
1804
1805
    /* load items */
1806
67.7k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1807
57.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1808
57.2k
            ECC_CURVE_FIELD_PRIME);
1809
67.7k
    if (load_items & ECC_CURVE_FIELD_AF)
1810
57.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1811
57.2k
            ECC_CURVE_FIELD_AF);
1812
67.7k
#ifdef USE_ECC_B_PARAM
1813
67.7k
    if (load_items & ECC_CURVE_FIELD_BF)
1814
55.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1815
55.8k
            ECC_CURVE_FIELD_BF);
1816
67.7k
#endif
1817
67.7k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1818
47.9k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1819
47.9k
            ECC_CURVE_FIELD_ORDER);
1820
67.7k
    if (load_items & ECC_CURVE_FIELD_GX)
1821
29.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1822
29.8k
            ECC_CURVE_FIELD_GX);
1823
67.7k
    if (load_items & ECC_CURVE_FIELD_GY)
1824
29.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1825
29.8k
            ECC_CURVE_FIELD_GY);
1826
1827
    /* check for error */
1828
67.7k
    if (ret != 0) {
1829
182
        wc_ecc_curve_free(curve);
1830
182
        ret = MP_READ_E;
1831
182
    }
1832
1833
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1834
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1835
#endif
1836
1837
67.7k
    return ret;
1838
67.7k
}
1839
1840
#ifdef ECC_CACHE_CURVE
1841
int wc_ecc_curve_cache_init(void)
1842
{
1843
    int ret = 0;
1844
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1845
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1846
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1847
#endif
1848
    return ret;
1849
}
1850
1851
void wc_ecc_curve_cache_free(void)
1852
{
1853
    int x;
1854
1855
    /* free all ECC curve caches */
1856
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1857
    #ifdef WOLFSSL_NO_MALLOC
1858
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1859
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1860
    #else
1861
        if (ecc_curve_spec_cache[x]) {
1862
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1863
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1864
            ecc_curve_spec_cache[x] = NULL;
1865
        }
1866
    #endif /* WOLFSSL_NO_MALLOC */
1867
    }
1868
1869
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1870
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1871
    wc_FreeMutex(&ecc_curve_cache_mutex);
1872
#endif
1873
}
1874
#endif /* ECC_CACHE_CURVE */
1875
1876
1877
/* Retrieve the curve name for the ECC curve id.
1878
 *
1879
 * curve_id  The id of the curve.
1880
 * returns the name stored from the curve if available, otherwise NULL.
1881
 */
1882
const char* wc_ecc_get_name(int curve_id)
1883
11.8k
{
1884
11.8k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1885
11.8k
    if (curve_idx == ECC_CURVE_INVALID)
1886
48
        return NULL;
1887
11.8k
    return ecc_sets[curve_idx].name;
1888
11.8k
}
1889
1890
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1891
56.9k
{
1892
56.9k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1893
0
        return BAD_FUNC_ARG;
1894
0
    }
1895
1896
56.9k
    if (keysize > ECC_MAXSIZE) {
1897
847
        return ECC_BAD_ARG_E;
1898
847
    }
1899
1900
    /* handle custom case */
1901
56.0k
    if (key->idx != ECC_CUSTOM_IDX) {
1902
55.9k
        int x;
1903
1904
        /* default values */
1905
55.9k
        key->idx = 0;
1906
55.9k
        key->dp = NULL;
1907
1908
        /* find ecc_set based on curve_id or key size */
1909
822k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1910
822k
            if (curve_id > ECC_CURVE_DEF) {
1911
717k
                if (curve_id == ecc_sets[x].id)
1912
50.4k
                  break;
1913
717k
            }
1914
105k
            else if (keysize <= ecc_sets[x].size) {
1915
5.31k
                break;
1916
5.31k
            }
1917
822k
        }
1918
55.9k
        if (ecc_sets[x].size == 0) {
1919
192
            WOLFSSL_MSG("ECC Curve not found");
1920
192
            return ECC_CURVE_OID_E;
1921
192
        }
1922
1923
55.7k
        key->idx = x;
1924
55.7k
        key->dp  = &ecc_sets[x];
1925
55.7k
    }
1926
1927
55.8k
    return 0;
1928
56.0k
}
1929
1930
1931
#ifdef ALT_ECC_SIZE
1932
static void alt_fp_init(mp_int* a)
1933
{
1934
    a->size = FP_SIZE_ECC;
1935
    mp_zero(a);
1936
}
1937
#endif /* ALT_ECC_SIZE */
1938
1939
1940
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1941
    !defined(WOLFSSL_CRYPTOCELL) && \
1942
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
1943
      defined(WOLFSSL_IMXRT1170_CAAM))
1944
1945
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
1946
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
1947
                                     mp_int* modulus, mp_digit mp);
1948
1949
/**
1950
   Add two ECC points
1951
   P        The point to add
1952
   Q        The point to add
1953
   R        [out] The destination of the double
1954
   a        ECC curve parameter a
1955
   modulus  The modulus of the field the ECC curve is in
1956
   mp       The "b" value from montgomery_setup()
1957
   return   MP_OKAY on success
1958
*/
1959
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
1960
                                     mp_int* a, mp_int* modulus, mp_digit mp)
1961
6.29M
{
1962
6.29M
#if !defined(WOLFSSL_SP_MATH)
1963
6.29M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1964
6.29M
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1965
#ifdef ALT_ECC_SIZE
1966
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1967
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1968
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1969
#endif
1970
6.29M
   mp_int  *x, *y, *z;
1971
6.29M
   int     err;
1972
1973
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1974
6.29M
   if (Q == R) {
1975
0
      ecc_point* tPt  = P;
1976
0
      P = Q;
1977
0
      Q = tPt;
1978
0
   }
1979
1980
6.29M
#ifdef WOLFSSL_SMALL_STACK
1981
#ifdef WOLFSSL_SMALL_STACK_CACHE
1982
   if (R->key != NULL) {
1983
       t1 = R->key->t1;
1984
       t2 = R->key->t2;
1985
#ifdef ALT_ECC_SIZE
1986
       rx = R->key->x;
1987
       ry = R->key->y;
1988
       rz = R->key->z;
1989
#endif
1990
   }
1991
   else
1992
#endif /* WOLFSSL_SMALL_STACK_CACHE */
1993
6.29M
#endif /* WOLFSSL_SMALL_STACK */
1994
6.29M
   {
1995
6.29M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1996
6.29M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1997
6.29M
   #ifdef MP_INT_SIZE_CHECK_NULL
1998
6.29M
      if (t1 == NULL || t2 == NULL) {
1999
174
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2000
174
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2001
174
         return MEMORY_E;
2002
174
      }
2003
6.29M
   #endif
2004
#ifdef ALT_ECC_SIZE
2005
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2006
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2007
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2008
   #ifdef MP_INT_SIZE_CHECK_NULL
2009
      if (rx == NULL || ry == NULL || rz == NULL) {
2010
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2011
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2012
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2013
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2014
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2015
         return MEMORY_E;
2016
      }
2017
   #endif
2018
#endif
2019
6.29M
   }
2020
2021
6.29M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2022
6.29M
   if (err == MP_OKAY) {
2023
6.29M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2024
6.29M
   }
2025
6.29M
   if (err != MP_OKAY) {
2026
0
#ifdef WOLFSSL_SMALL_STACK
2027
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2028
      if (R->key == NULL)
2029
   #endif
2030
0
#endif
2031
0
      {
2032
      #ifdef ALT_ECC_SIZE
2033
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2034
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2035
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2036
      #endif
2037
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2038
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2039
0
      }
2040
0
      return err;
2041
0
   }
2042
2043
   /* should we dbl instead? */
2044
6.29M
   if (err == MP_OKAY) {
2045
6.29M
#ifdef ECC_TIMING_RESISTANT
2046
6.29M
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2047
#else
2048
      err = mp_sub(modulus, Q->y, t1);
2049
#endif
2050
6.29M
   }
2051
6.29M
   if (err == MP_OKAY) {
2052
6.29M
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2053
9.41k
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2054
283
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2055
224
          mp_clear(t1);
2056
224
          mp_clear(t2);
2057
224
   #ifdef WOLFSSL_SMALL_STACK
2058
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2059
         if (R->key == NULL)
2060
      #endif
2061
224
   #endif
2062
224
         {
2063
         #ifdef ALT_ECC_SIZE
2064
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2065
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2066
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2067
         #endif
2068
224
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2069
224
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2070
224
         }
2071
224
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2072
224
      }
2073
6.29M
   }
2074
2075
6.29M
   if (err != MP_OKAY) {
2076
0
      goto done;
2077
0
   }
2078
2079
/* If use ALT_ECC_SIZE we need to use local stack variable since
2080
   ecc_point x,y,z is reduced size */
2081
#ifdef ALT_ECC_SIZE
2082
   /* Use local stack variable */
2083
   x = rx;
2084
   y = ry;
2085
   z = rz;
2086
2087
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2088
   if (err == MP_OKAY) {
2089
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2090
   }
2091
   if (err == MP_OKAY) {
2092
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2093
   }
2094
   if (err != MP_OKAY) {
2095
      goto done;
2096
   }
2097
#else
2098
   /* Use destination directly */
2099
6.29M
   x = R->x;
2100
6.29M
   y = R->y;
2101
6.29M
   z = R->z;
2102
6.29M
#endif
2103
2104
6.29M
   if (err == MP_OKAY)
2105
6.29M
       err = mp_copy(P->x, x);
2106
6.29M
   if (err == MP_OKAY)
2107
6.29M
       err = mp_copy(P->y, y);
2108
6.29M
   if (err == MP_OKAY)
2109
6.29M
       err = mp_copy(P->z, z);
2110
2111
   /* if Z is one then these are no-operations */
2112
6.29M
   if (err == MP_OKAY) {
2113
6.29M
       if (!mp_iszero(Q->z)) {
2114
           /* T1 = Z' * Z' */
2115
6.29M
           err = mp_sqr(Q->z, t1);
2116
6.29M
           if (err == MP_OKAY)
2117
6.29M
               err = mp_montgomery_reduce(t1, modulus, mp);
2118
2119
           /* X = X * T1 */
2120
6.29M
           if (err == MP_OKAY)
2121
6.29M
               err = mp_mul(t1, x, x);
2122
6.29M
           if (err == MP_OKAY)
2123
6.29M
               err = mp_montgomery_reduce(x, modulus, mp);
2124
2125
           /* T1 = Z' * T1 */
2126
6.29M
           if (err == MP_OKAY)
2127
6.29M
               err = mp_mul(Q->z, t1, t1);
2128
6.29M
           if (err == MP_OKAY)
2129
6.29M
               err = mp_montgomery_reduce(t1, modulus, mp);
2130
2131
           /* Y = Y * T1 */
2132
6.29M
           if (err == MP_OKAY)
2133
6.29M
               err = mp_mul(t1, y, y);
2134
6.29M
           if (err == MP_OKAY)
2135
6.29M
               err = mp_montgomery_reduce(y, modulus, mp);
2136
6.29M
       }
2137
6.29M
   }
2138
2139
   /* T1 = Z*Z */
2140
6.29M
   if (err == MP_OKAY)
2141
6.29M
       err = mp_sqr(z, t1);
2142
6.29M
   if (err == MP_OKAY)
2143
6.29M
       err = mp_montgomery_reduce(t1, modulus, mp);
2144
2145
   /* T2 = X' * T1 */
2146
6.29M
   if (err == MP_OKAY)
2147
6.29M
       err = mp_mul(Q->x, t1, t2);
2148
6.29M
   if (err == MP_OKAY)
2149
6.29M
       err = mp_montgomery_reduce(t2, modulus, mp);
2150
2151
   /* T1 = Z * T1 */
2152
6.29M
   if (err == MP_OKAY)
2153
6.29M
       err = mp_mul(z, t1, t1);
2154
6.29M
   if (err == MP_OKAY)
2155
6.29M
       err = mp_montgomery_reduce(t1, modulus, mp);
2156
2157
   /* T1 = Y' * T1 */
2158
6.29M
   if (err == MP_OKAY)
2159
6.29M
       err = mp_mul(Q->y, t1, t1);
2160
6.29M
   if (err == MP_OKAY)
2161
6.29M
       err = mp_montgomery_reduce(t1, modulus, mp);
2162
2163
   /* Y = Y - T1 */
2164
6.29M
   if (err == MP_OKAY)
2165
6.29M
       err = mp_submod_ct(y, t1, modulus, y);
2166
   /* T1 = 2T1 */
2167
6.29M
   if (err == MP_OKAY)
2168
6.29M
       err = mp_addmod_ct(t1, t1, modulus, t1);
2169
   /* T1 = Y + T1 */
2170
6.29M
   if (err == MP_OKAY)
2171
6.29M
       err = mp_addmod_ct(t1, y, modulus, t1);
2172
   /* X = X - T2 */
2173
6.29M
   if (err == MP_OKAY)
2174
6.29M
       err = mp_submod_ct(x, t2, modulus, x);
2175
   /* T2 = 2T2 */
2176
6.29M
   if (err == MP_OKAY)
2177
6.29M
       err = mp_addmod_ct(t2, t2, modulus, t2);
2178
   /* T2 = X + T2 */
2179
6.29M
   if (err == MP_OKAY)
2180
6.29M
       err = mp_addmod_ct(t2, x, modulus, t2);
2181
2182
6.29M
   if (err == MP_OKAY) {
2183
6.29M
       if (!mp_iszero(Q->z)) {
2184
           /* Z = Z * Z' */
2185
6.29M
           err = mp_mul(z, Q->z, z);
2186
6.29M
           if (err == MP_OKAY)
2187
6.29M
               err = mp_montgomery_reduce(z, modulus, mp);
2188
6.29M
       }
2189
6.29M
   }
2190
2191
   /* Z = Z * X */
2192
6.29M
   if (err == MP_OKAY)
2193
6.29M
       err = mp_mul(z, x, z);
2194
6.29M
   if (err == MP_OKAY)
2195
6.29M
       err = mp_montgomery_reduce(z, modulus, mp);
2196
2197
   /* T1 = T1 * X  */
2198
6.29M
   if (err == MP_OKAY)
2199
6.29M
       err = mp_mul(t1, x, t1);
2200
6.29M
   if (err == MP_OKAY)
2201
6.29M
       err = mp_montgomery_reduce(t1, modulus, mp);
2202
2203
   /* X = X * X */
2204
6.29M
   if (err == MP_OKAY)
2205
6.29M
       err = mp_sqr(x, x);
2206
6.29M
   if (err == MP_OKAY)
2207
6.29M
       err = mp_montgomery_reduce(x, modulus, mp);
2208
2209
   /* T2 = T2 * x */
2210
6.29M
   if (err == MP_OKAY)
2211
6.29M
       err = mp_mul(t2, x, t2);
2212
6.29M
   if (err == MP_OKAY)
2213
6.29M
       err = mp_montgomery_reduce(t2, modulus, mp);
2214
2215
   /* T1 = T1 * X  */
2216
6.29M
   if (err == MP_OKAY)
2217
6.29M
       err = mp_mul(t1, x, t1);
2218
6.29M
   if (err == MP_OKAY)
2219
6.29M
       err = mp_montgomery_reduce(t1, modulus, mp);
2220
2221
   /* X = Y*Y */
2222
6.29M
   if (err == MP_OKAY)
2223
6.29M
       err = mp_sqr(y, x);
2224
6.29M
   if (err == MP_OKAY)
2225
6.29M
       err = mp_montgomery_reduce(x, modulus, mp);
2226
2227
   /* X = X - T2 */
2228
6.29M
   if (err == MP_OKAY)
2229
6.29M
       err = mp_submod_ct(x, t2, modulus, x);
2230
   /* T2 = T2 - X */
2231
6.29M
   if (err == MP_OKAY)
2232
6.29M
       err = mp_submod_ct(t2, x, modulus, t2);
2233
   /* T2 = T2 - X */
2234
6.29M
   if (err == MP_OKAY)
2235
6.29M
       err = mp_submod_ct(t2, x, modulus, t2);
2236
   /* T2 = T2 * Y */
2237
6.29M
   if (err == MP_OKAY)
2238
6.29M
       err = mp_mul(t2, y, t2);
2239
6.29M
   if (err == MP_OKAY)
2240
6.29M
       err = mp_montgomery_reduce(t2, modulus, mp);
2241
2242
   /* Y = T2 - T1 */
2243
6.29M
   if (err == MP_OKAY)
2244
6.29M
       err = mp_submod_ct(t2, t1, modulus, y);
2245
   /* Y = Y/2 */
2246
6.29M
   if (err == MP_OKAY)
2247
6.29M
       err = mp_div_2_mod_ct(y, modulus, y);
2248
2249
#ifdef ALT_ECC_SIZE
2250
   if (err == MP_OKAY)
2251
       err = mp_copy(x, R->x);
2252
   if (err == MP_OKAY)
2253
       err = mp_copy(y, R->y);
2254
   if (err == MP_OKAY)
2255
       err = mp_copy(z, R->z);
2256
#endif
2257
2258
6.29M
done:
2259
2260
   /* clean up */
2261
6.29M
   mp_clear(t1);
2262
6.29M
   mp_clear(t2);
2263
6.29M
#ifdef WOLFSSL_SMALL_STACK
2264
#ifdef WOLFSSL_SMALL_STACK_CACHE
2265
   if (R->key == NULL)
2266
#endif
2267
6.29M
#endif
2268
6.29M
   {
2269
   #ifdef ALT_ECC_SIZE
2270
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2271
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2272
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2273
   #endif
2274
6.29M
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2275
6.29M
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2276
6.29M
   }
2277
2278
6.29M
   return err;
2279
#else
2280
    int modBits = mp_count_bits(modulus);
2281
2282
    (void)a;
2283
    (void)mp;
2284
2285
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2286
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2287
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2288
                                            R->x, R->y, R->z);
2289
    }
2290
#endif
2291
#ifndef WOLFSSL_SP_NO_256
2292
    if (modBits == 256) {
2293
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2294
                                         R->x, R->y, R->z);
2295
    }
2296
#endif
2297
#ifdef WOLFSSL_SP_384
2298
    if (modBits == 384) {
2299
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2300
                                         R->x, R->y, R->z);
2301
    }
2302
#endif
2303
#ifdef WOLFSSL_SP_521
2304
    if (modBits == 521) {
2305
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2306
                                         R->x, R->y, R->z);
2307
    }
2308
#endif
2309
    return ECC_BAD_ARG_E;
2310
#endif
2311
6.29M
}
2312
2313
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2314
                             mp_int* a, mp_int* modulus, mp_digit mp)
2315
2.94k
{
2316
2.94k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2317
0
        return ECC_BAD_ARG_E;
2318
0
    }
2319
2320
2.94k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2321
2.92k
        mp_cmp(P->y, modulus) != MP_LT ||
2322
2.88k
        mp_cmp(P->z, modulus) != MP_LT ||
2323
2.88k
        mp_cmp(Q->x, modulus) != MP_LT ||
2324
2.84k
        mp_cmp(Q->y, modulus) != MP_LT ||
2325
2.80k
        mp_cmp(Q->z, modulus) != MP_LT) {
2326
140
        return ECC_OUT_OF_RANGE_E;
2327
140
    }
2328
2329
2.80k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2330
2.94k
}
2331
2332
/* ### Point doubling in Jacobian coordinate system ###
2333
 *
2334
 * let us have a curve:                 y^2 = x^3 + a*x + b
2335
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2336
 *
2337
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2338
 * Xr = M^2 - 2*S
2339
 * Yr = M * (S - Xr) - 8*T
2340
 * Zr = 2 * Yp * Zp
2341
 *
2342
 * M = 3 * Xp^2 + a*Zp^4
2343
 * T = Yp^4
2344
 * S = 4 * Xp * Yp^2
2345
 *
2346
 * SPECIAL CASE: when a == 3 we can compute M as
2347
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2348
 */
2349
2350
/**
2351
   Double an ECC point
2352
   P   The point to double
2353
   R   [out] The destination of the double
2354
   a   ECC curve parameter a
2355
   modulus  The modulus of the field the ECC curve is in
2356
   mp       The "b" value from montgomery_setup()
2357
   return   MP_OKAY on success
2358
*/
2359
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2360
                                     mp_int* modulus, mp_digit mp)
2361
6.79M
{
2362
6.79M
#if !defined(WOLFSSL_SP_MATH)
2363
6.79M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2364
6.79M
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2365
#ifdef ALT_ECC_SIZE
2366
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2367
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2368
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2369
#endif
2370
6.79M
   mp_int *x, *y, *z;
2371
6.79M
   int    err;
2372
2373
6.79M
#ifdef WOLFSSL_SMALL_STACK
2374
#ifdef WOLFSSL_SMALL_STACK_CACHE
2375
   if (R->key != NULL) {
2376
       t1 = R->key->t1;
2377
       t2 = R->key->t2;
2378
   #ifdef ALT_ECC_SIZE
2379
       rx = R->key->x;
2380
       ry = R->key->y;
2381
       rz = R->key->z;
2382
   #endif
2383
   }
2384
   else
2385
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2386
6.79M
#endif
2387
6.79M
   {
2388
6.79M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2389
6.79M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2390
6.79M
   #ifdef MP_INT_SIZE_CHECK_NULL
2391
6.79M
      if (t1 == NULL || t2 == NULL) {
2392
186
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2393
186
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2394
186
         return MEMORY_E;
2395
186
      }
2396
6.79M
   #endif
2397
   #ifdef ALT_ECC_SIZE
2398
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2399
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2400
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2401
   #ifdef MP_INT_SIZE_CHECK_NULL
2402
      if (rx == NULL || ry == NULL || rz == NULL) {
2403
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2404
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2405
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2406
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2407
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2408
          return MEMORY_E;
2409
      }
2410
   #endif
2411
   #endif
2412
6.79M
   }
2413
2414
6.79M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2415
6.79M
   if (err == MP_OKAY) {
2416
6.79M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2417
6.79M
   }
2418
6.79M
   if (err != MP_OKAY) {
2419
0
#ifdef WOLFSSL_SMALL_STACK
2420
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2421
      if (R->key == NULL)
2422
   #endif
2423
0
#endif
2424
0
      {
2425
      #ifdef ALT_ECC_SIZE
2426
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2427
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2428
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2429
      #endif
2430
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2431
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2432
0
      }
2433
0
      return err;
2434
0
   }
2435
2436
/* If use ALT_ECC_SIZE we need to use local stack variable since
2437
   ecc_point x,y,z is reduced size */
2438
#ifdef ALT_ECC_SIZE
2439
   /* Use local stack variable */
2440
   x = rx;
2441
   y = ry;
2442
   z = rz;
2443
2444
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2445
   if (err == MP_OKAY) {
2446
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2447
   }
2448
   if (err == MP_OKAY) {
2449
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2450
   }
2451
   if (err != MP_OKAY) {
2452
#ifdef WOLFSSL_SMALL_STACK
2453
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2454
      if (R->key == NULL)
2455
   #endif
2456
#endif
2457
      {
2458
      #ifdef ALT_ECC_SIZE
2459
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2460
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2461
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2462
      #endif
2463
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2464
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2465
      }
2466
      return err;
2467
   }
2468
#else
2469
   /* Use destination directly */
2470
6.79M
   x = R->x;
2471
6.79M
   y = R->y;
2472
6.79M
   z = R->z;
2473
6.79M
#endif
2474
2475
6.79M
   if (err == MP_OKAY)
2476
6.79M
       err = mp_copy(P->x, x);
2477
6.79M
   if (err == MP_OKAY)
2478
6.79M
       err = mp_copy(P->y, y);
2479
6.79M
   if (err == MP_OKAY)
2480
6.79M
       err = mp_copy(P->z, z);
2481
2482
   /* T1 = Z * Z */
2483
6.79M
   if (err == MP_OKAY)
2484
6.79M
       err = mp_sqr(z, t1);
2485
6.79M
   if (err == MP_OKAY)
2486
6.79M
       err = mp_montgomery_reduce(t1, modulus, mp);
2487
2488
   /* Z = Y * Z */
2489
6.79M
   if (err == MP_OKAY)
2490
6.79M
       err = mp_mul(z, y, z);
2491
6.79M
   if (err == MP_OKAY)
2492
6.79M
       err = mp_montgomery_reduce(z, modulus, mp);
2493
2494
   /* Z = 2Z */
2495
6.79M
   if (err == MP_OKAY)
2496
6.79M
       err = mp_addmod_ct(z, z, modulus, z);
2497
2498
   /* Determine if curve "a" should be used in calc */
2499
6.79M
#ifdef WOLFSSL_CUSTOM_CURVES
2500
6.79M
   if (err == MP_OKAY) {
2501
      /* Use a and prime to determine if a == 3 */
2502
6.79M
      err = mp_submod(modulus, a, modulus, t2);
2503
6.79M
   }
2504
6.79M
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2505
      /* T2 = X * X */
2506
968k
      err = mp_sqr(x, t2);
2507
968k
      if (err == MP_OKAY)
2508
968k
          err = mp_montgomery_reduce(t2, modulus, mp);
2509
      /* T1 = T2 + T1 */
2510
968k
      if (err == MP_OKAY)
2511
968k
          err = mp_addmod_ct(t2, t2, modulus, t1);
2512
      /* T1 = T2 + T1 */
2513
968k
      if (err == MP_OKAY)
2514
968k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2515
968k
   }
2516
5.82M
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2517
      /* use "a" in calc */
2518
2519
      /* T2 = T1 * T1 */
2520
826k
      err = mp_sqr(t1, t2);
2521
826k
      if (err == MP_OKAY)
2522
826k
          err = mp_montgomery_reduce(t2, modulus, mp);
2523
      /* T1 = T2 * a */
2524
826k
      if (err == MP_OKAY)
2525
826k
          err = mp_mulmod(t2, a, modulus, t1);
2526
      /* T2 = X * X */
2527
826k
      if (err == MP_OKAY)
2528
826k
          err = mp_sqr(x, t2);
2529
826k
      if (err == MP_OKAY)
2530
826k
          err = mp_montgomery_reduce(t2, modulus, mp);
2531
      /* T1 = T2 + T1 */
2532
826k
      if (err == MP_OKAY)
2533
826k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2534
      /* T1 = T2 + T1 */
2535
826k
      if (err == MP_OKAY)
2536
826k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2537
      /* T1 = T2 + T1 */
2538
826k
      if (err == MP_OKAY)
2539
826k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2540
826k
   }
2541
5.00M
   else
2542
5.00M
#endif /* WOLFSSL_CUSTOM_CURVES */
2543
5.00M
   {
2544
      /* assumes "a" == 3 */
2545
5.00M
      (void)a;
2546
2547
      /* T2 = X - T1 */
2548
5.00M
      if (err == MP_OKAY)
2549
5.00M
          err = mp_submod_ct(x, t1, modulus, t2);
2550
      /* T1 = X + T1 */
2551
5.00M
      if (err == MP_OKAY)
2552
5.00M
          err = mp_addmod_ct(t1, x, modulus, t1);
2553
      /* T2 = T1 * T2 */
2554
5.00M
      if (err == MP_OKAY)
2555
5.00M
          err = mp_mul(t1, t2, t2);
2556
5.00M
      if (err == MP_OKAY)
2557
5.00M
          err = mp_montgomery_reduce(t2, modulus, mp);
2558
2559
      /* T1 = 2T2 */
2560
5.00M
      if (err == MP_OKAY)
2561
5.00M
          err = mp_addmod_ct(t2, t2, modulus, t1);
2562
      /* T1 = T1 + T2 */
2563
5.00M
      if (err == MP_OKAY)
2564
5.00M
          err = mp_addmod_ct(t1, t2, modulus, t1);
2565
5.00M
   }
2566
2567
   /* Y = 2Y */
2568
6.79M
   if (err == MP_OKAY)
2569
6.79M
       err = mp_addmod_ct(y, y, modulus, y);
2570
   /* Y = Y * Y */
2571
6.79M
   if (err == MP_OKAY)
2572
6.79M
       err = mp_sqr(y, y);
2573
6.79M
   if (err == MP_OKAY)
2574
6.79M
       err = mp_montgomery_reduce(y, modulus, mp);
2575
2576
   /* T2 = Y * Y */
2577
6.79M
   if (err == MP_OKAY)
2578
6.79M
       err = mp_sqr(y, t2);
2579
6.79M
   if (err == MP_OKAY)
2580
6.79M
       err = mp_montgomery_reduce(t2, modulus, mp);
2581
2582
   /* T2 = T2/2 */
2583
6.79M
   if (err == MP_OKAY)
2584
6.79M
       err = mp_div_2_mod_ct(t2, modulus, t2);
2585
2586
   /* Y = Y * X */
2587
6.79M
   if (err == MP_OKAY)
2588
6.79M
       err = mp_mul(y, x, y);
2589
6.79M
   if (err == MP_OKAY)
2590
6.79M
       err = mp_montgomery_reduce(y, modulus, mp);
2591
2592
   /* X = T1 * T1 */
2593
6.79M
   if (err == MP_OKAY)
2594
6.79M
       err = mp_sqr(t1, x);
2595
6.79M
   if (err == MP_OKAY)
2596
6.79M
       err = mp_montgomery_reduce(x, modulus, mp);
2597
2598
   /* X = X - Y */
2599
6.79M
   if (err == MP_OKAY)
2600
6.79M
       err = mp_submod_ct(x, y, modulus, x);
2601
   /* X = X - Y */
2602
6.79M
   if (err == MP_OKAY)
2603
6.79M
       err = mp_submod_ct(x, y, modulus, x);
2604
2605
   /* Y = Y - X */
2606
6.79M
   if (err == MP_OKAY)
2607
6.79M
       err = mp_submod_ct(y, x, modulus, y);
2608
   /* Y = Y * T1 */
2609
6.79M
   if (err == MP_OKAY)
2610
6.79M
       err = mp_mul(y, t1, y);
2611
6.79M
   if (err == MP_OKAY)
2612
6.79M
       err = mp_montgomery_reduce(y, modulus, mp);
2613
2614
   /* Y = Y - T2 */
2615
6.79M
   if (err == MP_OKAY)
2616
6.79M
       err = mp_submod_ct(y, t2, modulus, y);
2617
2618
#ifdef ALT_ECC_SIZE
2619
   if (err == MP_OKAY)
2620
       err = mp_copy(x, R->x);
2621
   if (err == MP_OKAY)
2622
       err = mp_copy(y, R->y);
2623
   if (err == MP_OKAY)
2624
       err = mp_copy(z, R->z);
2625
#endif
2626
2627
   /* clean up */
2628
6.79M
   mp_clear(t1);
2629
6.79M
   mp_clear(t2);
2630
2631
6.79M
#ifdef WOLFSSL_SMALL_STACK
2632
#ifdef WOLFSSL_SMALL_STACK_CACHE
2633
   if (R->key == NULL)
2634
#endif
2635
6.79M
#endif
2636
6.79M
   {
2637
    #ifdef ALT_ECC_SIZE
2638
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2639
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2640
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2641
    #endif
2642
6.79M
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2643
6.79M
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2644
6.79M
    }
2645
2646
6.79M
   return err;
2647
#else
2648
    int modBits = mp_count_bits(modulus);
2649
2650
    (void)a;
2651
    (void)mp;
2652
2653
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2654
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2655
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2656
    }
2657
#endif
2658
#ifndef WOLFSSL_SP_NO_256
2659
    if (modBits == 256) {
2660
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2661
    }
2662
#endif
2663
#ifdef WOLFSSL_SP_384
2664
    if (modBits == 384) {
2665
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2666
    }
2667
#endif
2668
#ifdef WOLFSSL_SP_521
2669
    if (modBits == 521) {
2670
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2671
    }
2672
#endif
2673
    return ECC_BAD_ARG_E;
2674
#endif
2675
6.79M
}
2676
2677
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2678
                             mp_int* modulus, mp_digit mp)
2679
4.54k
{
2680
4.54k
    if (P == NULL || R == NULL || modulus == NULL)
2681
0
        return ECC_BAD_ARG_E;
2682
2683
4.54k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2684
4.51k
        mp_cmp(P->y, modulus) != MP_LT ||
2685
4.47k
        mp_cmp(P->z, modulus) != MP_LT) {
2686
67
        return ECC_OUT_OF_RANGE_E;
2687
67
    }
2688
2689
4.47k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2690
4.54k
}
2691
2692
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2693
    !defined(WOLFSSL_CRYPTOCELL)
2694
2695
2696
/**
2697
  Map a projective Jacobian point back to affine space
2698
  P        [in/out] The point to map
2699
  modulus  The modulus of the field the ECC curve is in
2700
  mp       The "b" value from montgomery_setup()
2701
  ct       Operation should be constant time.
2702
  return   MP_OKAY on success
2703
*/
2704
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2705
29.0k
{
2706
29.0k
   int err = MP_OKAY;
2707
29.0k
#if !defined(WOLFSSL_SP_MATH)
2708
29.0k
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2709
29.0k
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2710
#ifdef ALT_ECC_SIZE
2711
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2712
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2713
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2714
#endif
2715
29.0k
   mp_int *x, *y, *z;
2716
2717
29.0k
   (void)ct;
2718
2719
29.0k
   if (P == NULL || modulus == NULL)
2720
0
       return ECC_BAD_ARG_E;
2721
2722
   /* special case for point at infinity */
2723
29.0k
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2724
706
       err = mp_set(P->x, 0);
2725
706
       if (err == MP_OKAY)
2726
706
           err = mp_set(P->y, 0);
2727
706
       if (err == MP_OKAY)
2728
706
           err = mp_set(P->z, 1);
2729
706
       return err;
2730
706
   }
2731
2732
28.3k
#ifdef WOLFSSL_SMALL_STACK
2733
#ifdef WOLFSSL_SMALL_STACK_CACHE
2734
   if (P->key != NULL) {
2735
       t1 = P->key->t1;
2736
       t2 = P->key->t2;
2737
   #ifdef ALT_ECC_SIZE
2738
       rx = P->key->x;
2739
       ry = P->key->y;
2740
       rz = P->key->z;
2741
   #endif
2742
   }
2743
   else
2744
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2745
28.3k
#endif
2746
28.3k
   {
2747
28.3k
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2748
28.3k
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2749
28.3k
   #ifdef MP_INT_SIZE_CHECK_NULL
2750
28.3k
      if (t1 == NULL || t2 == NULL) {
2751
40
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2752
40
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2753
40
         return MEMORY_E;
2754
40
      }
2755
28.3k
   #endif
2756
   #ifdef ALT_ECC_SIZE
2757
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2758
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2759
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2760
   #ifdef MP_INT_SIZE_CHECK_NULL
2761
      if (rx == NULL || ry == NULL || rz == NULL) {
2762
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2763
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2764
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2765
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2766
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2767
          return MEMORY_E;
2768
      }
2769
   #endif
2770
   #endif
2771
28.3k
   }
2772
2773
28.3k
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2774
28.3k
   if (err == MP_OKAY) {
2775
28.3k
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2776
28.3k
   }
2777
28.3k
   if (err != MP_OKAY) {
2778
0
#ifdef WOLFSSL_SMALL_STACK
2779
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2780
      if (P->key == NULL)
2781
   #endif
2782
0
#endif
2783
0
      {
2784
      #ifdef ALT_ECC_SIZE
2785
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2786
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2787
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2788
      #endif
2789
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2790
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2791
0
      }
2792
0
      return MEMORY_E;
2793
0
   }
2794
2795
#ifdef ALT_ECC_SIZE
2796
   /* Use local stack variable */
2797
   x = rx;
2798
   y = ry;
2799
   z = rz;
2800
2801
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2802
   if (err == MP_OKAY) {
2803
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2804
   }
2805
   if (err == MP_OKAY) {
2806
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2807
   }
2808
   if (err != MP_OKAY) {
2809
      goto done;
2810
   }
2811
2812
   if (err == MP_OKAY)
2813
      err = mp_copy(P->x, x);
2814
   if (err == MP_OKAY)
2815
      err = mp_copy(P->y, y);
2816
   if (err == MP_OKAY)
2817
      err = mp_copy(P->z, z);
2818
2819
   if (err != MP_OKAY) {
2820
      goto done;
2821
   }
2822
#else
2823
   /* Use destination directly */
2824
28.3k
   x = P->x;
2825
28.3k
   y = P->y;
2826
28.3k
   z = P->z;
2827
28.3k
#endif
2828
2829
   /* get 1/z */
2830
28.3k
   if (err == MP_OKAY) {
2831
28.3k
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2832
28.3k
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2833
28.3k
       if (ct) {
2834
16.2k
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2835
16.2k
           if (err == MP_OKAY)
2836
16.0k
               err = mp_montgomery_reduce(t1, modulus, mp);
2837
16.2k
       }
2838
12.1k
       else
2839
12.1k
#endif
2840
12.1k
       {
2841
           /* first map z back to normal */
2842
12.1k
           err = mp_montgomery_reduce(z, modulus, mp);
2843
12.1k
           if (err == MP_OKAY)
2844
12.1k
               err = mp_invmod(z, modulus, t1);
2845
12.1k
       }
2846
28.3k
   }
2847
2848
   /* get 1/z^2 and 1/z^3 */
2849
28.3k
   if (err == MP_OKAY)
2850
28.1k
       err = mp_sqr(t1, t2);
2851
28.3k
   if (err == MP_OKAY)
2852
28.1k
       err = mp_mod(t2, modulus, t2);
2853
28.3k
   if (err == MP_OKAY)
2854
28.1k
       err = mp_mul(t1, t2, t1);
2855
28.3k
   if (err == MP_OKAY)
2856
28.1k
       err = mp_mod(t1, modulus, t1);
2857
2858
   /* multiply against x/y */
2859
28.3k
   if (err == MP_OKAY)
2860
28.1k
       err = mp_mul(x, t2, x);
2861
28.3k
   if (err == MP_OKAY)
2862
28.1k
       err = mp_montgomery_reduce(x, modulus, mp);
2863
28.3k
   if (err == MP_OKAY)
2864
28.1k
       err = mp_mul(y, t1, y);
2865
28.3k
   if (err == MP_OKAY)
2866
28.1k
       err = mp_montgomery_reduce(y, modulus, mp);
2867
2868
28.3k
   if (err == MP_OKAY)
2869
28.1k
       err = mp_set(z, 1);
2870
2871
#ifdef ALT_ECC_SIZE
2872
   /* return result */
2873
   if (err == MP_OKAY)
2874
      err = mp_copy(x, P->x);
2875
   if (err == MP_OKAY)
2876
      err = mp_copy(y, P->y);
2877
   if (err == MP_OKAY)
2878
      err = mp_copy(z, P->z);
2879
2880
done:
2881
#endif
2882
2883
   /* clean up */
2884
28.3k
   mp_clear(t1);
2885
28.3k
   mp_clear(t2);
2886
2887
28.3k
#ifdef WOLFSSL_SMALL_STACK
2888
#ifdef WOLFSSL_SMALL_STACK_CACHE
2889
   if (P->key == NULL)
2890
#endif
2891
28.3k
#endif
2892
28.3k
   {
2893
   #ifdef ALT_ECC_SIZE
2894
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2895
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2896
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2897
   #endif
2898
28.3k
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2899
28.3k
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2900
28.3k
   }
2901
2902
28.3k
   return err;
2903
   /* end !defined(WOLFSSL_SP_MATH) */
2904
2905
#else
2906
   /* begin defined(WOLFSSL_SP_MATH) */
2907
   if (P == NULL || modulus == NULL)
2908
       return ECC_BAD_ARG_E;
2909
2910
   (void)mp;
2911
   (void)ct;
2912
2913
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2914
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
2915
       err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
2916
   }
2917
#elif !defined(WOLFSSL_SP_NO_256)
2918
   if (mp_count_bits(modulus) == 256) {
2919
       err = sp_ecc_map_256(P->x, P->y, P->z);
2920
   }
2921
#elif defined(WOLFSSL_SP_384)
2922
   if (mp_count_bits(modulus) == 384) {
2923
       err = sp_ecc_map_384(P->x, P->y, P->z);
2924
   }
2925
#elif defined(WOLFSSL_SP_521)
2926
   if (mp_count_bits(modulus) == 521) {
2927
       err = sp_ecc_map_521(P->x, P->y, P->z);
2928
   }
2929
#else
2930
   err = ECC_BAD_ARG_E;
2931
#endif
2932
2933
   WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
2934
   return err;
2935
#endif /* WOLFSSL_SP_MATH */
2936
28.3k
}
2937
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2938
2939
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2940
21.1k
{
2941
21.1k
    return ecc_map_ex(P, modulus, mp, 0);
2942
21.1k
}
2943
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2944
2945
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2946
    !defined(WOLFSSL_CRYPTOCELL)
2947
#if !defined(WOLFSSL_SP_MATH)
2948
2949
#ifndef ECC_TIMING_RESISTANT
2950
2951
/* size of sliding window, don't change this! */
2952
#define WINSIZE  4
2953
#define M_POINTS 8
2954
2955
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2956
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2957
{
2958
   int      err = MP_OKAY;
2959
   int      i;
2960
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2961
   int      bitcnt = 0, mode = 0, digidx = 0;
2962
   mp_digit buf;
2963
   int      infinity;
2964
2965
   (void)rng;
2966
2967
   /* calc the M tab, which holds kG for k==8..15 */
2968
   /* M[0] == 8G */
2969
   if (err == MP_OKAY)
2970
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2971
   if (err == MP_OKAY)
2972
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2973
   if (err == MP_OKAY)
2974
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2975
2976
   /* now find (8+k)G for k=1..7 */
2977
   if (err == MP_OKAY)
2978
       for (j = 9; j < 16; j++) {
2979
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2980
                                                        modulus, mp, &infinity);
2981
           if (err != MP_OKAY) break;
2982
       }
2983
2984
   /* setup sliding window */
2985
   if (err == MP_OKAY) {
2986
       mode   = 0;
2987
       bitcnt = 1;
2988
       buf    = 0;
2989
       digidx = mp_get_digit_count(k) - 1;
2990
       bitcpy = bitbuf = 0;
2991
       first  = 1;
2992
2993
       /* perform ops */
2994
       for (;;) {
2995
           /* grab next digit as required */
2996
           if (--bitcnt == 0) {
2997
               if (digidx == -1) {
2998
                   break;
2999
               }
3000
               buf    = mp_get_digit(k, digidx);
3001
               bitcnt = (int) DIGIT_BIT;
3002
               --digidx;
3003
           }
3004
3005
           /* grab the next msb from the ltiplicand */
3006
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3007
           buf <<= 1;
3008
3009
           /* skip leading zero bits */
3010
           if (mode == 0 && i == 0)
3011
               continue;
3012
3013
           /* if the bit is zero and mode == 1 then we double */
3014
           if (mode == 1 && i == 0) {
3015
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3016
               if (err != MP_OKAY) break;
3017
               continue;
3018
           }
3019
3020
           /* else we add it to the window */
3021
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3022
           mode = 2;
3023
3024
           if (bitcpy == WINSIZE) {
3025
               /* if this is the first window we do a simple copy */
3026
               if (first == 1) {
3027
                   /* R = kG [k = first window] */
3028
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3029
                   if (err != MP_OKAY) break;
3030
3031
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3032
                   if (err != MP_OKAY) break;
3033
3034
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3035
                   first = 0;
3036
               } else {
3037
                   /* normal window */
3038
                   /* ok window is filled so double as required and add  */
3039
                   /* double first */
3040
                   for (j = 0; j < WINSIZE; j++) {
3041
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3042
                                                                            mp);
3043
                       if (err != MP_OKAY) break;
3044
                   }
3045
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3046
3047
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3048
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3049
                                                     a, modulus, mp, &infinity);
3050
               }
3051
               if (err != MP_OKAY) break;
3052
               /* empty window and reset */
3053
               bitcpy = bitbuf = 0;
3054
               mode = 1;
3055
           }
3056
       }
3057
   }
3058
3059
   /* if bits remain then double/add */
3060
   if (err == MP_OKAY) {
3061
       if (mode == 2 && bitcpy > 0) {
3062
           /* double then add */
3063
           for (j = 0; j < bitcpy; j++) {
3064
               /* only double if we have had at least one add first */
3065
               if (first == 0) {
3066
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3067
                   if (err != MP_OKAY) break;
3068
               }
3069
3070
               bitbuf <<= 1;
3071
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3072
                   if (first == 1) {
3073
                       /* first add, so copy */
3074
                       err = mp_copy(tG->x, R->x);
3075
                       if (err != MP_OKAY) break;
3076
3077
                       err = mp_copy(tG->y, R->y);
3078
                       if (err != MP_OKAY) break;
3079
3080
                       err = mp_copy(tG->z, R->z);
3081
                       if (err != MP_OKAY) break;
3082
                       first = 0;
3083
                   } else {
3084
                       /* then add */
3085
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3086
                                                                 mp, &infinity);
3087
                       if (err != MP_OKAY) break;
3088
                   }
3089
               }
3090
           }
3091
       }
3092
   }
3093
3094
   #undef WINSIZE
3095
3096
   return err;
3097
}
3098
3099
#else
3100
3101
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3102
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3103
33.1k
{
3104
33.1k
    int err = MP_OKAY;
3105
3106
33.1k
    err = mp_montgomery_calc_normalization(mu, modulus);
3107
    /* Generate random value to multiply into p->z. */
3108
33.1k
    if (err == MP_OKAY)
3109
33.1k
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3110
    /* Convert to montogmery form. */
3111
33.1k
    if (err == MP_OKAY)
3112
32.9k
        err = mp_mulmod(ty, mu, modulus, ty);
3113
    /* Multiply random value into p->z. */
3114
33.1k
    if (err == MP_OKAY)
3115
32.9k
        err = mp_mul(p->z, ty, p->z);
3116
33.1k
    if (err == MP_OKAY)
3117
32.8k
        err = mp_montgomery_reduce(p->z, modulus, mp);
3118
    /* Square random value for X (X' = X / Z^2). */
3119
33.1k
    if (err == MP_OKAY)
3120
32.8k
        err = mp_sqr(ty, tx);
3121
33.1k
    if (err == MP_OKAY)
3122
32.8k
        err = mp_montgomery_reduce(tx, modulus, mp);
3123
    /* Multiply square of random by random value for Y. */
3124
33.1k
    if (err == MP_OKAY)
3125
32.8k
        err = mp_mul(ty, tx, ty);
3126
33.1k
    if (err == MP_OKAY)
3127
32.8k
        err = mp_montgomery_reduce(ty, modulus, mp);
3128
    /* Multiply square into X. */
3129
33.1k
    if (err == MP_OKAY)
3130
32.8k
        err = mp_mul(p->x, tx, p->x);
3131
33.1k
    if (err == MP_OKAY)
3132
32.8k
        err = mp_montgomery_reduce(p->x, modulus, mp);
3133
    /* Multiply cube into Y (Y' = Y / Z^3). */
3134
33.1k
    if (err == MP_OKAY)
3135
32.8k
        err = mp_mul(p->y, ty, p->y);
3136
33.1k
    if (err == MP_OKAY)
3137
32.7k
        err = mp_montgomery_reduce(p->y, modulus, mp);
3138
3139
33.1k
    return err;
3140
33.1k
}
3141
3142
#ifndef WC_PROTECT_ENCRYPTED_MEM
3143
168k
#define M_POINTS 3
3144
3145
/* Joye double-add ladder.
3146
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3147
 * by Marc Joye (2007)
3148
 *
3149
 * Algorithm 1':
3150
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3151
 *   Output: Q = kP
3152
 *   1: R[0] = P; R[1] = P
3153
 *   2: for j = 1 to t-1 do
3154
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3155
 *   4: end for
3156
 *   5: b = k[0]; R[b] = R[b] - P
3157
 *   6: return R[0]
3158
 *
3159
 * Assumes: k < order.
3160
 */
3161
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3162
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3163
30.6k
{
3164
30.6k
    int      err = MP_OKAY;
3165
30.6k
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3166
30.6k
    int      i;
3167
30.6k
    int      j = 1;
3168
30.6k
    int      cnt = DIGIT_BIT;
3169
30.6k
    int      t = 0;
3170
30.6k
    mp_digit b;
3171
30.6k
    mp_digit v = 0;
3172
30.6k
    mp_int*  kt = R[2]->x;
3173
30.6k
#ifndef WC_NO_CACHE_RESISTANT
3174
    /* First bit always 1 (fix at end) and swap equals first bit */
3175
30.6k
    int      swap = 1;
3176
30.6k
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3177
30.6k
#endif
3178
30.6k
    int      infinity;
3179
3180
30.6k
#ifndef WC_NO_CACHE_RESISTANT
3181
30.6k
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3182
30.6k
    if (err == MP_OKAY)
3183
30.5k
        err = mp_init(tmp);
3184
30.6k
#endif
3185
3186
    /* Step 1: R[0] = P; R[1] = P */
3187
    /* R[0] = P */
3188
30.6k
    if (err == MP_OKAY)
3189
30.5k
        err = mp_copy(P->x, R[0]->x);
3190
30.6k
    if (err == MP_OKAY)
3191
30.5k
        err = mp_copy(P->y, R[0]->y);
3192
30.6k
    if (err == MP_OKAY)
3193
30.5k
        err = mp_copy(P->z, R[0]->z);
3194
3195
    /* R[1] = P */
3196
30.6k
    if (err == MP_OKAY)
3197
30.5k
        err = mp_copy(P->x, R[1]->x);
3198
30.6k
    if (err == MP_OKAY)
3199
30.5k
        err = mp_copy(P->y, R[1]->y);
3200
30.6k
    if (err == MP_OKAY)
3201
30.5k
        err = mp_copy(P->z, R[1]->z);
3202
3203
    /* Randomize z ordinates to obfuscate timing. */
3204
30.6k
    if ((err == MP_OKAY) && (rng != NULL))
3205
15.6k
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3206
30.6k
    if ((err == MP_OKAY) && (rng != NULL))
3207
15.4k
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3208
3209
30.6k
    if (err == MP_OKAY) {
3210
        /* Order could be one greater than the size of the modulus. */
3211
30.1k
        t = mp_count_bits(modulus) + 1;
3212
30.1k
        v = k->dp[0] >> 1;
3213
30.1k
        if (cnt > t) {
3214
0
            cnt = t;
3215
0
        }
3216
30.1k
        err = mp_copy(k, kt);
3217
30.1k
    }
3218
30.6k
    if (err == MP_OKAY) {
3219
30.1k
        err = mp_grow(kt, (int)modulus->used + 1);
3220
30.1k
    }
3221
    /* Step 2: for j = 1 to t-1 do */
3222
7.70M
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3223
7.67M
        if (--cnt == 0) {
3224
188k
            v = kt->dp[j++];
3225
188k
            cnt = DIGIT_BIT;
3226
188k
        }
3227
3228
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3229
7.67M
        b = v & 1;
3230
7.67M
        v >>= 1;
3231
#ifdef WC_NO_CACHE_RESISTANT
3232
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3233
        if (err == MP_OKAY) {
3234
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3235
                                                        modulus, mp, &infinity);
3236
        }
3237
#else
3238
        /* Swap R[0] and R[1] if other index is needed. */
3239
7.67M
        swap ^= (int)b;
3240
7.67M
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3241
7.67M
            tmp);
3242
7.67M
        if (err == MP_OKAY) {
3243
7.67M
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3244
7.67M
                tmp);
3245
7.67M
        }
3246
7.67M
        if (err == MP_OKAY) {
3247
7.67M
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3248
7.67M
                tmp);
3249
7.67M
        }
3250
7.67M
        swap = (int)b;
3251
3252
7.67M
        if (err == MP_OKAY)
3253
7.67M
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3254
7.67M
        if (err == MP_OKAY) {
3255
7.67M
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3256
7.67M
                                                                 mp, &infinity);
3257
7.67M
        }
3258
7.67M
#endif /* WC_NO_CACHE_RESISTANT */
3259
7.67M
    }
3260
    /* Step 4: end for */
3261
30.6k
#ifndef WC_NO_CACHE_RESISTANT
3262
    /* Swap back if last bit is 0. */
3263
30.6k
    swap ^= 1;
3264
30.6k
    if (err == MP_OKAY) {
3265
28.6k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3266
28.6k
            tmp);
3267
28.6k
    }
3268
30.6k
    if (err == MP_OKAY) {
3269
28.6k
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3270
28.6k
            tmp);
3271
28.6k
    }
3272
30.6k
    if (err == MP_OKAY) {
3273
28.6k
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3274
28.6k
            tmp);
3275
28.6k
    }
3276
30.6k
#endif
3277
3278
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3279
    /* R[2] = -P */
3280
30.6k
    if (err == MP_OKAY)
3281
28.6k
        err = mp_copy(P->x, R[2]->x);
3282
30.6k
    if (err == MP_OKAY)
3283
28.6k
        err = mp_sub(modulus, P->y, R[2]->y);
3284
30.6k
    if (err == MP_OKAY)
3285
28.6k
        err = mp_copy(P->z, R[2]->z);
3286
    /* Subtract point by adding negative. */
3287
30.6k
    if (err == MP_OKAY) {
3288
28.6k
        b = k->dp[0] & 1;
3289
#ifdef WC_NO_CACHE_RESISTANT
3290
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3291
                                                                     &infinity);
3292
#else
3293
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3294
28.6k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3295
28.6k
            tmp);
3296
28.6k
        if (err == MP_OKAY) {
3297
28.6k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3298
28.6k
                (int)b, tmp);
3299
28.6k
        }
3300
28.6k
        if (err == MP_OKAY) {
3301
28.6k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3302
28.6k
                (int)b, tmp);
3303
28.6k
        }
3304
28.6k
        if (err == MP_OKAY)
3305
28.6k
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3306
28.6k
                                                                 mp, &infinity);
3307
        /* Swap back if necessary. */
3308
28.6k
        if (err == MP_OKAY) {
3309
28.6k
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3310
28.6k
                (int)b, tmp);
3311
28.6k
        }
3312
28.6k
        if (err == MP_OKAY) {
3313
28.6k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3314
28.6k
                (int)b, tmp);
3315
28.6k
        }
3316
28.6k
        if (err == MP_OKAY) {
3317
28.6k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3318
28.6k
                (int)b, tmp);
3319
28.6k
        }
3320
28.6k
#endif
3321
28.6k
    }
3322
3323
    /* Step 6: return R[0] */
3324
30.6k
    if (err == MP_OKAY)
3325
28.6k
        err = mp_copy(R[0]->x, Q->x);
3326
30.6k
    if (err == MP_OKAY)
3327
28.6k
        err = mp_copy(R[0]->y, Q->y);
3328
30.6k
    if (err == MP_OKAY)
3329
28.6k
        err = mp_copy(R[0]->z, Q->z);
3330
3331
30.6k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3332
30.6k
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3333
30.6k
#endif
3334
3335
30.6k
    return err;
3336
30.6k
}
3337
3338
#else
3339
/* Number of points to allocate for use during scalar multiplication. */
3340
#define M_POINTS        5
3341
/* Last of the points is used as a temporary during calculations. */
3342
#define TMP_IDX         M_POINTS - 1
3343
3344
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3345
    int digits, int m)
3346
{
3347
    int i;
3348
3349
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3350
    /* Only using positive numbers in ECC operations. */
3351
    ra->sign = 0;
3352
    rb->sign = 0;
3353
#endif
3354
    /* Don't store 0 when mask is 0, it will be in a register. */
3355
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3356
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3357
    for (i = 0; i < digits; i++) {
3358
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3359
                    a->dp[i];
3360
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3361
                    b->dp[i];
3362
    }
3363
}
3364
3365
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3366
    ecc_point* b, int digits, int m)
3367
{
3368
    /* Conditionally swap each ordinate. */
3369
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3370
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3371
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3372
}
3373
3374
/* Joye double-add ladder.
3375
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3376
 * by Marc Joye (2007)
3377
 *
3378
 * Algorithm 1':
3379
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3380
 *   Output: Q = kP
3381
 *   1: R[0] = P; R[1] = P
3382
 *   2: for j = 1 to t-1 do
3383
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3384
 *   4: end for
3385
 *   5: b = k[0]; R[b] = R[b] - P
3386
 *   6: return R[0]
3387
 *
3388
 * Assumes: k < order.
3389
 */
3390
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3391
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3392
{
3393
    int          err = MP_OKAY;
3394
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3395
    int          i;
3396
    int          j = 1;
3397
    int          cnt;
3398
    int          t = 0;
3399
    mp_int*      kt = R[TMP_IDX]->x;
3400
    /* First bit always 1 (fix at end) and swap equals first bit */
3401
    register int swap = 1;
3402
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3403
    int          set = 0;
3404
    int          infinity;
3405
3406
    /* Step 1: R[0] = P; R[1] = P */
3407
    /* R[0] = P */
3408
    if (err == MP_OKAY)
3409
        err = mp_copy(P->x, R[0]->x);
3410
    if (err == MP_OKAY)
3411
        err = mp_copy(P->y, R[0]->y);
3412
    if (err == MP_OKAY)
3413
        err = mp_copy(P->z, R[0]->z);
3414
3415
    /* R[1] = P */
3416
    if (err == MP_OKAY)
3417
        err = mp_copy(P->x, R[1]->x);
3418
    if (err == MP_OKAY)
3419
        err = mp_copy(P->y, R[1]->y);
3420
    if (err == MP_OKAY)
3421
        err = mp_copy(P->z, R[1]->z);
3422
3423
    /* Randomize z ordinates to obfuscate timing. */
3424
    if ((err == MP_OKAY) && (rng != NULL))
3425
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3426
                           R[TMP_IDX]->y, kt);
3427
    if ((err == MP_OKAY) && (rng != NULL))
3428
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3429
                           R[TMP_IDX]->y, kt);
3430
3431
    if (err == MP_OKAY) {
3432
        /* Order could be one greater than the size of the modulus. */
3433
        t = mp_count_bits(modulus) + 1;
3434
        err = mp_copy(k, kt);
3435
    }
3436
    if (err == MP_OKAY) {
3437
        err = mp_grow(kt, modulus->used + 1);
3438
    }
3439
    /* Step 2: for j = 1 to t-1 do */
3440
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3441
        if (++cnt == DIGIT_BIT) {
3442
            j++;
3443
            cnt = 0;
3444
        }
3445
3446
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3447
        /* Swap R[0] and R[1] if other index is needed. */
3448
        /* Ensure 'swap' changes when shifted word is 0. */
3449
        swap += (kt->dp[j] >> cnt) + 2;
3450
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3451
                              R[set + 0], R[set + 1], modulus->used, swap);
3452
        /* Change to operate on set copied into. */
3453
        set = 2 - set;
3454
        /* Ensure 'swap' changes to a previously unseen value. */
3455
        swap += (kt->dp[j] >> cnt) + swap;
3456
3457
        /* R[0] = 2*R[0] */
3458
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3459
                                            mp);
3460
        if (err == MP_OKAY) {
3461
            /* R[0] = R[1] + R[0] */
3462
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3463
                                         R[set + 0], a, modulus, mp, &infinity);
3464
        }
3465
        /*  R[1]->z * 2 - same point. */
3466
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3467
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3468
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3469
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3470
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3471
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3472
    }
3473
    /* Step 4: end for */
3474
    /* Swap back if last bit is 0. */
3475
    /* Ensure 'swap' changes. */
3476
    swap += 1;
3477
    if (err == MP_OKAY) {
3478
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3479
                              R[set + 0], R[set + 1], modulus->used, swap);
3480
        set = 2 - set;
3481
    }
3482
3483
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3484
    /* R[TMP_IDX] = -P */
3485
    if (err == MP_OKAY)
3486
        err = mp_copy(P->x, R[TMP_IDX]->x);
3487
    if (err == MP_OKAY)
3488
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3489
    if (err == MP_OKAY)
3490
        err = mp_copy(P->z, R[TMP_IDX]->z);
3491
    /* Subtract point by adding negative. */
3492
    if (err == MP_OKAY) {
3493
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3494
         * Last bit of k->dp[0] is being used to make decision to swap.
3495
         */
3496
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3497
                              R[set + 0], R[set + 1], modulus->used,
3498
                              (int)k->dp[0]);
3499
        set = 2 - set;
3500
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3501
                                            a, modulus, mp, &infinity);
3502
        /* Swap back if necessary. */
3503
        if (err == MP_OKAY) {
3504
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3505
                                  R[set + 0], R[set + 1], modulus->used,
3506
                                  (int)k->dp[0]);
3507
            set = 2 - set;
3508
        }
3509
    }
3510
3511
    /* Step 6: return R[0] */
3512
    if (err == MP_OKAY)
3513
        err = mp_copy(R[set + 0]->x, Q->x);
3514
    if (err == MP_OKAY)
3515
        err = mp_copy(R[set + 0]->y, Q->y);
3516
    if (err == MP_OKAY)
3517
        err = mp_copy(R[set + 0]->z, Q->z);
3518
3519
    return err;
3520
}
3521
3522
#endif
3523
3524
#endif
3525
3526
/* Convert the point to montgomery form.
3527
 *
3528
 * @param  [in]   p        Point to convert.
3529
 * @param  [out]  r        Point in montgomery form.
3530
 * @param  [in]   modulus  Modulus of ordinates.
3531
 * @return  0 on success.
3532
 * @return  -ve on failure.
3533
 */
3534
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3535
                             void* heap)
3536
24.7k
{
3537
24.7k
   int err = MP_OKAY;
3538
24.7k
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3539
3540
24.7k
   (void)heap;
3541
3542
24.7k
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3543
24.7k
#ifdef MP_INT_SIZE_CHECK_NULL
3544
24.7k
   if (mu == NULL)
3545
29
       err = MEMORY_E;
3546
24.7k
#endif
3547
24.7k
   if (err == MP_OKAY)
3548
24.6k
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3549
24.7k
   if (err == MP_OKAY) {
3550
24.6k
       err = mp_montgomery_calc_normalization(mu, modulus);
3551
3552
24.6k
       if (err == MP_OKAY) {
3553
24.6k
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3554
2.08k
               err = mp_copy(p->x, r->x);
3555
2.08k
               if (err == MP_OKAY)
3556
2.08k
                   err = mp_copy(p->y, r->y);
3557
2.08k
               if (err == MP_OKAY)
3558
2.08k
                   err = mp_copy(p->z, r->z);
3559
2.08k
           }
3560
22.5k
           else {
3561
22.5k
               err = mp_mulmod(p->x, mu, modulus, r->x);
3562
22.5k
               if (err == MP_OKAY)
3563
22.5k
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3564
22.5k
               if (err == MP_OKAY)
3565
22.5k
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3566
22.5k
           }
3567
24.6k
       }
3568
3569
24.6k
       mp_clear(mu);
3570
24.6k
   }
3571
3572
24.7k
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3573
24.7k
   return err;
3574
24.7k
}
3575
3576
#ifdef WOLFSSL_SMALL_STACK_CACHE
3577
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3578
{
3579
   int err = MP_OKAY;
3580
3581
   (void)heap;
3582
3583
   if (key == NULL) {
3584
       return ECC_BAD_ARG_E;
3585
   }
3586
3587
   XMEMSET(key, 0, sizeof(*key));
3588
3589
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3590
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3591
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3592
#ifdef ALT_ECC_SIZE
3593
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3594
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3595
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3596
#endif
3597
   if (key->t1 == NULL || key->t2 == NULL
3598
#ifdef ALT_ECC_SIZE
3599
      || key->x == NULL || key->y == NULL || key->z == NULL
3600
#endif
3601
   ) {
3602
       err = MEMORY_E;
3603
   }
3604
   if (err == 0) {
3605
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3606
   }
3607
   if (err == 0) {
3608
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3609
   }
3610
#ifdef ALT_ECC_SIZE
3611
   if (err == 0) {
3612
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3613
   }
3614
   if (err == 0) {
3615
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3616
   }
3617
   if (err == 0) {
3618
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3619
   }
3620
#endif
3621
#else
3622
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3623
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3624
#ifdef ALT_ECC_SIZE
3625
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3626
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3627
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3628
#endif
3629
   if (key->t1 == NULL || key->t2 == NULL
3630
#ifdef ALT_ECC_SIZE
3631
      || key->x == NULL || key->y == NULL || key->z == NULL
3632
#endif
3633
   ) {
3634
       err = MEMORY_E;
3635
   }
3636
#endif
3637
3638
   return err;
3639
}
3640
3641
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3642
{
3643
    (void)heap;
3644
3645
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3646
#ifdef ALT_ECC_SIZE
3647
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3648
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3649
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3650
#endif
3651
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3652
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3653
#else
3654
#ifdef ALT_ECC_SIZE
3655
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3656
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3657
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3658
#endif
3659
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3660
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3661
#endif
3662
}
3663
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3664
#endif /* !WOLFSSL_SP_MATH */
3665
3666
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3667
/**
3668
   Perform a point multiplication
3669
   k    The scalar to multiply by
3670
   G    The base point
3671
   R    [out] Destination for kG
3672
   a    ECC curve parameter a
3673
   modulus  The modulus of the field the ECC curve is in
3674
   map      Boolean whether to map back to affine or not
3675
                (1==map, 0 == leave in projective)
3676
   return MP_OKAY on success
3677
*/
3678
#ifdef FP_ECC
3679
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3680
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3681
                             void* heap)
3682
#else
3683
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3684
                     mp_int* modulus, int map, void* heap)
3685
#endif
3686
#if !defined(WOLFSSL_SP_MATH)
3687
10.1k
{
3688
10.1k
   ecc_point     *tG, *M[M_POINTS];
3689
#ifdef WOLFSSL_NO_MALLOC
3690
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3691
#endif
3692
10.1k
   int           i, err;
3693
#ifdef WOLFSSL_SMALL_STACK_CACHE
3694
   ecc_key       *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3695
#endif
3696
10.1k
   mp_digit      mp;
3697
3698
   /* init variables */
3699
10.1k
   tG = NULL;
3700
10.1k
   XMEMSET(M, 0, sizeof(M));
3701
3702
10.1k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3703
0
       err = ECC_BAD_ARG_E;
3704
0
       goto exit;
3705
0
   }
3706
3707
   /* k can't have more bits than modulus count plus 1 */
3708
10.1k
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3709
325
       err = ECC_OUT_OF_RANGE_E;
3710
325
       goto exit;
3711
325
   }
3712
3713
#ifdef WOLFSSL_SMALL_STACK_CACHE
3714
   if (key == NULL) {
3715
       err = MP_MEM;
3716
       goto exit;
3717
   }
3718
   err = ecc_key_tmp_init(key, heap);
3719
   if (err != MP_OKAY)
3720
      goto exit;
3721
   R->key = key;
3722
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3723
3724
  /* alloc ram for window temps */
3725
39.2k
  for (i = 0; i < M_POINTS; i++) {
3726
  #ifdef WOLFSSL_NO_MALLOC
3727
      M[i] = &lcl_M[i];
3728
  #endif
3729
29.4k
      err = wc_ecc_new_point_ex(&M[i], heap);
3730
29.4k
      if (err != MP_OKAY) {
3731
97
         goto exit;
3732
97
      }
3733
#ifdef WOLFSSL_SMALL_STACK_CACHE
3734
      M[i]->key = key;
3735
#endif
3736
29.4k
  }
3737
3738
   /* make a copy of G in case R==G */
3739
#ifdef WOLFSSL_NO_MALLOC
3740
   tG = &lcl_tG;
3741
#endif
3742
9.77k
   err = wc_ecc_new_point_ex(&tG, heap);
3743
9.77k
   if (err != MP_OKAY) {
3744
21
       goto exit;
3745
21
   }
3746
9.75k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3747
39
       goto exit;
3748
39
   }
3749
3750
   /* init montgomery reduction */
3751
9.71k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3752
0
       goto exit;
3753
0
   }
3754
3755
#ifdef FP_ECC
3756
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3757
#else
3758
9.71k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3759
9.71k
#endif
3760
   /* map R back from projective space */
3761
9.71k
   if (err == MP_OKAY && map)
3762
9.33k
       err = ecc_map(R, modulus, mp);
3763
3764
10.1k
exit:
3765
3766
   /* done */
3767
10.1k
   wc_ecc_del_point_ex(tG, heap);
3768
40.7k
   for (i = 0; i < M_POINTS; i++) {
3769
30.5k
       wc_ecc_del_point_ex(M[i], heap);
3770
30.5k
   }
3771
3772
#ifdef WOLFSSL_SMALL_STACK_CACHE
3773
   if (key) {
3774
       if (R)
3775
           R->key = NULL;
3776
       if (err == MP_OKAY)
3777
           ecc_key_tmp_final(key, heap);
3778
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3779
   }
3780
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3781
3782
10.1k
   return err;
3783
9.71k
}
3784
#else
3785
{
3786
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3787
       return ECC_BAD_ARG_E;
3788
   }
3789
3790
   (void)a;
3791
3792
   /* For supported curves the order is the same length in bits as the modulus.
3793
    * Can't have more than order bits for the scalar.
3794
    */
3795
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3796
       return ECC_OUT_OF_RANGE_E;
3797
   }
3798
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3799
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3800
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3801
       return IS_POINT_E;
3802
   }
3803
3804
#ifdef WOLFSSL_HAVE_SP_ECC
3805
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3806
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3807
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3808
   }
3809
#endif
3810
#ifndef WOLFSSL_SP_NO_256
3811
   if (mp_count_bits(modulus) == 256) {
3812
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3813
   }
3814
#endif
3815
#ifdef WOLFSSL_SP_384
3816
   if (mp_count_bits(modulus) == 384) {
3817
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3818
   }
3819
#endif
3820
#ifdef WOLFSSL_SP_521
3821
   if (mp_count_bits(modulus) == 521) {
3822
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3823
   }
3824
#endif
3825
#else
3826
   (void)map;
3827
   (void)map;
3828
   (void)heap;
3829
#endif
3830
   return ECC_BAD_ARG_E;
3831
}
3832
#endif
3833
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3834
3835
#ifndef FP_ECC
3836
#if !defined(WOLFSSL_SP_MATH)
3837
#ifdef ECC_TIMING_RESISTANT
3838
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3839
   mp_int* modulus, mp_int* order)
3840
16.3k
{
3841
16.3k
    int err;
3842
16.3k
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3843
3844
16.3k
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3845
16.3k
#ifdef MP_INT_SIZE_CHECK_NULL
3846
16.3k
    if (t == NULL) {
3847
10
        err = MEMORY_E;
3848
10
    }
3849
16.2k
    else
3850
16.2k
#endif
3851
16.2k
    {
3852
16.2k
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3853
16.2k
    }
3854
16.3k
    if (err == MP_OKAY) {
3855
        /* Check for k == order - 1. Result will be 0 point which is not correct
3856
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3857
         * (with constant time implementation)
3858
         */
3859
16.2k
        err = mp_sub_d(order, 1, t);
3860
16.2k
        if (err == MP_OKAY) {
3861
16.2k
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3862
16.2k
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3863
16.2k
            if (err == MP_OKAY) {
3864
16.2k
                err = mp_sub(modulus, tG->y, t);
3865
16.2k
            }
3866
16.2k
            if (err == MP_OKAY) {
3867
16.2k
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3868
16.2k
            }
3869
16.2k
            if (err == MP_OKAY) {
3870
16.2k
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3871
16.2k
            }
3872
16.2k
        }
3873
3874
16.2k
        mp_free(t);
3875
16.2k
    }
3876
3877
16.3k
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3878
16.3k
    return err;
3879
16.3k
}
3880
#endif /* ECC_TIMING_RESISTANT */
3881
#endif
3882
3883
/**
3884
   Perform a point multiplication
3885
   k    The scalar to multiply by
3886
   G    The base point
3887
   R    [out] Destination for kG
3888
   a    ECC curve parameter a
3889
   modulus  The modulus of the field the ECC curve is in
3890
   map      Boolean whether to map back to affine or not
3891
                (1==map, 0 == leave in projective)
3892
   return MP_OKAY on success
3893
*/
3894
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
3895
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3896
                      void* heap)
3897
#if !defined(WOLFSSL_SP_MATH)
3898
11.0k
{
3899
11.0k
   ecc_point     *tG, *M[M_POINTS];
3900
#ifdef WOLFSSL_NO_MALLOC
3901
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3902
#endif
3903
11.0k
   int           i, err;
3904
#ifdef WOLFSSL_SMALL_STACK_CACHE
3905
   ecc_key       *key = NULL;
3906
#endif
3907
11.0k
   mp_digit      mp;
3908
3909
11.0k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3910
0
      return ECC_BAD_ARG_E;
3911
0
   }
3912
3913
#ifdef HAVE_ECC_CDH
3914
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
3915
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
3916
          return ECC_OUT_OF_RANGE_E;
3917
      }
3918
   }
3919
   else
3920
#endif
3921
   /* k can't have more bits than order */
3922
11.0k
   if (mp_count_bits(k) > mp_count_bits(order)) {
3923
21
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3924
21
      return ECC_OUT_OF_RANGE_E;
3925
21
   }
3926
3927
   /* init variables */
3928
11.0k
   tG = NULL;
3929
11.0k
   XMEMSET(M, 0, sizeof(M));
3930
3931
#ifdef WOLFSSL_SMALL_STACK_CACHE
3932
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3933
   if (key == NULL)
3934
       return MEMORY_E;
3935
   err = ecc_key_tmp_init(key, heap);
3936
   if (err != MP_OKAY)
3937
      goto exit;
3938
   R->key = key;
3939
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3940
3941
   /* alloc ram for window temps */
3942
43.8k
   for (i = 0; i < M_POINTS; i++) {
3943
   #ifdef WOLFSSL_NO_MALLOC
3944
      M[i] = &lcl_M[i];
3945
   #endif
3946
32.9k
      err = wc_ecc_new_point_ex(&M[i], heap);
3947
32.9k
      if (err != MP_OKAY) {
3948
92
         goto exit;
3949
92
      }
3950
#ifdef WOLFSSL_SMALL_STACK_CACHE
3951
      M[i]->key = key;
3952
#endif
3953
32.9k
  }
3954
3955
   /* make a copy of G in case R==G */
3956
#ifdef WOLFSSL_NO_MALLOC
3957
   tG = &lcl_tG;
3958
#endif
3959
10.9k
   err = wc_ecc_new_point_ex(&tG, heap);
3960
10.9k
   if (err != MP_OKAY) {
3961
18
       goto exit;
3962
18
   }
3963
10.9k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3964
60
       goto exit;
3965
60
   }
3966
3967
   /* init montgomery reduction */
3968
10.8k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3969
0
      goto exit;
3970
0
   }
3971
3972
10.8k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3973
10.8k
#ifdef ECC_TIMING_RESISTANT
3974
10.8k
   if (err == MP_OKAY) {
3975
10.6k
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3976
10.6k
   }
3977
#else
3978
   (void)order;
3979
#endif
3980
   /* map R back from projective space */
3981
10.8k
   if (err == MP_OKAY && map)
3982
0
      err = ecc_map(R, modulus, mp);
3983
3984
11.0k
exit:
3985
3986
   /* done */
3987
11.0k
   wc_ecc_del_point_ex(tG, heap);
3988
44.1k
   for (i = 0; i < M_POINTS; i++) {
3989
33.0k
      wc_ecc_del_point_ex(M[i], heap);
3990
33.0k
   }
3991
#ifdef WOLFSSL_SMALL_STACK_CACHE
3992
   R->key = NULL;
3993
   ecc_key_tmp_final(key, heap);
3994
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
3995
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3996
3997
11.0k
   return err;
3998
10.8k
}
3999
#else
4000
{
4001
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4002
       return ECC_BAD_ARG_E;
4003
   }
4004
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4005
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4006
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4007
       return IS_POINT_E;
4008
   }
4009
4010
   (void)a;
4011
   (void)order;
4012
   (void)rng;
4013
4014
#ifdef WOLFSSL_HAVE_SP_ECC
4015
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4016
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4017
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4018
   }
4019
#endif
4020
#ifndef WOLFSSL_SP_NO_256
4021
   if (mp_count_bits(modulus) == 256) {
4022
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4023
   }
4024
#endif
4025
#ifdef WOLFSSL_SP_384
4026
   if (mp_count_bits(modulus) == 384) {
4027
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4028
   }
4029
#endif
4030
#ifdef WOLFSSL_SP_521
4031
   if (mp_count_bits(modulus) == 521) {
4032
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4033
   }
4034
#endif
4035
#else
4036
   (void)map;
4037
   (void)heap;
4038
#endif
4039
   return ECC_BAD_ARG_E;
4040
}
4041
#endif /* !WOLFSSL_SP_MATH */
4042
#endif /* !FP_ECC */
4043
4044
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4045
4046
/** ECC Fixed Point mulmod global
4047
    k        The multiplicand
4048
    G        Base point to multiply
4049
    R        [out] Destination of product
4050
    a        ECC curve parameter a
4051
    modulus  The modulus for the curve
4052
    map      [boolean] If non-zero maps the point back to affine coordinates,
4053
             otherwise it's left in jacobian-montgomery form
4054
    return MP_OKAY if successful
4055
*/
4056
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4057
                  mp_int* modulus, int map)
4058
1.65k
{
4059
1.65k
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4060
14
        mp_zero(R->x);
4061
14
        mp_zero(R->y);
4062
14
        mp_set(R->z, 1);
4063
14
        return MP_OKAY;
4064
14
    }
4065
1.63k
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4066
1.65k
}
4067
4068
#endif
4069
4070
/**
4071
 * Allocate a new ECC point (if one not provided)
4072
 * use a heap hint when creating new ecc_point
4073
 * @return 0 on success
4074
 * @return BAD_FUNC_ARG for invalid arguments
4075
 * @return MEMORY_E on failure to allocate memory
4076
*/
4077
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4078
301k
{
4079
301k
   int err = MP_OKAY;
4080
301k
   ecc_point* p;
4081
4082
301k
   if (point == NULL) {
4083
0
       return BAD_FUNC_ARG;
4084
0
   }
4085
4086
301k
   p = *point;
4087
301k
   if (p == NULL) {
4088
301k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4089
301k
   }
4090
301k
   if (p == NULL) {
4091
1.65k
      return MEMORY_E;
4092
1.65k
   }
4093
299k
   XMEMSET(p, 0, sizeof(ecc_point));
4094
4095
299k
   if (*point == NULL)
4096
299k
       p->isAllocated = 1;
4097
4098
299k
#ifndef ALT_ECC_SIZE
4099
299k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4100
299k
   if (err != MP_OKAY) {
4101
0
      WOLFSSL_MSG("mp_init_multi failed.");
4102
0
      if (p->isAllocated)
4103
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4104
0
      p = NULL;
4105
0
   }
4106
#else
4107
   p->x = (mp_int*)&p->xyz[0];
4108
   p->y = (mp_int*)&p->xyz[1];
4109
   p->z = (mp_int*)&p->xyz[2];
4110
   alt_fp_init(p->x);
4111
   alt_fp_init(p->y);
4112
   alt_fp_init(p->z);
4113
#endif
4114
4115
299k
   *point = p;
4116
299k
   (void)heap;
4117
299k
   return err;
4118
301k
} /* wc_ecc_new_point_ex */
4119
4120
ecc_point* wc_ecc_new_point_h(void* heap)
4121
44.1k
{
4122
44.1k
    ecc_point* p = NULL;
4123
44.1k
    (void)wc_ecc_new_point_ex(&p, heap);
4124
44.1k
    return p;
4125
44.1k
}
4126
4127
ecc_point* wc_ecc_new_point(void)
4128
13.9k
{
4129
13.9k
   ecc_point* p = NULL;
4130
13.9k
   (void)wc_ecc_new_point_ex(&p, NULL);
4131
13.9k
   return p;
4132
13.9k
}
4133
4134
/** Free an ECC point from memory
4135
  p   The point to free
4136
*/
4137
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4138
358k
{
4139
358k
   if (p != NULL) {
4140
299k
      mp_clear(p->x);
4141
299k
      mp_clear(p->y);
4142
299k
      mp_clear(p->z);
4143
299k
      if (p->isAllocated)
4144
299k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4145
299k
   }
4146
358k
   (void)heap;
4147
358k
}
4148
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4149
414
{
4150
414
   wc_ecc_del_point_ex(p, heap);
4151
414
}
4152
void wc_ecc_del_point(ecc_point* p)
4153
112k
{
4154
112k
    wc_ecc_del_point_ex(p, NULL);
4155
112k
}
4156
4157
void wc_ecc_forcezero_point(ecc_point* p)
4158
0
{
4159
0
    if (p != NULL) {
4160
0
        mp_forcezero(p->x);
4161
0
        mp_forcezero(p->y);
4162
0
        mp_forcezero(p->z);
4163
0
    }
4164
0
}
4165
4166
4167
/** Copy the value of a point to an other one
4168
  p    The point to copy
4169
  r    The created point
4170
*/
4171
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4172
912k
{
4173
912k
    int ret;
4174
4175
    /* prevents null arguments */
4176
912k
    if (p == NULL || r == NULL)
4177
0
        return ECC_BAD_ARG_E;
4178
4179
912k
    ret = mp_copy(p->x, r->x);
4180
912k
    if (ret != MP_OKAY)
4181
2
        return ret;
4182
912k
    ret = mp_copy(p->y, r->y);
4183
912k
    if (ret != MP_OKAY)
4184
2
        return ret;
4185
912k
    ret = mp_copy(p->z, r->z);
4186
912k
    if (ret != MP_OKAY)
4187
3
        return ret;
4188
4189
912k
    return MP_OKAY;
4190
912k
}
4191
4192
/** Compare the value of a point with an other one
4193
 a    The point to compare
4194
 b    The other point to compare
4195
4196
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4197
 */
4198
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4199
2.96k
{
4200
2.96k
    int ret;
4201
4202
    /* prevents null arguments */
4203
2.96k
    if (a == NULL || b == NULL)
4204
0
        return BAD_FUNC_ARG;
4205
4206
2.96k
    ret = mp_cmp(a->x, b->x);
4207
2.96k
    if (ret != MP_EQ)
4208
2.21k
        return ret;
4209
746
    ret = mp_cmp(a->y, b->y);
4210
746
    if (ret != MP_EQ)
4211
393
        return ret;
4212
353
    ret = mp_cmp(a->z, b->z);
4213
353
    if (ret != MP_EQ)
4214
23
        return ret;
4215
4216
330
    return MP_EQ;
4217
353
}
4218
4219
4220
/** Returns whether an ECC idx is valid or not
4221
  n      The idx number to check
4222
  return 1 if valid, 0 if not
4223
*/
4224
int wc_ecc_is_valid_idx(int n)
4225
49.7k
{
4226
49.7k
   int x;
4227
4228
49.7k
   if (n >= (int)ECC_SET_COUNT)
4229
0
       return 0;
4230
4231
1.17M
   for (x = 0; ecc_sets[x].size != 0; x++)
4232
1.12M
       ;
4233
   /* -1 is a valid index --- indicating that the domain params
4234
      were supplied by the user */
4235
49.7k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4236
49.7k
      return 1;
4237
49.7k
   }
4238
4239
0
   return 0;
4240
49.7k
}
4241
4242
int wc_ecc_get_curve_idx(int curve_id)
4243
40.3k
{
4244
40.3k
    int curve_idx;
4245
517k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4246
517k
        if (curve_id == ecc_sets[curve_idx].id)
4247
40.2k
            break;
4248
517k
    }
4249
40.3k
    if (ecc_sets[curve_idx].size == 0) {
4250
110
        return ECC_CURVE_INVALID;
4251
110
    }
4252
40.2k
    return curve_idx;
4253
40.3k
}
4254
4255
int wc_ecc_get_curve_id(int curve_idx)
4256
1.87k
{
4257
1.87k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4258
1.87k
        return ecc_sets[curve_idx].id;
4259
1.87k
    }
4260
0
    return ECC_CURVE_INVALID;
4261
1.87k
}
4262
4263
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4264
 *
4265
 * id      curve id, from ecc_curve_id enum in ecc.h
4266
 * return  curve size, from ecc_sets[] on success, negative on error
4267
 */
4268
int wc_ecc_get_curve_size_from_id(int curve_id)
4269
1.13k
{
4270
1.13k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4271
1.13k
    if (curve_idx == ECC_CURVE_INVALID)
4272
0
        return ECC_BAD_ARG_E;
4273
1.13k
    return ecc_sets[curve_idx].size;
4274
1.13k
}
4275
4276
/* Returns the curve index that corresponds to a given curve name in
4277
 * ecc_sets[] of ecc.c
4278
 *
4279
 * name    curve name, from ecc_sets[].name in ecc.c
4280
 * return  curve index in ecc_sets[] on success, negative on error
4281
 */
4282
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4283
0
{
4284
0
    int curve_idx;
4285
4286
0
    if (curveName == NULL)
4287
0
        return BAD_FUNC_ARG;
4288
4289
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4290
0
        if (
4291
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4292
0
            ecc_sets[curve_idx].name &&
4293
0
        #endif
4294
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4295
0
            break;
4296
0
        }
4297
0
    }
4298
0
    if (ecc_sets[curve_idx].size == 0) {
4299
0
        WOLFSSL_MSG("ecc_set curve name not found");
4300
0
        return ECC_CURVE_INVALID;
4301
0
    }
4302
0
    return curve_idx;
4303
0
}
4304
4305
/* Returns the curve size that corresponds to a given curve name,
4306
 * as listed in ecc_sets[] of ecc.c.
4307
 *
4308
 * name    curve name, from ecc_sets[].name in ecc.c
4309
 * return  curve size, from ecc_sets[] on success, negative on error
4310
 */
4311
int wc_ecc_get_curve_size_from_name(const char* curveName)
4312
0
{
4313
0
    int curve_idx;
4314
4315
0
    if (curveName == NULL)
4316
0
        return BAD_FUNC_ARG;
4317
4318
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4319
0
    if (curve_idx < 0)
4320
0
        return curve_idx;
4321
4322
0
    return ecc_sets[curve_idx].size;
4323
0
}
4324
4325
/* Returns the curve id that corresponds to a given curve name,
4326
 * as listed in ecc_sets[] of ecc.c.
4327
 *
4328
 * name   curve name, from ecc_sets[].name in ecc.c
4329
 * return curve id, from ecc_sets[] on success, negative on error
4330
 */
4331
int wc_ecc_get_curve_id_from_name(const char* curveName)
4332
0
{
4333
0
    int curve_idx;
4334
4335
0
    if (curveName == NULL)
4336
0
        return BAD_FUNC_ARG;
4337
4338
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4339
0
    if (curve_idx < 0)
4340
0
        return curve_idx;
4341
4342
0
    return ecc_sets[curve_idx].id;
4343
0
}
4344
4345
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4346
 * parameter for equality.
4347
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4348
 * Returns MP_EQ on success, negative on error */
4349
static int wc_ecc_cmp_param(const char* curveParam,
4350
                            const byte* param, word32 paramSz, int encType)
4351
0
{
4352
0
    int err = MP_OKAY;
4353
0
#ifdef WOLFSSL_SMALL_STACK
4354
0
    mp_int* a = NULL;
4355
0
    mp_int* b = NULL;
4356
#else
4357
    mp_int  a[1], b[1];
4358
#endif
4359
4360
0
    if (param == NULL || curveParam == NULL)
4361
0
        return BAD_FUNC_ARG;
4362
4363
0
    if (encType == WC_TYPE_HEX_STR) {
4364
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4365
0
            return -1;
4366
0
        return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1;
4367
0
    }
4368
4369
0
#ifdef WOLFSSL_SMALL_STACK
4370
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4371
0
    if (a == NULL)
4372
0
        return MEMORY_E;
4373
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4374
0
    if (b == NULL) {
4375
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4376
0
        return MEMORY_E;
4377
0
    }
4378
0
#endif
4379
4380
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4381
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4382
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4383
0
        return err;
4384
0
    }
4385
4386
0
    if (err == MP_OKAY) {
4387
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4388
0
    }
4389
0
    if (err == MP_OKAY)
4390
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4391
4392
0
    if (err == MP_OKAY) {
4393
0
        if (mp_cmp(a, b) != MP_EQ) {
4394
0
            err = -1;
4395
0
        } else {
4396
0
            err = MP_EQ;
4397
0
        }
4398
0
    }
4399
4400
0
    mp_clear(a);
4401
0
    mp_clear(b);
4402
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4403
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4404
4405
0
    return err;
4406
0
}
4407
4408
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4409
 * curve parameters.
4410
 *
4411
 * fieldSize  the field size in bits
4412
 * prime      prime of the finite field
4413
 * primeSz    size of prime in octets
4414
 * Af         first coefficient a of the curve
4415
 * AfSz       size of Af in octets
4416
 * Bf         second coefficient b of the curve
4417
 * BfSz       size of Bf in octets
4418
 * order      curve order
4419
 * orderSz    size of curve in octets
4420
 * Gx         affine x coordinate of base point
4421
 * GxSz       size of Gx in octets
4422
 * Gy         affine y coordinate of base point
4423
 * GySz       size of Gy in octets
4424
 * cofactor   curve cofactor
4425
 *
4426
 * return curve id, from ecc_sets[] on success, negative on error
4427
 */
4428
int wc_ecc_get_curve_id_from_params(int fieldSize,
4429
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4430
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4431
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4432
0
{
4433
0
    int idx;
4434
0
    int curveSz;
4435
4436
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4437
0
        Gx == NULL || Gy == NULL)
4438
0
        return BAD_FUNC_ARG;
4439
4440
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4441
4442
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4443
0
        if (curveSz == ecc_sets[idx].size) {
4444
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4445
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4446
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4447
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4448
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4449
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4450
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4451
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4452
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4453
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4454
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4455
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4456
0
                (cofactor == ecc_sets[idx].cofactor)) {
4457
0
                    break;
4458
0
            }
4459
0
        }
4460
0
    }
4461
4462
0
    if (ecc_sets[idx].size == 0)
4463
0
        return ECC_CURVE_INVALID;
4464
4465
0
    return ecc_sets[idx].id;
4466
0
}
4467
4468
/* Returns the curve id in ecc_sets[] that corresponds
4469
 * to a given domain parameters pointer.
4470
 *
4471
 * dp   domain parameters pointer
4472
 *
4473
 * return curve id, from ecc_sets[] on success, negative on error
4474
 */
4475
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4476
0
{
4477
0
    int idx;
4478
4479
0
    if (dp == NULL
4480
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4481
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4482
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4483
0
    #endif
4484
0
    ) {
4485
0
        return BAD_FUNC_ARG;
4486
0
    }
4487
4488
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4489
0
        if (dp->size == ecc_sets[idx].size) {
4490
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4491
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4492
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4493
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4494
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4495
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4496
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4497
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4498
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4499
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4500
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4501
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4502
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4503
0
                    break;
4504
0
            }
4505
0
        }
4506
0
    }
4507
4508
0
    if (ecc_sets[idx].size == 0)
4509
0
        return ECC_CURVE_INVALID;
4510
4511
0
    return ecc_sets[idx].id;
4512
0
}
4513
4514
/* Returns the curve id that corresponds to a given OID,
4515
 * as listed in ecc_sets[] of ecc.c.
4516
 *
4517
 * oid   OID, from ecc_sets[].name in ecc.c
4518
 * len   OID len, from ecc_sets[].name in ecc.c
4519
 * return curve id, from ecc_sets[] on success, negative on error
4520
 */
4521
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4522
0
{
4523
0
    int curve_idx;
4524
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4525
    int ret;
4526
    #ifdef HAVE_OID_DECODING
4527
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4528
    #else
4529
    byte  decOid[MAX_OID_SZ];
4530
    #endif
4531
    word32 decOidSz;
4532
#endif
4533
4534
0
    if (oid == NULL)
4535
0
        return BAD_FUNC_ARG;
4536
4537
#ifdef HAVE_OID_DECODING
4538
    decOidSz = (word32)sizeof(decOid);
4539
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4540
    if (ret != 0) {
4541
        return ret;
4542
    }
4543
#endif
4544
4545
0
    if (len == 0) {
4546
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4547
0
        WOLFSSL_MSG("zero oidSz");
4548
0
        return ECC_CURVE_INVALID;
4549
0
    }
4550
4551
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4552
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4553
        decOidSz = (word32)sizeof(decOid);
4554
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4555
            decOid, &decOidSz);
4556
        if (ret != 0) {
4557
            continue;
4558
        }
4559
    #endif
4560
4561
0
        if (
4562
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4563
0
            ecc_sets[curve_idx].oid &&
4564
0
        #endif
4565
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4566
            decOidSz == len &&
4567
                XMEMCMP(decOid, oid, len) == 0
4568
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4569
            /* We double because decOidSz is a count of word16 elements. */
4570
            ecc_sets[curve_idx].oidSz == decOidSz &&
4571
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4572
        #else
4573
0
            ecc_sets[curve_idx].oidSz == len &&
4574
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4575
0
        #endif
4576
0
        ) {
4577
0
            break;
4578
0
        }
4579
0
    }
4580
0
    if (ecc_sets[curve_idx].size == 0) {
4581
0
        WOLFSSL_MSG("ecc_set curve name not found");
4582
0
        return ECC_CURVE_INVALID;
4583
0
    }
4584
4585
0
    return ecc_sets[curve_idx].id;
4586
0
}
4587
4588
/* Get curve parameters using curve index */
4589
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4590
28.4k
{
4591
28.4k
    const ecc_set_type* ecc_set = NULL;
4592
4593
28.4k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4594
28.4k
        ecc_set = &ecc_sets[curve_idx];
4595
28.4k
    }
4596
28.4k
    return ecc_set;
4597
28.4k
}
4598
4599
4600
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4601
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4602
{
4603
   if (key == NULL || mp == NULL)
4604
      return BAD_FUNC_ARG;
4605
   if (*mp == NULL) {
4606
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4607
      if (*mp == NULL) {
4608
         return MEMORY_E;
4609
      }
4610
      XMEMSET(*mp, 0, sizeof(mp_int));
4611
   }
4612
   return 0;
4613
}
4614
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4615
{
4616
   if (key && mp && *mp) {
4617
      mp_clear(*mp);
4618
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4619
      *mp = NULL;
4620
   }
4621
}
4622
4623
static int wc_ecc_alloc_async(ecc_key* key)
4624
{
4625
    int err = wc_ecc_alloc_mpint(key, &key->r);
4626
    if (err == 0)
4627
        err = wc_ecc_alloc_mpint(key, &key->s);
4628
    return err;
4629
}
4630
4631
static void wc_ecc_free_async(ecc_key* key)
4632
{
4633
    wc_ecc_free_mpint(key, &key->r);
4634
    wc_ecc_free_mpint(key, &key->s);
4635
#ifdef HAVE_CAVIUM_V
4636
    wc_ecc_free_mpint(key, &key->e);
4637
    wc_ecc_free_mpint(key, &key->signK);
4638
#endif /* HAVE_CAVIUM_V */
4639
}
4640
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4641
4642
4643
#ifdef HAVE_ECC_DHE
4644
/**
4645
  Create an ECC shared secret between two keys
4646
  private_key      The private ECC key (heap hint based off of private key)
4647
  public_key       The public key
4648
  out              [out] Destination of the shared secret
4649
                         Conforms to EC-DH from ANSI X9.63
4650
  outlen           [in/out] The max size and resulting size of the shared secret
4651
  return           MP_OKAY if successful
4652
*/
4653
WOLFSSL_ABI
4654
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4655
                      word32* outlen)
4656
1.42k
{
4657
1.42k
   int err = 0;
4658
4659
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4660
   !defined(WOLFSSL_ATECC608A)
4661
   CRYS_ECDH_TempData_t tempBuff;
4662
#endif
4663
4664
1.42k
   (void)err;
4665
4666
1.42k
   if (private_key == NULL || public_key == NULL || out == NULL ||
4667
1.42k
                                                            outlen == NULL) {
4668
0
       return BAD_FUNC_ARG;
4669
0
   }
4670
4671
1.42k
#ifdef WOLF_CRYPTO_CB
4672
1.42k
    #ifndef WOLF_CRYPTO_CB_FIND
4673
1.42k
    if (private_key->devId != INVALID_DEVID)
4674
0
    #endif
4675
0
    {
4676
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4677
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4678
0
            return err;
4679
        /* fall-through when unavailable */
4680
0
    }
4681
1.42k
#endif
4682
4683
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4684
    return NO_VALID_DEVID;
4685
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4686
   /* type valid? */
4687
1.42k
   if (private_key->type != ECC_PRIVATEKEY &&
4688
338
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4689
0
      return ECC_BAD_ARG_E;
4690
0
   }
4691
4692
   /* Verify domain params supplied */
4693
1.42k
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4694
1.42k
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4695
0
      return ECC_BAD_ARG_E;
4696
0
   }
4697
4698
   /* Verify curve id matches */
4699
1.42k
   if (private_key->dp->id != public_key->dp->id) {
4700
0
      return ECC_BAD_ARG_E;
4701
0
   }
4702
4703
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4704
   /* For SECP256R1 use hardware */
4705
   if (private_key->dp->id == ECC_SECP256R1) {
4706
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4707
       *outlen = private_key->dp->size;
4708
   }
4709
   else {
4710
      err = NOT_COMPILED_IN;
4711
   }
4712
#elif defined(WOLFSSL_CRYPTOCELL)
4713
4714
    /* generate a secret*/
4715
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4716
                            &private_key->ctx.privKey,
4717
                            out,
4718
                            (uint32_t*)outlen,
4719
                            &tempBuff);
4720
4721
    if (err != SA_SILIB_RET_OK){
4722
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4723
        return err;
4724
    }
4725
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4726
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4727
#elif defined(WOLFSSL_KCAPI_ECC)
4728
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4729
#elif defined(WOLFSSL_SE050)
4730
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4731
#else
4732
1.42k
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4733
1.42k
#endif /* WOLFSSL_ATECC508A */
4734
1.42k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4735
4736
1.42k
   return err;
4737
1.42k
}
4738
4739
4740
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4741
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4742
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4743
4744
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4745
                               byte* out, word32* outlen)
4746
264
{
4747
264
    int err = MP_OKAY;
4748
264
    mp_int* k = ecc_get_k(private_key);
4749
#ifdef HAVE_ECC_CDH
4750
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
4751
#endif
4752
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4753
    defined(WC_ECC_NONBLOCK_ONLY)
4754
    ecc_nb_ctx_t nb_ctx;
4755
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4756
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4757
4758
#ifdef HAVE_ECC_CDH
4759
    /* if cofactor flag has been set */
4760
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4761
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4762
        /* only perform cofactor calc if not equal to 1 */
4763
        if (cofactor != 1) {
4764
#ifdef WOLFSSL_SMALL_STACK
4765
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4766
                return MEMORY_E;
4767
#endif
4768
            k = k_lcl;
4769
            if (mp_init(k) != MP_OKAY) {
4770
                err = MEMORY_E;
4771
                goto errout;
4772
            }
4773
            /* multiply cofactor times private key "k" */
4774
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4775
            if (err != MP_OKAY)
4776
                goto errout;
4777
        }
4778
    }
4779
#endif
4780
4781
#ifdef WOLFSSL_HAVE_SP_ECC
4782
4783
#ifndef WOLFSSL_SP_NO_256
4784
    if (private_key->idx != ECC_CUSTOM_IDX &&
4785
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4786
    #ifndef WC_ECC_NONBLOCK
4787
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4788
    #else
4789
        if (private_key->nb_ctx) {
4790
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4791
                                           point, out, outlen,
4792
                                           private_key->heap);
4793
        }
4794
        else {
4795
        #ifdef WC_ECC_NONBLOCK_ONLY
4796
            do { /* perform blocking call to non-blocking function */
4797
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4798
                                               outlen, private_key->heap);
4799
            } while (err == FP_WOULDBLOCK);
4800
        #else
4801
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4802
                                        private_key->heap);
4803
        #endif /* WC_ECC_NONBLOCK_ONLY */
4804
        }
4805
    #endif /* !WC_ECC_NONBLOCK */
4806
    }
4807
    else
4808
#endif /* ! WOLFSSL_SP_NO_256 */
4809
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4810
    if (private_key->idx != ECC_CUSTOM_IDX &&
4811
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4812
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4813
                                                             private_key->heap);
4814
    }
4815
    else
4816
#endif
4817
#ifdef WOLFSSL_SP_384
4818
    if (private_key->idx != ECC_CUSTOM_IDX &&
4819
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4820
    #ifndef WC_ECC_NONBLOCK
4821
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4822
    #else
4823
        if (private_key->nb_ctx) {
4824
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4825
                                           point, out, outlen,
4826
                                           private_key->heap);
4827
        }
4828
        else {
4829
        #ifdef WC_ECC_NONBLOCK_ONLY
4830
            do { /* perform blocking call to non-blocking function */
4831
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4832
                                               outlen, private_key->heap);
4833
            } while (err == FP_WOULDBLOCK);
4834
        #else
4835
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4836
                                        private_key->heap);
4837
        #endif /* WC_ECC_NONBLOCK_ONLY */
4838
        }
4839
    #endif /* !WC_ECC_NONBLOCK */
4840
    }
4841
    else
4842
#endif /* WOLFSSL_SP_384 */
4843
#ifdef WOLFSSL_SP_521
4844
    if (private_key->idx != ECC_CUSTOM_IDX &&
4845
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4846
    #ifndef WC_ECC_NONBLOCK
4847
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4848
    #else
4849
        if (private_key->nb_ctx) {
4850
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4851
                                           point, out, outlen,
4852
                                           private_key->heap);
4853
        }
4854
        else {
4855
        #ifdef WC_ECC_NONBLOCK_ONLY
4856
            do { /* perform blocking call to non-blocking function */
4857
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4858
                                               outlen, private_key->heap);
4859
            } while (err == FP_WOULDBLOCK);
4860
        #else
4861
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4862
                                        private_key->heap);
4863
        #endif /* WC_ECC_NONBLOCK_ONLY */
4864
        }
4865
    #endif /* !WC_ECC_NONBLOCK */
4866
    }
4867
    else
4868
#endif /* WOLFSSL_SP_521 */
4869
#else
4870
264
    (void)point;
4871
264
    (void)out;
4872
264
    (void)outlen;
4873
264
    (void)k;
4874
264
#endif
4875
#if defined(WOLFSSL_SP_MATH)
4876
    {
4877
        err = WC_KEY_SIZE_E;
4878
        goto errout;
4879
    }
4880
#else
4881
264
    {
4882
264
        ecc_point* result = NULL;
4883
        #ifdef WOLFSSL_NO_MALLOC
4884
        ecc_point  lcl_result;
4885
        #endif
4886
264
        int x = 0;
4887
264
        mp_digit mp = 0;
4888
264
        DECLARE_CURVE_SPECS(3);
4889
4890
        /* load curve info */
4891
264
        ALLOC_CURVE_SPECS(3, err);
4892
264
        if (err == MP_OKAY) {
4893
263
            err = wc_ecc_curve_load(private_key->dp, &curve,
4894
263
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4895
263
                 ECC_CURVE_FIELD_ORDER));
4896
263
        }
4897
4898
264
        if (err != MP_OKAY) {
4899
1
            FREE_CURVE_SPECS();
4900
1
            goto errout;
4901
1
        }
4902
4903
        /* make new point */
4904
    #ifdef WOLFSSL_NO_MALLOC
4905
        result = &lcl_result;
4906
    #endif
4907
263
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4908
263
        if (err != MP_OKAY) {
4909
1
            wc_ecc_curve_free(curve);
4910
1
            FREE_CURVE_SPECS();
4911
1
            goto errout;
4912
1
        }
4913
4914
262
#ifdef ECC_TIMING_RESISTANT
4915
262
        if (private_key->rng == NULL) {
4916
0
            err = MISSING_RNG_E;
4917
0
        }
4918
262
#endif
4919
4920
262
        if (err == MP_OKAY) {
4921
            /* Map in a separate call as this should be constant time */
4922
262
#ifdef ECC_TIMING_RESISTANT
4923
262
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4924
262
                                              curve->order, private_key->rng, 0,
4925
262
                                              private_key->heap);
4926
#else
4927
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4928
                                      curve->order, NULL, 0, private_key->heap);
4929
#endif
4930
262
        }
4931
262
        if (err == MP_OKAY) {
4932
        #ifdef WOLFSSL_CHECK_MEM_ZERO
4933
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
4934
                result->x);
4935
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
4936
                result->y);
4937
        #endif
4938
240
            err = mp_montgomery_setup(curve->prime, &mp);
4939
240
        }
4940
262
        if (err == MP_OKAY) {
4941
            /* Use constant time map if compiled in */
4942
240
            err = ecc_map_ex(result, curve->prime, mp, 1);
4943
240
        }
4944
262
        if (err == MP_OKAY) {
4945
240
            x = mp_unsigned_bin_size(curve->prime);
4946
240
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4947
0
                err = BUFFER_E;
4948
0
            }
4949
240
        }
4950
4951
262
        if (err == MP_OKAY) {
4952
240
            XMEMSET(out, 0, (size_t)x);
4953
240
            err = mp_to_unsigned_bin(result->x, out +
4954
240
                                     (x - mp_unsigned_bin_size(result->x)));
4955
240
        }
4956
262
        *outlen = (word32)x;
4957
4958
262
        mp_forcezero(result->x);
4959
262
        mp_forcezero(result->y);
4960
262
        wc_ecc_del_point_ex(result, private_key->heap);
4961
4962
262
        wc_ecc_curve_free(curve);
4963
262
        FREE_CURVE_SPECS();
4964
262
    }
4965
0
#endif
4966
4967
264
  errout:
4968
4969
#ifdef HAVE_ECC_CDH
4970
    if (k == k_lcl)
4971
        mp_clear(k);
4972
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
4973
#endif
4974
4975
264
    return err;
4976
262
}
4977
4978
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4979
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
4980
            ecc_point* point, byte* out, word32 *outlen)
4981
{
4982
    int err = 0;
4983
4984
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
4985
    DECLARE_CURVE_SPECS(3);
4986
4987
    /* load curve info */
4988
    ALLOC_CURVE_SPECS(3, err);
4989
    if (err == MP_OKAY) {
4990
        err = wc_ecc_curve_load(private_key->dp, &curve,
4991
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4992
             ECC_CURVE_FIELD_ORDER));
4993
    }
4994
4995
    if (err != MP_OKAY) {
4996
        FREE_CURVE_SPECS();
4997
        return err;
4998
    }
4999
5000
    if (private_key->dp
5001
    #ifdef WOLFSSL_CUSTOM_CURVES
5002
        && private_key->dp->id != ECC_CURVE_CUSTOM
5003
    #endif
5004
    #ifdef HAVE_CAVIUM_V
5005
        /* verify the curve is supported by hardware */
5006
        && NitroxEccIsCurveSupported(private_key)
5007
    #endif
5008
    ) {
5009
        word32 keySz = private_key->dp->size;
5010
5011
        /* sync public key x/y */
5012
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5013
            &ecc_get_k(private_key)->raw, keySz);
5014
        if (err == MP_OKAY)
5015
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5016
        if (err == MP_OKAY)
5017
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5018
    #ifdef HAVE_CAVIUM_V
5019
        /* allocate buffer for output */
5020
        if (err == MP_OKAY)
5021
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5022
        if (err == MP_OKAY)
5023
            err = wc_bigint_alloc(&private_key->e->raw,
5024
                NitroxEccGetSize(private_key)*2);
5025
        if (err == MP_OKAY)
5026
            err = NitroxEcdh(private_key,
5027
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5028
                private_key->e->raw.buf, &private_key->e->raw.len,
5029
                &curve->prime->raw);
5030
    #else
5031
        if (err == MP_OKAY)
5032
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5033
        if (err == MP_OKAY)
5034
            err = IntelQaEcdh(&private_key->asyncDev,
5035
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5036
                out, outlen,
5037
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5038
                private_key->dp->cofactor);
5039
    #endif
5040
    }
5041
    else
5042
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5043
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5044
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5045
        sw->eccSharedSec.private_key = private_key;
5046
        sw->eccSharedSec.public_point = point;
5047
        sw->eccSharedSec.out = out;
5048
        sw->eccSharedSec.outLen = outlen;
5049
        err = WC_PENDING_E;
5050
    }
5051
    else
5052
#endif
5053
    {
5054
        /* use sync in other cases */
5055
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5056
    }
5057
5058
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5059
        private_key->state++;
5060
    }
5061
5062
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5063
    wc_ecc_curve_free(curve);
5064
    FREE_CURVE_SPECS();
5065
#endif
5066
5067
    return err;
5068
}
5069
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5070
5071
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5072
/**
5073
 Create an ECC shared secret between private key and public point
5074
 private_key      The private ECC key (heap hint based on private key)
5075
 point            The point to use (public key)
5076
 out              [out] Destination of the shared secret
5077
                        Conforms to EC-DH from ANSI X9.63
5078
 outlen           [in/out] The max size and resulting size of the shared secret
5079
 return           MP_OKAY if successful
5080
*/
5081
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5082
                            byte* out, word32 *outlen)
5083
1.42k
{
5084
1.42k
    int err;
5085
5086
1.42k
    if (private_key == NULL || point == NULL || out == NULL ||
5087
1.42k
                                                            outlen == NULL) {
5088
0
        return BAD_FUNC_ARG;
5089
0
    }
5090
5091
    /* type valid? */
5092
1.42k
    if (private_key->type != ECC_PRIVATEKEY &&
5093
338
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5094
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5095
0
        return ECC_BAD_ARG_E;
5096
0
    }
5097
5098
    /* Verify domain params supplied */
5099
1.42k
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5100
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5101
0
        return ECC_BAD_ARG_E;
5102
0
    }
5103
5104
1.42k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5105
5106
1.42k
    switch (private_key->state) {
5107
1.42k
        case ECC_STATE_NONE:
5108
1.42k
        case ECC_STATE_SHARED_SEC_GEN:
5109
1.42k
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5110
5111
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5112
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5113
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5114
                    out, outlen);
5115
            }
5116
            else
5117
        #endif
5118
1.42k
            {
5119
1.42k
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5120
1.42k
                    out, outlen);
5121
1.42k
            }
5122
1.42k
            if (err < 0) {
5123
89
                break;
5124
89
            }
5125
1.34k
            FALL_THROUGH;
5126
5127
1.34k
        case ECC_STATE_SHARED_SEC_RES:
5128
1.34k
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5129
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5130
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5131
            #ifdef HAVE_CAVIUM_V
5132
                /* verify the curve is supported by hardware */
5133
                if (NitroxEccIsCurveSupported(private_key)) {
5134
                    /* copy output */
5135
                    *outlen = private_key->dp->size;
5136
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5137
                }
5138
            #endif /* HAVE_CAVIUM_V */
5139
            }
5140
        #endif /* WOLFSSL_ASYNC_CRYPT */
5141
1.34k
            err = 0;
5142
1.34k
            break;
5143
5144
0
        default:
5145
0
            err = BAD_STATE_E;
5146
1.42k
    } /* switch */
5147
5148
1.42k
    RESTORE_VECTOR_REGISTERS();
5149
5150
    /* if async pending then return and skip done cleanup below */
5151
1.42k
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5152
0
        return err;
5153
0
    }
5154
5155
    /* cleanup */
5156
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5157
    wc_ecc_free_async(private_key);
5158
#endif
5159
1.42k
    private_key->state = ECC_STATE_NONE;
5160
5161
1.42k
    return err;
5162
1.42k
}
5163
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5164
#elif defined(WOLFSSL_KCAPI_ECC)
5165
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5166
                            byte* out, word32 *outlen)
5167
{
5168
    int err;
5169
    ecc_key public_key;
5170
5171
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
5172
    if (err == MP_OKAY) {
5173
        #if FIPS_VERSION3_GE(6,0,0)
5174
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5175
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5176
         * keysize here when relying on default selection */
5177
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5178
            if (private_key->dp->size == 0 &&
5179
                (private_key->dp->id == ECC_SECP256R1 ||
5180
                private_key->dp->id == ECC_SECP224R1 ||
5181
                private_key->dp->id == ECC_SECP384R1 ||
5182
                private_key->dp->id == ECC_SECP521R1)) {
5183
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5184
                err = 0;
5185
            } else {
5186
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5187
                err = ECC_CURVE_OID_E;
5188
            }
5189
        }
5190
        if (err == 0) { /* FIPS specific check */
5191
        #endif
5192
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
5193
                               private_key->dp->id);
5194
        if (err == MP_OKAY) {
5195
            err = mp_copy(point->x, public_key.pubkey.x);
5196
        }
5197
        #if FIPS_VERSION3_GE(6,0,0)
5198
        } /* end FIPS specific check */
5199
        #endif
5200
        if (err == MP_OKAY) {
5201
            err = mp_copy(point->y, public_key.pubkey.y);
5202
        }
5203
        if (err == MP_OKAY) {
5204
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
5205
        }
5206
5207
        wc_ecc_free(&public_key);
5208
    }
5209
5210
    return err;
5211
}
5212
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5213
#endif /* HAVE_ECC_DHE */
5214
5215
#ifdef USE_ECC_B_PARAM
5216
/* Checks if a point p lies on the curve with index curve_idx */
5217
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5218
7.72k
{
5219
7.72k
    int err = MP_OKAY;
5220
7.72k
    DECLARE_CURVE_SPECS(3);
5221
5222
7.72k
    if (p == NULL)
5223
0
        return BAD_FUNC_ARG;
5224
5225
    /* is the IDX valid ?  */
5226
7.72k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5227
0
       return ECC_BAD_ARG_E;
5228
0
    }
5229
5230
7.72k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5231
5232
7.72k
    ALLOC_CURVE_SPECS(3, err);
5233
7.72k
    if (err == MP_OKAY) {
5234
7.39k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5235
7.39k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5236
7.39k
                                ECC_CURVE_FIELD_BF);
5237
7.39k
    }
5238
5239
7.72k
    if (err == MP_OKAY) {
5240
7.39k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5241
7.39k
    }
5242
5243
7.72k
    wc_ecc_curve_free(curve);
5244
7.72k
    FREE_CURVE_SPECS();
5245
5246
7.72k
    RESTORE_VECTOR_REGISTERS();
5247
5248
7.72k
    return err;
5249
7.72k
}
5250
#endif /* USE_ECC_B_PARAM */
5251
5252
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5253
    !defined(WOLFSSL_CRYPTOCELL) && \
5254
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5255
      defined(WOLFSSL_IMXRT1170_CAAM))
5256
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5257
int wc_ecc_point_is_at_infinity(ecc_point* p)
5258
11.5k
{
5259
11.5k
    if (p == NULL)
5260
0
        return BAD_FUNC_ARG;
5261
11.5k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5262
3.68k
        return 1;
5263
5264
7.84k
    return 0;
5265
11.5k
}
5266
#endif
5267
5268
/* generate random and ensure its greater than 0 and less than order */
5269
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5270
46.8k
{
5271
46.8k
#ifndef WC_NO_RNG
5272
46.8k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5273
46.8k
    int err;
5274
46.8k
    byte buf[ECC_MAXSIZE_GEN];
5275
5276
46.8k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5277
46.8k
                                                                order == NULL) {
5278
0
        return BAD_FUNC_ARG;
5279
0
    }
5280
5281
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5282
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5283
46.8k
    size += 8;
5284
5285
    /* make up random string */
5286
46.8k
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5287
#ifdef WOLFSSL_CHECK_MEM_ZERO
5288
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5289
#endif
5290
5291
    /* load random buffer data into k */
5292
46.8k
    if (err == 0)
5293
46.5k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5294
5295
    /* the key should be smaller than the order of base point */
5296
46.8k
    if (err == MP_OKAY) {
5297
46.5k
        if (mp_cmp(k, order) != MP_LT) {
5298
46.2k
            err = mp_mod(k, order, k);
5299
46.2k
        }
5300
46.5k
    }
5301
5302
    /* quick sanity check to make sure we're not dealing with a 0 key */
5303
46.8k
    if (err == MP_OKAY) {
5304
46.4k
        if (mp_iszero(k) == MP_YES)
5305
255
          err = MP_ZERO_E;
5306
46.4k
    }
5307
5308
46.8k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5309
#ifdef WOLFSSL_CHECK_MEM_ZERO
5310
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5311
#endif
5312
5313
46.8k
    return err;
5314
#else
5315
    int err;
5316
    byte buf[ECC_MAXSIZE_GEN];
5317
    int bits;
5318
5319
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5320
            (k == NULL) || (order == NULL)) {
5321
        return BAD_FUNC_ARG;
5322
    }
5323
5324
    /* Get actual bit count of order. */
5325
    bits = mp_count_bits(order);
5326
    size = (bits + 7) >> 3;
5327
5328
    /* generate number in range of order through rejection sampling. */
5329
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5330
    do {
5331
        /* A.2.2 step 3: make up random string */
5332
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5333
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5334
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5335
    #endif
5336
        /* Generated multiple of 8 bits but now make it size of order. */
5337
        if ((bits & 0x7) > 0) {
5338
            buf[0] &= (1 << (bits & 0x7)) - 1;
5339
        }
5340
5341
        /* A.2.2 step 4: convert to integer. */
5342
        /* A.4.2 step 3: Convert the bit string to integer x. */
5343
        if (err == 0) {
5344
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5345
        }
5346
5347
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5348
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5349
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5350
            break;
5351
        }
5352
    }
5353
    while (err == MP_OKAY);
5354
5355
    ForceZero(buf, ECC_MAXSIZE_GEN);
5356
#ifdef WOLFSSL_CHECK_MEM_ZERO
5357
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5358
#endif
5359
5360
    return err;
5361
#endif
5362
#else
5363
    (void)rng;
5364
    (void)size;
5365
    (void)k;
5366
    (void)order;
5367
    return NOT_COMPILED_IN;
5368
#endif /* !WC_NO_RNG */
5369
46.8k
}
5370
5371
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5372
51.8k
{
5373
    /* make sure required key variables are reset */
5374
51.8k
    key->state = ECC_STATE_NONE;
5375
51.8k
}
5376
5377
5378
/* create the public ECC key from a private key
5379
 *
5380
 * key     an initialized private key to generate public part from
5381
 * curve   [in]curve for key, cannot be NULL
5382
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5383
 *         is cached in key instead.
5384
 *
5385
 * Note this function is local to the file because of the argument type
5386
 *      ecc_curve_spec. Having this argument allows for not having to load the
5387
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5388
 * For async the results are placed directly into pubOut, so this function
5389
 *      does not need to be called again
5390
 *
5391
 * returns MP_OKAY on success
5392
 */
5393
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5394
        ecc_point* pubOut, WC_RNG* rng)
5395
3.41k
{
5396
3.41k
    int err = MP_OKAY;
5397
3.41k
#ifdef HAVE_ECC_MAKE_PUB
5398
3.41k
    ecc_point* pub;
5399
3.41k
#endif /* HAVE_ECC_MAKE_PUB */
5400
5401
3.41k
    (void)rng;
5402
5403
3.41k
    if (key == NULL) {
5404
0
        return BAD_FUNC_ARG;
5405
0
    }
5406
5407
3.41k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5408
5409
3.41k
#ifdef HAVE_ECC_MAKE_PUB
5410
    /* if ecc_point passed in then use it as output for public key point */
5411
3.41k
    if (pubOut != NULL) {
5412
855
        pub = pubOut;
5413
855
    }
5414
2.56k
    else {
5415
        /* caching public key making it a ECC_PRIVATEKEY instead of
5416
           ECC_PRIVATEKEY_ONLY */
5417
2.56k
        pub = &key->pubkey;
5418
2.56k
        key->type = ECC_PRIVATEKEY_ONLY;
5419
2.56k
    }
5420
5421
3.41k
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5422
3.41k
            mp_isneg(ecc_get_k(key)) ||
5423
3.41k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5424
40
        err = ECC_PRIV_KEY_E;
5425
40
    }
5426
5427
3.41k
    if (err == MP_OKAY) {
5428
3.37k
    #ifndef ALT_ECC_SIZE
5429
3.37k
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5430
    #else
5431
        pub->x = (mp_int*)&pub->xyz[0];
5432
        pub->y = (mp_int*)&pub->xyz[1];
5433
        pub->z = (mp_int*)&pub->xyz[2];
5434
        alt_fp_init(pub->x);
5435
        alt_fp_init(pub->y);
5436
        alt_fp_init(pub->z);
5437
    #endif
5438
3.37k
    }
5439
5440
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5441
    defined(HAVE_INTEL_QA)
5442
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5443
        word32 keySz = key->dp->size;
5444
        /* sync private key to raw */
5445
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5446
        if (err == MP_OKAY) {
5447
            err = IntelQaEccPointMul(&key->asyncDev,
5448
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5449
                &curve->Gx->raw, &curve->Gy->raw,
5450
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5451
                key->dp->cofactor);
5452
        }
5453
    }
5454
    else
5455
#endif
5456
3.41k
    { /* BEGIN: Software Crypto */
5457
#ifdef WOLFSSL_HAVE_SP_ECC
5458
    /* Single-Precision Math (optimized for specific curves) */
5459
    if (err != MP_OKAY) {
5460
    }
5461
    else
5462
#ifndef WOLFSSL_SP_NO_256
5463
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5464
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5465
    }
5466
    else
5467
#endif /* WOLFSSL_SP_NO_256 */
5468
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5469
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5470
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5471
    }
5472
    else
5473
#endif
5474
#ifdef WOLFSSL_SP_384
5475
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5476
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5477
    }
5478
    else
5479
#endif
5480
#ifdef WOLFSSL_SP_521
5481
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5482
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5483
    }
5484
    else
5485
#endif
5486
#endif /* WOLFSSL_HAVE_SP_ECC */
5487
5488
#if defined(WOLFSSL_SP_MATH)
5489
        err = WC_KEY_SIZE_E;
5490
#else
5491
3.41k
    if (err == MP_OKAY) {
5492
        /* Multi-Precision Math: compute public curve */
5493
3.37k
        mp_digit mp = 0;
5494
3.37k
        ecc_point* base = NULL;
5495
    #ifdef WOLFSSL_NO_MALLOC
5496
        ecc_point  lcl_base;
5497
        base = &lcl_base;
5498
    #endif
5499
3.37k
        err = wc_ecc_new_point_ex(&base, key->heap);
5500
5501
        /* read in the x/y for this key */
5502
3.37k
        if (err == MP_OKAY)
5503
3.31k
            err = mp_copy(curve->Gx, base->x);
5504
3.37k
        if (err == MP_OKAY)
5505
3.31k
            err = mp_copy(curve->Gy, base->y);
5506
3.37k
        if (err == MP_OKAY)
5507
3.31k
            err = mp_montgomery_setup(curve->prime, &mp);
5508
3.37k
        if (err == MP_OKAY)
5509
3.31k
            err = mp_set(base->z, 1);
5510
5511
        /* make the public key */
5512
3.37k
        if (err == MP_OKAY) {
5513
            /* Map in a separate call as this should be constant time */
5514
3.31k
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5515
3.31k
                                 curve->prime, curve->order, rng, 0, key->heap);
5516
3.31k
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5517
19
               err = MEMORY_E;
5518
19
            }
5519
3.31k
        }
5520
3.37k
        if (err == MP_OKAY) {
5521
            /* Use constant time map if compiled in */
5522
3.20k
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5523
3.20k
        }
5524
5525
3.37k
        wc_ecc_del_point_ex(base, key->heap);
5526
3.37k
    }
5527
3.41k
#endif /* WOLFSSL_SP_MATH */
5528
3.41k
    } /* END: Software Crypto */
5529
5530
3.41k
    if (err != MP_OKAY
5531
    #ifdef WOLFSSL_ASYNC_CRYPT
5532
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5533
    #endif
5534
3.41k
    ) {
5535
        /* clean up if failed */
5536
253
    #ifndef ALT_ECC_SIZE
5537
253
        mp_clear(pub->x);
5538
253
        mp_clear(pub->y);
5539
253
        mp_clear(pub->z);
5540
253
    #endif
5541
253
    }
5542
5543
#else
5544
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5545
    (void)curve;
5546
    err = NOT_COMPILED_IN;
5547
#endif /* HAVE_ECC_MAKE_PUB */
5548
5549
    /* change key state if public part is cached */
5550
3.41k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5551
2.56k
        key->type = ECC_PRIVATEKEY;
5552
2.56k
    }
5553
5554
3.41k
    RESTORE_VECTOR_REGISTERS();
5555
5556
3.41k
    return err;
5557
3.41k
}
5558
5559
5560
/* create the public ECC key from a private key
5561
 *
5562
 * key     an initialized private key to generate public part from
5563
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5564
 *         is cached in key instead.
5565
 *
5566
 *
5567
 * returns MP_OKAY on success
5568
 */
5569
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5570
5.67k
{
5571
5.67k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5572
5573
5.67k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5574
5.67k
}
5575
5576
/* create the public ECC key from a private key - mask timing use random z
5577
 *
5578
 * key     an initialized private key to generate public part from
5579
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5580
 *         is cached in key instead.
5581
 *
5582
 *
5583
 * returns MP_OKAY on success
5584
 */
5585
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5586
2.51k
{
5587
2.51k
    int err = MP_OKAY;
5588
2.51k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5589
5590
2.51k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5591
5592
2.51k
    if (key == NULL) {
5593
0
        return BAD_FUNC_ARG;
5594
0
    }
5595
5596
    /* load curve info */
5597
2.51k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5598
2.51k
    if (err == MP_OKAY) {
5599
2.47k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5600
2.47k
    }
5601
2.51k
    if (err == MP_OKAY) {
5602
2.47k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5603
2.47k
    }
5604
5605
2.51k
    wc_ecc_curve_free(curve);
5606
2.51k
    FREE_CURVE_SPECS();
5607
5608
2.51k
    return err;
5609
2.51k
}
5610
5611
5612
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5613
        int curve_id, int flags)
5614
13.0k
{
5615
13.0k
    int err = 0;
5616
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5617
    !defined(WOLFSSL_ATECC608A)
5618
    const CRYS_ECPKI_Domain_t*  pDomain;
5619
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5620
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5621
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5622
    word32 raw_size = 0;
5623
#endif
5624
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5625
    defined(WC_ECC_NONBLOCK_ONLY)
5626
    ecc_nb_ctx_t nb_ctx;
5627
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5628
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5629
5630
13.0k
    if (key == NULL || rng == NULL) {
5631
0
        return BAD_FUNC_ARG;
5632
0
    }
5633
5634
    /* make sure required variables are reset */
5635
13.0k
    wc_ecc_reset(key);
5636
5637
    #if FIPS_VERSION3_GE(6,0,0)
5638
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5639
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5640
     * keysize here when relying on default selection */
5641
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5642
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5643
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5644
             curve_id == ECC_SECP521R1)) {
5645
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5646
            err = 0;
5647
        } else {
5648
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5649
            err = ECC_CURVE_OID_E;
5650
        }
5651
    }
5652
    if (err == 0) { /* FIPS specific check */
5653
    #endif
5654
13.0k
    err = wc_ecc_set_curve(key, keysize, curve_id);
5655
13.0k
    if (err != 0) {
5656
0
        return err;
5657
0
    }
5658
    #if FIPS_VERSION3_GE(6,0,0)
5659
    } /* end FIPS specific check */
5660
    #endif
5661
13.0k
    key->flags = (byte)flags;
5662
5663
13.0k
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5664
13.0k
    #ifndef WOLF_CRYPTO_CB_FIND
5665
13.0k
    if (key->devId != INVALID_DEVID)
5666
0
    #endif
5667
0
    {
5668
0
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5669
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5670
0
            return err;
5671
        /* fall-through when unavailable */
5672
0
    }
5673
13.0k
#endif
5674
5675
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5676
    return NO_VALID_DEVID;
5677
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5678
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5679
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5680
    #ifdef HAVE_CAVIUM
5681
        /* TODO: Not implemented */
5682
    #elif defined(HAVE_INTEL_QA)
5683
        /* Implemented in ecc_make_pub_ex for the pub calc */
5684
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5685
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5686
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5687
            sw->eccMake.rng = rng;
5688
            sw->eccMake.key = key;
5689
            sw->eccMake.size = keysize;
5690
            sw->eccMake.curve_id = curve_id;
5691
            return WC_PENDING_E;
5692
        }
5693
    #endif
5694
    }
5695
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5696
5697
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5698
   if (key->dp->id == ECC_SECP256R1) {
5699
       key->type = ECC_PRIVATEKEY;
5700
       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5701
       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
5702
5703
       /* populate key->pubkey */
5704
       if (err == 0
5705
       #ifdef ALT_ECC_SIZE
5706
          && key->pubkey.x
5707
       #endif
5708
       ) {
5709
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5710
                                      ECC_MAX_CRYPTO_HW_SIZE);
5711
       }
5712
       if (err == 0
5713
       #ifdef ALT_ECC_SIZE
5714
          && key->pubkey.y
5715
       #endif
5716
       ) {
5717
           err = mp_read_unsigned_bin(key->pubkey.y,
5718
                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
5719
                                      ECC_MAX_CRYPTO_HW_SIZE);
5720
       }
5721
   }
5722
   else {
5723
      err = NOT_COMPILED_IN;
5724
   }
5725
#elif defined(WOLFSSL_SE050)
5726
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5727
    key->type = ECC_PRIVATEKEY;
5728
#elif defined(WOLFSSL_CRYPTOCELL)
5729
5730
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5731
    raw_size = (word32)(key->dp->size)*2 + 1;
5732
5733
    /* generate first key pair */
5734
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5735
                                wc_rndGenVectFunc,
5736
                                pDomain,
5737
                                &key->ctx.privKey,
5738
                                &key->ctx.pubKey,
5739
                                &tempBuff,
5740
                                &fipsCtx);
5741
5742
    if (err != SA_SILIB_RET_OK){
5743
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5744
        return err;
5745
    }
5746
    key->type = ECC_PRIVATEKEY;
5747
5748
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5749
                                   CRYS_EC_PointUncompressed,
5750
                                   &ucompressed_key[0],
5751
                                   (uint32_t*)&raw_size);
5752
5753
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5754
        err = mp_read_unsigned_bin(key->pubkey.x,
5755
                                   &ucompressed_key[1], key->dp->size);
5756
        if (err == MP_OKAY) {
5757
            err = mp_read_unsigned_bin(key->pubkey.y,
5758
                            &ucompressed_key[1+key->dp->size],key->dp->size);
5759
        }
5760
    }
5761
    raw_size = key->dp->size;
5762
    if (err == MP_OKAY) {
5763
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
5764
                                       ucompressed_key,
5765
                                       (uint32_t*)&raw_size);
5766
    }
5767
5768
    if (err == SA_SILIB_RET_OK) {
5769
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
5770
#ifdef WOLFSSL_ECC_BLIND_K
5771
        if (err == MP_OKAY) {
5772
            err = ecc_blind_k_rng(key, rng);
5773
        }
5774
#endif
5775
    }
5776
5777
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5778
    return silabs_ecc_make_key(key, keysize);
5779
#elif defined(WOLFSSL_KCAPI_ECC)
5780
5781
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
5782
    (void)rng;
5783
5784
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
5785
    if (xil_curve_type[key->dp->id] == 0)
5786
        return ECC_CURVE_OID_E;
5787
5788
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
5789
    if (err)
5790
        return err;
5791
    /* Make sure that private key is max. 521 bits */
5792
    if (key->dp->size == 66)
5793
        key->privKey[65] &= 0x1U;
5794
5795
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
5796
5797
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5798
                                        2 * key->dp->size);
5799
5800
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
5801
                                      xil_curve_type[key->dp->id],
5802
                                      XIL_CAST_U64(key->privKey),
5803
                                      XIL_CAST_U64(key->keyRaw));
5804
    if (err != XST_SUCCESS) {
5805
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
5806
        err = WC_HW_E;
5807
    }
5808
5809
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5810
                                        2 * key->dp->size);
5811
5812
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
5813
    if (err == 0)
5814
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
5815
                                          xil_curve_type[key->dp->id],
5816
                                          XIL_CAST_U64(key->keyRaw));
5817
#endif
5818
5819
    if (err == 0)
5820
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
5821
                             key->heap);
5822
    if (err == 0)
5823
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
5824
                             key->dp->size, key->heap);
5825
    if (err == 0)
5826
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
5827
                             key->heap);
5828
#ifdef WOLFSSL_ECC_BLIND_K
5829
    if (err == 0)
5830
        err = ecc_blind_k_rng(key, rng);
5831
#endif
5832
    if (err == 0)
5833
        err = mp_set(key->pubkey.z, 1);
5834
    if (err) {
5835
        key->privKey = NULL;
5836
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
5837
        return err;
5838
    }
5839
5840
    key->type = ECC_PRIVATEKEY;
5841
5842
#else
5843
5844
#ifdef WOLFSSL_HAVE_SP_ECC
5845
5846
#ifndef WOLFSSL_SP_NO_256
5847
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5848
    #ifndef WC_ECC_NONBLOCK
5849
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5850
    #else
5851
        if (key->nb_ctx) {
5852
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5853
                                         &key->pubkey, key->heap);
5854
        }
5855
        else {
5856
        #ifdef WC_ECC_NONBLOCK_ONLY
5857
            do { /* perform blocking call to non-blocking function */
5858
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
5859
                                             &key->pubkey, key->heap);
5860
            } while (err == FP_WOULDBLOCK);
5861
        #else
5862
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5863
        #endif /* WC_ECC_NONBLOCK_ONLY */
5864
        }
5865
    #endif /* !WC_ECC_NONBLOCK */
5866
5867
        if (err == MP_OKAY) {
5868
            key->type = ECC_PRIVATEKEY;
5869
        }
5870
    }
5871
    else
5872
#endif /* !WOLFSSL_SP_NO_256 */
5873
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5874
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5875
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
5876
        if (err == MP_OKAY) {
5877
            key->type = ECC_PRIVATEKEY;
5878
        }
5879
    }
5880
    else
5881
#endif
5882
#ifdef WOLFSSL_SP_384
5883
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5884
    #ifndef WC_ECC_NONBLOCK
5885
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5886
    #else
5887
        if (key->nb_ctx) {
5888
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5889
                                         &key->pubkey, key->heap);
5890
        }
5891
        else {
5892
        #ifdef WC_ECC_NONBLOCK_ONLY
5893
            do { /* perform blocking call to non-blocking function */
5894
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
5895
                                             &key->pubkey, key->heap);
5896
            } while (err == FP_WOULDBLOCK);
5897
        #else
5898
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5899
        #endif /* WC_ECC_NONBLOCK_ONLY */
5900
        }
5901
    #endif /* !WC_ECC_NONBLOCK */
5902
5903
        if (err == MP_OKAY) {
5904
            key->type = ECC_PRIVATEKEY;
5905
        }
5906
    }
5907
    else
5908
#endif /* WOLFSSL_SP_384 */
5909
#ifdef WOLFSSL_SP_521
5910
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5911
    #ifndef WC_ECC_NONBLOCK
5912
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5913
    #else
5914
        if (key->nb_ctx) {
5915
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5916
                                         &key->pubkey, key->heap);
5917
        }
5918
        else {
5919
        #ifdef WC_ECC_NONBLOCK_ONLY
5920
            do { /* perform blocking call to non-blocking function */
5921
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
5922
                                             &key->pubkey, key->heap);
5923
            } while (err == FP_WOULDBLOCK);
5924
        #else
5925
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5926
        #endif /* WC_ECC_NONBLOCK_ONLY */
5927
        }
5928
    #endif /* !WC_ECC_NONBLOCK */
5929
5930
        if (err == MP_OKAY) {
5931
            key->type = ECC_PRIVATEKEY;
5932
        }
5933
    }
5934
    else
5935
#endif /* WOLFSSL_SP_521 */
5936
#endif /* WOLFSSL_HAVE_SP_ECC */
5937
5938
13.0k
   { /* software key gen */
5939
#if defined(WOLFSSL_SP_MATH)
5940
        err = WC_KEY_SIZE_E;
5941
#else
5942
13.0k
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5943
5944
        /* setup the key variables */
5945
13.0k
#ifndef ALT_ECC_SIZE
5946
13.0k
        err = mp_init(key->k);
5947
#else
5948
        err = 0;
5949
        key->k = (mp_int*)key->ka;
5950
        alt_fp_init(key->k);
5951
#endif
5952
5953
        /* load curve info */
5954
13.0k
        if (err == MP_OKAY) {
5955
13.0k
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5956
13.0k
            if (err != MP_OKAY) {
5957
53
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5958
53
            }
5959
13.0k
        }
5960
5961
13.0k
        if (err == MP_OKAY) {
5962
12.9k
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5963
12.9k
            if (err != MP_OKAY) {
5964
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5965
0
            }
5966
12.9k
        }
5967
5968
        /* generate k */
5969
13.0k
        if (err == MP_OKAY) {
5970
12.9k
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5971
12.9k
            if (err != MP_OKAY) {
5972
199
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5973
199
            }
5974
12.9k
        }
5975
5976
        /* generate public key from k */
5977
13.0k
        if (err == MP_OKAY) {
5978
12.7k
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5979
12.7k
            if (err != MP_OKAY) {
5980
1.91k
                WOLFSSL_MSG("ecc_make_pub_ex failed");
5981
1.91k
            }
5982
12.7k
        }
5983
5984
13.0k
        if (err == MP_OKAY
5985
        #ifdef WOLFSSL_ASYNC_CRYPT
5986
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
5987
        #endif
5988
13.0k
        ) {
5989
10.8k
            key->type = ECC_PRIVATEKEY;
5990
10.8k
        }
5991
2.16k
        else {
5992
            /* cleanup these on failure case only */
5993
2.16k
            mp_forcezero(key->k);
5994
2.16k
        }
5995
5996
        /* cleanup allocations */
5997
13.0k
        wc_ecc_curve_free(curve);
5998
13.0k
        FREE_CURVE_SPECS();
5999
13.0k
#endif /* WOLFSSL_SP_MATH */
6000
13.0k
    }
6001
6002
#ifdef HAVE_WOLF_BIGINT
6003
    if (err == MP_OKAY)
6004
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6005
    if (err == MP_OKAY)
6006
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6007
    if (err == MP_OKAY)
6008
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6009
    if (err == MP_OKAY)
6010
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6011
#endif
6012
6013
#ifdef WOLFSSL_ECC_BLIND_K
6014
    if (err == MP_OKAY)
6015
        err = ecc_blind_k_rng(key, rng);
6016
#endif
6017
6018
13.0k
#endif /* HAVE_ECC_MAKE_PUB */
6019
6020
13.0k
    return err;
6021
13.0k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6022
13.0k
}
6023
6024
6025
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6026
                        int flags)
6027
14.4k
{
6028
14.4k
    int err;
6029
6030
14.4k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6031
6032
14.4k
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6033
6034
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6035
    !defined(WOLFSSL_KCAPI_ECC)
6036
    if (err == MP_OKAY) {
6037
        err = _ecc_validate_public_key(key, 0, 0);
6038
    }
6039
    if (err == MP_OKAY
6040
#if defined(WOLF_CRYPTO_CB)
6041
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6042
        && key->devId == INVALID_DEVID
6043
#endif
6044
        ) {
6045
        err = _ecc_pairwise_consistency_test(key, rng);
6046
    }
6047
#endif
6048
6049
14.4k
    RESTORE_VECTOR_REGISTERS();
6050
6051
14.4k
    return err;
6052
14.4k
}
6053
6054
WOLFSSL_ABI
6055
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6056
14.4k
{
6057
14.4k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6058
14.4k
}
6059
6060
#ifdef ECC_DUMP_OID
6061
/* Optional dump of encoded OID for adding new curves */
6062
static int mOidDumpDone;
6063
static void wc_ecc_dump_oids(void)
6064
{
6065
    int x;
6066
6067
    if (mOidDumpDone) {
6068
        return;
6069
    }
6070
6071
    /* find matching OID sum (based on encoded value) */
6072
    for (x = 0; ecc_sets[x].size != 0; x++) {
6073
        int i;
6074
        byte* oid;
6075
        word32 oidSz, sum = 0;
6076
6077
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6078
6079
    #ifdef HAVE_OID_ENCODING
6080
        byte oidEnc[ECC_MAX_OID_LEN];
6081
6082
        oid = oidEnc;
6083
        oidSz = ECC_MAX_OID_LEN;
6084
6085
        printf("OID: ");
6086
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6087
            printf("%d.", ecc_sets[x].oid[i]);
6088
        }
6089
        printf("\n");
6090
6091
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6092
    #else
6093
        oid = (byte*)ecc_sets[x].oid;
6094
        oidSz = ecc_sets[x].oidSz;
6095
    #endif
6096
6097
        printf("OID Encoded: ");
6098
        for (i = 0; i < (int)oidSz; i++) {
6099
            printf("0x%02X,", oid[i]);
6100
        }
6101
        printf("\n");
6102
6103
        for (i = 0; i < (int)oidSz; i++) {
6104
            sum += oid[i];
6105
        }
6106
        printf("Sum: %u\n", sum);
6107
6108
        /* validate sum */
6109
        if (ecc_sets[x].oidSum != sum) {
6110
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6111
        }
6112
    }
6113
    mOidDumpDone = 1;
6114
}
6115
#endif /* ECC_DUMP_OID */
6116
6117
6118
WOLFSSL_ABI
6119
ecc_key* wc_ecc_key_new(void* heap)
6120
37.7k
{
6121
37.7k
    int devId = INVALID_DEVID;
6122
37.7k
    ecc_key* key;
6123
6124
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6125
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6126
    devId = WOLFSSL_CAAM_DEVID;
6127
#endif
6128
37.7k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6129
37.7k
    if (key) {
6130
33.6k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6131
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6132
0
            key = NULL;
6133
0
        }
6134
33.6k
    }
6135
6136
37.7k
    return key;
6137
37.7k
}
6138
6139
6140
WOLFSSL_ABI
6141
void wc_ecc_key_free(ecc_key* key)
6142
102k
{
6143
102k
    if (key) {
6144
33.6k
        void* heap = key->heap;
6145
6146
33.6k
        wc_ecc_free(key);
6147
33.6k
        ForceZero(key, sizeof(ecc_key));
6148
33.6k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6149
33.6k
        (void)heap;
6150
33.6k
    }
6151
102k
}
6152
6153
6154
/**
6155
 Make a new ECC key
6156
 rng          An active RNG state
6157
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6158
 key          [out] Destination of the newly created key
6159
 return       MP_OKAY if successful,
6160
 upon error all allocated memory will be freed
6161
 */
6162
WOLFSSL_ABI
6163
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6164
0
{
6165
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6166
0
}
6167
6168
/* Setup dynamic pointers if using normal math for proper freeing */
6169
WOLFSSL_ABI
6170
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6171
59.1k
{
6172
59.1k
    int ret      = 0;
6173
6174
59.1k
    if (key == NULL) {
6175
0
        return BAD_FUNC_ARG;
6176
0
    }
6177
6178
#ifdef ECC_DUMP_OID
6179
    wc_ecc_dump_oids();
6180
#endif
6181
6182
59.1k
    XMEMSET(key, 0, sizeof(ecc_key));
6183
59.1k
    key->state = ECC_STATE_NONE;
6184
6185
59.1k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6186
59.1k
    key->devId = devId;
6187
#else
6188
    (void)devId;
6189
#endif
6190
6191
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6192
    key->slot = ATECC_INVALID_SLOT;
6193
#else
6194
#if defined(WOLFSSL_KCAPI_ECC)
6195
    key->handle = NULL;
6196
#endif
6197
#ifdef ALT_ECC_SIZE
6198
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6199
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6200
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6201
    alt_fp_init(key->pubkey.x);
6202
    alt_fp_init(key->pubkey.y);
6203
    alt_fp_init(key->pubkey.z);
6204
    key->k = (mp_int*)key->ka;
6205
    alt_fp_init(key->k);
6206
#ifdef WOLFSSL_ECC_BLIND_K
6207
    key->kb = (mp_int*)key->kba;
6208
    key->ku = (mp_int*)key->kia;
6209
    alt_fp_init(key->kb);
6210
    alt_fp_init(key->ku);
6211
#endif
6212
#else
6213
59.1k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6214
59.1k
#ifndef WOLFSSL_ECC_BLIND_K
6215
59.1k
                                                                      NULL, NULL
6216
#else
6217
                                                                key->kb, key->ku
6218
#endif
6219
59.1k
                        );
6220
59.1k
    if (ret != MP_OKAY) {
6221
0
        return MEMORY_E;
6222
0
    }
6223
59.1k
#endif /* ALT_ECC_SIZE */
6224
#ifdef WOLFSSL_ECC_BLIND_K
6225
    mp_forcezero(key->kb);
6226
#endif
6227
59.1k
#endif /* WOLFSSL_ATECC508A */
6228
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6229
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6230
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6231
     defined(WOLFSSL_NO_MALLOC)
6232
    ret = mp_init(key->sign_k);
6233
    if (ret != MP_OKAY) {
6234
        return MEMORY_E;
6235
    }
6236
#endif
6237
6238
#ifdef WOLFSSL_HEAP_TEST
6239
    (void)heap;
6240
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6241
#else
6242
59.1k
    key->heap = heap;
6243
59.1k
#endif
6244
6245
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6246
    #ifdef WOLF_CRYPTO_CB
6247
    /* prefer crypto callback */
6248
    if (key->devId != INVALID_DEVID)
6249
    #endif
6250
    {
6251
        /* handle as async */
6252
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6253
                                                        key->heap, devId);
6254
    }
6255
    if (ret != 0)
6256
        return ret;
6257
#endif
6258
6259
#if defined(WOLFSSL_DSP)
6260
    key->handle = -1;
6261
#endif
6262
6263
#ifdef WOLFSSL_SE050
6264
    key->keyId = 0;
6265
    key->keyIdSet = 0;
6266
#endif
6267
6268
#ifdef WOLFSSL_CHECK_MEM_ZERO
6269
    mp_memzero_add("ECC k", key->k);
6270
#ifdef WOLFSSL_ECC_BLIND_K
6271
    mp_memzero_add("ECC kb", key->kb);
6272
    mp_memzero_add("ECC ku", key->ku);
6273
#endif
6274
#endif
6275
6276
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6277
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6278
6279
    if (wc_InitXsecure(&(key->xSec))) {
6280
        WOLFSSL_MSG("Can't initialize Xsecure");
6281
        return WC_HW_E;
6282
    }
6283
#endif
6284
6285
59.1k
    return ret;
6286
59.1k
}
6287
6288
WOLFSSL_ABI
6289
int wc_ecc_init(ecc_key* key)
6290
2.17k
{
6291
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6292
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6293
#else
6294
2.17k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6295
2.17k
#endif
6296
2.17k
}
6297
6298
#ifdef WOLF_PRIVATE_KEY_ID
6299
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6300
                   int devId)
6301
0
{
6302
0
    int ret = 0;
6303
#ifdef WOLFSSL_SE050
6304
    /* SE050 TLS users store a word32 at id, need to cast back */
6305
    word32* keyPtr = NULL;
6306
#endif
6307
6308
0
    if (key == NULL)
6309
0
        ret = BAD_FUNC_ARG;
6310
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6311
0
        ret = BUFFER_E;
6312
0
    if (ret == 0)
6313
0
        ret = wc_ecc_init_ex(key, heap, devId);
6314
0
    if (ret == 0 && id != NULL && len != 0) {
6315
0
        XMEMCPY(key->id, id, (size_t)len);
6316
0
        key->idLen = len;
6317
    #ifdef WOLFSSL_SE050
6318
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6319
        if (len == (int)sizeof(word32)) {
6320
            keyPtr = (word32*)key->id;
6321
            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
6322
        }
6323
    #endif
6324
0
    }
6325
6326
0
    return ret;
6327
0
}
6328
6329
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6330
0
{
6331
0
    int ret = 0;
6332
0
    int labelLen = 0;
6333
6334
0
    if (key == NULL || label == NULL)
6335
0
        ret = BAD_FUNC_ARG;
6336
0
    if (ret == 0) {
6337
0
        labelLen = (int)XSTRLEN(label);
6338
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6339
0
            ret = BUFFER_E;
6340
0
    }
6341
0
    if (ret == 0)
6342
0
        ret = wc_ecc_init_ex(key, heap, devId);
6343
0
    if (ret == 0) {
6344
0
        XMEMCPY(key->label, label, (size_t)labelLen);
6345
0
        key->labelLen = labelLen;
6346
0
    }
6347
6348
0
    return ret;
6349
0
}
6350
#endif /* WOLF_PRIVATE_KEY_ID */
6351
6352
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6353
607
{
6354
607
    if (key == NULL) {
6355
0
        return BAD_FUNC_ARG;
6356
0
    }
6357
607
    key->flags |= flags;
6358
607
    return 0;
6359
607
}
6360
6361
6362
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6363
{
6364
    int err = MP_OKAY;
6365
    int orderBits;
6366
    DECLARE_CURVE_SPECS(1);
6367
6368
    ALLOC_CURVE_SPECS(1, err);
6369
    if (err == MP_OKAY) {
6370
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6371
    }
6372
6373
    if (err != 0) {
6374
       FREE_CURVE_SPECS();
6375
       return err;
6376
    }
6377
    orderBits = mp_count_bits(curve->order);
6378
6379
    wc_ecc_curve_free(curve);
6380
    FREE_CURVE_SPECS();
6381
    return orderBits;
6382
}
6383
6384
#ifdef HAVE_ECC_SIGN
6385
6386
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6387
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6388
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6389
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6390
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6391
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6392
    ecc_key* key)
6393
{
6394
    int err;
6395
#ifdef PLUTON_CRYPTO_ECC
6396
    if (key->devId != INVALID_DEVID) /* use hardware */
6397
#endif
6398
    {
6399
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6400
        !defined(WOLFSSL_ATECC608A)
6401
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6402
        word32 raw_sig_size = *outlen;
6403
        word32 msgLenInBytes = inlen;
6404
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6405
    #endif
6406
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6407
#ifdef WOLFSSL_SMALL_STACK
6408
        byte* K = NULL;
6409
        byte* incopy = NULL;
6410
#else
6411
        byte K[MAX_ECC_BYTES] = {0};
6412
        byte incopy[MAX_ECC_BYTES] = {0};
6413
#endif
6414
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6415
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6416
        word32 Ksize;
6417
#endif
6418
#endif
6419
        word32 keysize = (word32)key->dp->size;
6420
    #ifdef PLUTON_CRYPTO_ECC
6421
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6422
    #endif
6423
6424
    #ifndef WOLFSSL_KCAPI_ECC
6425
        /* Check args */
6426
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6427
            return ECC_BAD_ARG_E;
6428
        }
6429
    #endif
6430
6431
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6432
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6433
        err = atmel_ecc_sign(key->slot, in, out);
6434
        if (err != 0) {
6435
           return err;
6436
        }
6437
    #elif defined(PLUTON_CRYPTO_ECC)
6438
        {
6439
            /* if the input is larger than curve order, we must truncate */
6440
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6441
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6442
            }
6443
6444
            /* perform ECC sign */
6445
            word32 raw_sig_size = *outlen;
6446
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6447
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6448
               return BAD_COND_E;
6449
            }
6450
        }
6451
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6452
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6453
        if (err != 0) {
6454
               return WC_HW_E;
6455
        }
6456
    #elif defined(WOLFSSL_CRYPTOCELL)
6457
        /* truncate if hash is longer than key size */
6458
        if (msgLenInBytes > keysize) {
6459
            msgLenInBytes = keysize;
6460
        }
6461
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6462
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6463
            (void)cc310_hashModeECC(keysize);
6464
            /* Ignoring returned value */
6465
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6466
6467
        }
6468
6469
        /* create signature from an input buffer using a private key*/
6470
        err = CRYS_ECDSA_Sign(&wc_rndState,
6471
                               wc_rndGenVectFunc,
6472
                               &sigCtxTemp,
6473
                               &key->ctx.privKey,
6474
                               hash_mode,
6475
                               (byte*)in,
6476
                               msgLenInBytes,
6477
                               out,
6478
                               (uint32_t*)&raw_sig_size);
6479
6480
        if (err != SA_SILIB_RET_OK){
6481
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6482
            return err;
6483
        }
6484
    #elif defined(WOLFSSL_KCAPI_ECC)
6485
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6486
        if (err != MP_OKAY) {
6487
            return err;
6488
        }
6489
        (void)rng;
6490
    #elif defined(WOLFSSL_SE050)
6491
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6492
        if (err != MP_OKAY) {
6493
            return err;
6494
        }
6495
        (void)rng;
6496
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6497
6498
#ifdef WOLFSSL_SMALL_STACK
6499
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6500
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6501
        if (K == NULL || incopy == NULL) {
6502
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6503
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6504
            return MEMORY_E;
6505
        }
6506
#else
6507
        if (inlen > sizeof(incopy))
6508
            return ECC_BAD_ARG_E;
6509
#endif
6510
6511
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6512
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6513
        err = deterministic_sign_helper(in, inlen, key);
6514
        if (err)
6515
            return err;
6516
        Ksize = mp_unsigned_bin_size(key->sign_k);
6517
        if (Ksize > keysize) {
6518
            err = BUFFER_E;
6519
            goto error_out;
6520
        }
6521
        err = mp_to_unsigned_bin(key->sign_k, K);
6522
        if (err)
6523
            goto error_out;
6524
        mp_reverse(K, Ksize);
6525
#else
6526
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6527
        if (err)
6528
            goto error_out;
6529
        /* Make sure that K is max. 521 bits */
6530
        if (keysize == 66)
6531
            K[65] &= 0x1;
6532
#endif
6533
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6534
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6535
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6536
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6537
6538
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6539
6540
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6541
                                           xil_curve_type[key->dp->id],
6542
                                           XIL_CAST_U64(incopy), keysize,
6543
                                           XIL_CAST_U64(key->privKey),
6544
                                           XIL_CAST_U64(K),
6545
                                           XIL_CAST_U64(out));
6546
        if (err) {
6547
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6548
            err = WC_HW_E;
6549
        }
6550
6551
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6552
        mp_reverse(&out[0], keysize);
6553
        mp_reverse(&out[keysize], keysize);
6554
6555
error_out:
6556
        ForceZero(K, MAX_ECC_BYTES);
6557
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6558
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6559
        if (err) {
6560
            ForceZero(out, keysize * 2);
6561
            return err;
6562
        }
6563
    #endif /* HW-specific #if-#elif chain */
6564
6565
    #ifndef WOLFSSL_SE050
6566
        /* Load R and S, SE050 does this in port layer */
6567
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6568
        if (err != MP_OKAY) {
6569
            return err;
6570
        }
6571
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6572
        if (err != MP_OKAY) {
6573
            return err;
6574
        }
6575
    #endif
6576
6577
        /* Check for zeros */
6578
        if (mp_iszero(r) || mp_iszero(s)) {
6579
            return MP_ZERO_E;
6580
        }
6581
    }
6582
#ifdef PLUTON_CRYPTO_ECC
6583
    else {
6584
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6585
    }
6586
#endif
6587
    (void)rng;
6588
6589
    return err;
6590
}
6591
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6592
6593
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6594
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6595
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6596
{
6597
    int err;
6598
    mp_int *r = NULL, *s = NULL;
6599
6600
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6601
                                                                rng == NULL) {
6602
        return ECC_BAD_ARG_E;
6603
    }
6604
6605
    err = wc_ecc_alloc_async(key);
6606
    if (err != 0) {
6607
        return err;
6608
    }
6609
    r = key->r;
6610
    s = key->s;
6611
6612
    switch (key->state) {
6613
        case ECC_STATE_NONE:
6614
        case ECC_STATE_SIGN_DO:
6615
            key->state = ECC_STATE_SIGN_DO;
6616
6617
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6618
                break;
6619
            }
6620
6621
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6622
            if (err < 0) {
6623
                break;
6624
            }
6625
6626
            FALL_THROUGH;
6627
6628
        case ECC_STATE_SIGN_ENCODE:
6629
            key->state = ECC_STATE_SIGN_ENCODE;
6630
6631
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6632
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6633
                    DECLARE_CURVE_SPECS(1);
6634
                    ALLOC_CURVE_SPECS(1, err);
6635
                    if (err != MP_OKAY) {
6636
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6637
                        break;
6638
                    }
6639
6640
                    /* get curve order */
6641
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6642
                #endif
6643
6644
                #ifdef HAVE_CAVIUM_V
6645
                    /* Nitrox requires r and s in sep buffer, so split it */
6646
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6647
                #endif
6648
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6649
                    /* only do this if not software, since it overwrites result */
6650
                    wc_bigint_to_mp(&r->raw, r);
6651
                    wc_bigint_to_mp(&s->raw, s);
6652
6653
                /* if using a curve with cofactor != 1 then reduce by mod order */
6654
                #ifdef HAVE_ECC_CDH
6655
                    /* if r is not less than order than reduce */
6656
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6657
                        err = mp_mod(r, curve->order, r);
6658
                    }
6659
                    wc_ecc_curve_free(curve);
6660
                    FREE_CURVE_SPECS();
6661
                #endif
6662
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6663
            }
6664
6665
            /* encoded with DSA header */
6666
            if (err == 0) {
6667
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6668
            }
6669
6670
            /* done with R/S */
6671
            mp_clear(r);
6672
            mp_clear(s);
6673
            break;
6674
6675
        default:
6676
            err = BAD_STATE_E;
6677
            break;
6678
    }
6679
6680
    /* if async pending then return and skip done cleanup below */
6681
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6682
        key->state++;
6683
        return err;
6684
    }
6685
6686
    /* cleanup */
6687
    wc_ecc_free_async(key);
6688
    key->state = ECC_STATE_NONE;
6689
6690
    return err;
6691
}
6692
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6693
6694
/**
6695
 Sign a message digest
6696
 in        The message digest to sign
6697
 inlen     The length of the digest
6698
 out       [out] The destination for the signature
6699
 outlen    [in/out] The max size and resulting size of the signature
6700
 key       A private ECC key
6701
 return    MP_OKAY if successful
6702
 */
6703
WOLFSSL_ABI
6704
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6705
                     WC_RNG* rng, ecc_key* key)
6706
3.80k
{
6707
3.80k
    int err;
6708
3.80k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6709
3.80k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6710
3.80k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6711
3.80k
#endif
6712
#ifdef NO_ASN
6713
    word32 keySz;
6714
#endif
6715
6716
3.80k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6717
179
        return ECC_BAD_ARG_E;
6718
179
    }
6719
3.63k
    if (inlen > WC_MAX_DIGEST_SIZE) {
6720
128
        return BAD_LENGTH_E;
6721
128
    }
6722
6723
3.50k
#ifdef WOLF_CRYPTO_CB
6724
3.50k
    #ifndef WOLF_CRYPTO_CB_FIND
6725
3.50k
    if (key->devId != INVALID_DEVID)
6726
0
    #endif
6727
0
    {
6728
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
6729
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6730
0
            return err;
6731
        /* fall-through when unavailable */
6732
0
    }
6733
3.50k
#endif
6734
6735
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6736
    (void)rng;
6737
    (void)inlen;
6738
    (void)s;
6739
    (void)r;
6740
    (void)err;
6741
    return NO_VALID_DEVID;
6742
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6743
3.50k
    if (rng == NULL) {
6744
0
        WOLFSSL_MSG("ECC sign RNG missing");
6745
0
        return ECC_BAD_ARG_E;
6746
0
    }
6747
6748
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6749
    /* handle async cases */
6750
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
6751
#else
6752
6753
3.50k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6754
3.50k
    #ifdef MP_INT_SIZE_CHECK_NULL
6755
3.50k
    if (r == NULL)
6756
5
        return MEMORY_E;
6757
3.49k
    #endif
6758
3.49k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6759
3.49k
    #ifdef MP_INT_SIZE_CHECK_NULL
6760
3.49k
    if (s == NULL) {
6761
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6762
5
        return MEMORY_E;
6763
5
    }
6764
3.49k
    #endif
6765
6766
3.49k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6767
3.49k
    if (err != 0) {
6768
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6769
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6770
0
        return err;
6771
0
    }
6772
3.49k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6773
3.49k
    if (err != 0) {
6774
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6775
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6776
0
        return err;
6777
0
    }
6778
6779
/* hardware crypto */
6780
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6781
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6782
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6783
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6784
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
6785
#else
6786
3.49k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6787
3.49k
#endif
6788
3.49k
    if (err < 0) {
6789
121
        mp_clear(r);
6790
121
        mp_clear(s);
6791
121
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6792
121
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6793
121
        return err;
6794
121
    }
6795
6796
3.37k
#ifndef NO_ASN
6797
    /* encoded with DSA header */
6798
3.37k
    err = StoreECC_DSA_Sig(out, outlen, r, s);
6799
#else
6800
    /* No support for DSA ASN.1 header.
6801
     * Signature will be r+s directly. */
6802
    keySz = 0;
6803
    if (key->dp != NULL) {
6804
        keySz = (word32)key->dp->size;
6805
    }
6806
    if (keySz <= 0) {
6807
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
6808
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
6809
    }
6810
    *outlen = keySz * 2;
6811
6812
    /* Export signature into r,s */
6813
    mp_to_unsigned_bin_len(r, out, keySz);
6814
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
6815
#endif /* !NO_ASN */
6816
6817
    /* cleanup */
6818
3.37k
    mp_clear(r);
6819
3.37k
    mp_clear(s);
6820
6821
3.37k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6822
3.37k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6823
3.37k
#endif /* WOLFSSL_ASYNC_CRYPT */
6824
3.37k
    return err;
6825
3.49k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6826
3.49k
}
6827
6828
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6829
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6830
/* returns MP_OKAY on success */
6831
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
6832
{
6833
    int err = MP_OKAY;
6834
    DECLARE_CURVE_SPECS(1);
6835
    ALLOC_CURVE_SPECS(1, err);
6836
6837
    /* get curve order */
6838
    if (err == MP_OKAY) {
6839
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6840
    }
6841
6842
    if (err == MP_OKAY) {
6843
    #ifndef WOLFSSL_NO_MALLOC
6844
        /* if key->sign_k is NULL then create a buffer for the mp_int
6845
         * if not NULL then assume the user correctly set deterministic flag and
6846
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
6847
        if (key->sign_k == NULL) {
6848
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6849
                                                            DYNAMIC_TYPE_ECC);
6850
            if (key->sign_k != NULL) {
6851
                err = mp_init(key->sign_k);
6852
                if (err != MP_OKAY) {
6853
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6854
                    key->sign_k = NULL;
6855
                }
6856
            }
6857
        }
6858
        if (key->sign_k != NULL) {
6859
            if (wc_ecc_gen_deterministic_k(in, inlen,
6860
                        key->hashType, ecc_get_k(key), key->sign_k,
6861
                        curve->order, key->heap) != 0) {
6862
                mp_free(key->sign_k);
6863
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6864
                key->sign_k = NULL;
6865
                err = ECC_PRIV_KEY_E;
6866
            }
6867
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6868
            else {
6869
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
6870
            }
6871
        #endif
6872
        }
6873
        else {
6874
            err = MEMORY_E;
6875
        }
6876
    #else
6877
        key->sign_k_set = 0;
6878
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
6879
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
6880
            err = ECC_PRIV_KEY_E;
6881
        }
6882
        else {
6883
            key->sign_k_set = 1;
6884
        }
6885
    #endif
6886
    }
6887
6888
    wc_ecc_curve_free(curve);
6889
    FREE_CURVE_SPECS();
6890
    return err;
6891
}
6892
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
6893
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
6894
6895
#if defined(WOLFSSL_STM32_PKA)
6896
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6897
                     ecc_key* key, mp_int *r, mp_int *s)
6898
{
6899
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6900
}
6901
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6902
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
6903
#ifndef WOLFSSL_SP_MATH
6904
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
6905
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
6906
                            mp_int* s)
6907
1.98k
{
6908
1.98k
    int err = MP_OKAY;
6909
1.98k
    int loop_check = 0;
6910
1.98k
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6911
6912
1.98k
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6913
1.98k
#ifdef MP_INT_SIZE_CHECK_NULL
6914
1.98k
    if (b == NULL)
6915
2
        err = MEMORY_E;
6916
1.98k
#endif
6917
6918
1.98k
    if (err == MP_OKAY) {
6919
1.98k
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6920
1.98k
    }
6921
6922
1.98k
#ifdef WOLFSSL_CUSTOM_CURVES
6923
    /* if custom curve, apply params to pubkey */
6924
1.98k
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6925
0
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6926
0
    }
6927
1.98k
#endif
6928
6929
1.98k
    if (err == MP_OKAY) {
6930
        /* Generate blinding value - non-zero value. */
6931
2.20k
        do {
6932
2.20k
            if (++loop_check > 64) {
6933
2
                 err = RNG_FAILURE_E;
6934
2
                 break;
6935
2
            }
6936
6937
2.20k
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6938
2.20k
        }
6939
2.20k
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6940
1.98k
        loop_check = 0;
6941
1.98k
    }
6942
#ifdef WOLFSSL_CHECK_MEM_ZERO
6943
    if (err == MP_OKAY) {
6944
        mp_memzero_add("ecc_sign_hash_sw b", b);
6945
    }
6946
#endif
6947
6948
1.99k
    for (; err == MP_OKAY;) {
6949
1.99k
        if (++loop_check > 64) {
6950
16
             err = RNG_FAILURE_E;
6951
16
             break;
6952
16
        }
6953
1.97k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6954
1.97k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6955
1.97k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6956
1.97k
#ifndef WOLFSSL_NO_MALLOC
6957
1.97k
        if (key->sign_k != NULL)
6958
#else
6959
        if (key->sign_k_set)
6960
#endif
6961
596
        {
6962
596
            if (loop_check > 1) {
6963
0
               err = RNG_FAILURE_E;
6964
0
               break;
6965
0
            }
6966
6967
            /* use provided sign_k */
6968
596
            err = mp_copy(key->sign_k, pubkey->k);
6969
596
            if (err != MP_OKAY) break;
6970
6971
            /* free sign_k, so only used once */
6972
596
            mp_forcezero(key->sign_k);
6973
596
#ifndef WOLFSSL_NO_MALLOC
6974
596
            mp_free(key->sign_k);
6975
596
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6976
596
            key->sign_k = NULL;
6977
#else
6978
            key->sign_k_set = 0;
6979
#endif
6980
596
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6981
596
            loop_check = 64;
6982
596
    #endif
6983
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6984
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6985
            if (key->deterministic == 1) {
6986
                /* sign_k generated earlier in function for SP calls.
6987
                 * Only go through the loop once and fail if error */
6988
                loop_check = 64;
6989
            }
6990
    #endif
6991
6992
            /* compute public key based on provided "k" */
6993
596
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6994
596
        }
6995
1.38k
        else
6996
1.38k
#endif
6997
1.38k
        {
6998
1.38k
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6999
1.38k
                    WC_ECC_FLAG_NONE);
7000
1.38k
        }
7001
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7002
        if (err == MP_OKAY) {
7003
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7004
        }
7005
    #endif
7006
    #ifdef WOLFSSL_ASYNC_CRYPT
7007
        /* for async do blocking wait here */
7008
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7009
    #endif
7010
1.97k
        if (err != MP_OKAY) break;
7011
7012
        /* find r = x1 mod n */
7013
1.96k
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7014
1.96k
        if (err != MP_OKAY) break;
7015
7016
1.96k
        if (mp_iszero(r) == MP_NO) {
7017
1.96k
            mp_int* kp = ecc_get_k(pubkey);
7018
1.96k
            mp_int* ep = kp;
7019
1.96k
            mp_int* x  = ecc_get_k(key);
7020
7021
            /* Blind after getting. */
7022
1.96k
            ecc_blind_k(key, b);
7023
7024
            /* find s = (e + xr)/k
7025
                      = b.(e/k.b + x.r/k.b) */
7026
7027
            /* k' = k.b */
7028
1.96k
            err = mp_mulmod(kp, b, curve->order, kp);
7029
1.96k
            if (err != MP_OKAY) break;
7030
7031
            /* k' = 1/k.b
7032
                  = 1/k' */
7033
1.96k
            err = mp_invmod(kp, curve->order, kp);
7034
1.96k
            if (err != MP_OKAY) break;
7035
7036
            /* s = x.r */
7037
1.95k
            err = mp_mulmod(x, r, curve->order, s);
7038
1.95k
            if (err != MP_OKAY) break;
7039
7040
            /* s = x.r/k.b
7041
                 = k'.s */
7042
1.95k
            err = mp_mulmod(kp, s, curve->order, s);
7043
1.95k
            if (err != MP_OKAY) break;
7044
7045
            /* e' = e/k.b
7046
                  = e.k' */
7047
1.95k
            err = mp_mulmod(kp, e, curve->order, ep);
7048
1.95k
            if (err != MP_OKAY) break;
7049
7050
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7051
                 = e' + s */
7052
1.95k
            err = mp_addmod_ct(ep, s, curve->order, s);
7053
1.95k
            if (err != MP_OKAY) break;
7054
7055
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7056
                 = b.s */
7057
1.95k
            err = mp_mulmod(s, b, curve->order, s);
7058
1.95k
            if (err != MP_OKAY) break;
7059
7060
1.95k
            if (mp_iszero(s) == MP_NO) {
7061
                /* sign successful */
7062
1.93k
                break;
7063
1.93k
            }
7064
1.95k
         }
7065
16
     #ifndef ALT_ECC_SIZE
7066
16
         mp_clear(pubkey->pubkey.x);
7067
16
         mp_clear(pubkey->pubkey.y);
7068
16
         mp_clear(pubkey->pubkey.z);
7069
16
     #endif
7070
16
         mp_forcezero(pubkey->k);
7071
16
    }
7072
1.98k
    mp_forcezero(b);
7073
1.98k
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7074
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7075
    mp_memzero_check(b);
7076
#endif
7077
7078
1.98k
    return err;
7079
1.98k
}
7080
#endif
7081
7082
#ifdef WOLFSSL_HAVE_SP_ECC
7083
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7084
    ecc_key* key, mp_int *r, mp_int *s)
7085
{
7086
    if (key->idx != ECC_CUSTOM_IDX) {
7087
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7088
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7089
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7090
        mp_int* sign_k = key->sign_k;
7091
    #else
7092
        mp_int* sign_k = NULL;
7093
    #endif
7094
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7095
        /* perform blocking call to non-blocking function */
7096
        ecc_nb_ctx_t nb_ctx;
7097
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7098
    #endif
7099
    #ifndef WOLFSSL_SP_NO_256
7100
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7101
        #ifdef WC_ECC_NONBLOCK
7102
            #ifdef WC_ECC_NONBLOCK_ONLY
7103
            int err;
7104
            #endif
7105
            if (key->nb_ctx) {
7106
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7107
                    ecc_get_k(key), r, s, sign_k, key->heap);
7108
            }
7109
            #ifdef WC_ECC_NONBLOCK_ONLY
7110
            do { /* perform blocking call to non-blocking function */
7111
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7112
                    ecc_get_k(key), r, s, sign_k, key->heap);
7113
            } while (err == FP_WOULDBLOCK);
7114
            return err;
7115
            #endif
7116
        #endif /* WC_ECC_NONBLOCK */
7117
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7118
            {
7119
                int ret;
7120
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7121
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7122
                                      sign_k, key->heap);
7123
                RESTORE_VECTOR_REGISTERS();
7124
                return ret;
7125
            }
7126
        #endif
7127
        }
7128
    #endif
7129
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7130
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7131
            int ret;
7132
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
7133
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7134
                                      sign_k, key->heap);
7135
            RESTORE_VECTOR_REGISTERS();
7136
            return ret;
7137
        }
7138
    #endif
7139
    #ifdef WOLFSSL_SP_384
7140
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7141
        #ifdef WC_ECC_NONBLOCK
7142
            #ifdef WC_ECC_NONBLOCK_ONLY
7143
            int err;
7144
            #endif
7145
            if (key->nb_ctx) {
7146
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7147
                    ecc_get_k(key), r, s, sign_k, key->heap);
7148
            }
7149
            #ifdef WC_ECC_NONBLOCK_ONLY
7150
            do { /* perform blocking call to non-blocking function */
7151
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7152
                    ecc_get_k(key), r, s, sign_k, key->heap);
7153
            } while (err == FP_WOULDBLOCK);
7154
            return err;
7155
            #endif
7156
        #endif /* WC_ECC_NONBLOCK */
7157
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7158
            {
7159
                int ret;
7160
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7161
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7162
                                      sign_k, key->heap);
7163
                RESTORE_VECTOR_REGISTERS();
7164
                return ret;
7165
            }
7166
        #endif
7167
        }
7168
    #endif
7169
    #ifdef WOLFSSL_SP_521
7170
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7171
        #ifdef WC_ECC_NONBLOCK
7172
            #ifdef WC_ECC_NONBLOCK_ONLY
7173
            int err;
7174
            #endif
7175
            if (key->nb_ctx) {
7176
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7177
                    ecc_get_k(key), r, s, sign_k, key->heap);
7178
            }
7179
            #ifdef WC_ECC_NONBLOCK_ONLY
7180
            do { /* perform blocking call to non-blocking function */
7181
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7182
                    ecc_get_k(key), r, s, sign_k, key->heap);
7183
            } while (err == FP_WOULDBLOCK);
7184
            return err;
7185
            #endif
7186
        #endif /* WC_ECC_NONBLOCK */
7187
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7188
            {
7189
                int ret;
7190
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7191
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7192
                                      sign_k, key->heap);
7193
                RESTORE_VECTOR_REGISTERS();
7194
                return ret;
7195
            }
7196
        #endif
7197
        }
7198
    #endif
7199
        (void)sign_k;
7200
    }
7201
7202
    /* SP doesn't support curve. */
7203
    return WC_KEY_SIZE_E;
7204
}
7205
#endif
7206
7207
/**
7208
  Sign a message digest
7209
  in        The message digest to sign
7210
  inlen     The length of the digest
7211
  key       A private ECC key
7212
  r         [out] The destination for r component of the signature
7213
  s         [out] The destination for s component of the signature
7214
  return    MP_OKAY if successful
7215
*/
7216
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7217
                     ecc_key* key, mp_int *r, mp_int *s)
7218
1.98k
{
7219
1.98k
   int    err = 0;
7220
1.98k
#if !defined(WOLFSSL_SP_MATH)
7221
1.98k
   mp_int* e;
7222
1.98k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7223
1.98k
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7224
1.98k
#endif
7225
7226
1.98k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7227
1.98k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7228
1.98k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7229
1.98k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7230
1.98k
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7231
1.98k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7232
#else
7233
   DECLARE_CURVE_SPECS(1);
7234
#endif
7235
1.98k
#endif /* !WOLFSSL_SP_MATH */
7236
7237
1.98k
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7238
0
       return ECC_BAD_ARG_E;
7239
0
   }
7240
7241
   /* is this a private key? */
7242
1.98k
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7243
0
      return ECC_BAD_ARG_E;
7244
0
   }
7245
7246
   /* is the IDX valid ?  */
7247
1.98k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7248
0
      return ECC_BAD_ARG_E;
7249
0
   }
7250
7251
#if defined(WOLFSSL_SP_MATH)
7252
    if (key->idx == ECC_CUSTOM_IDX || (1
7253
    #ifndef WOLFSSL_SP_NO_256
7254
         && ecc_sets[key->idx].id != ECC_SECP256R1
7255
    #endif
7256
    #ifdef WOLFSSL_SP_SM2
7257
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7258
    #endif
7259
    #ifdef WOLFSSL_SP_384
7260
         && ecc_sets[key->idx].id != ECC_SECP384R1
7261
    #endif
7262
    #ifdef WOLFSSL_SP_521
7263
         && ecc_sets[key->idx].id != ECC_SECP521R1
7264
    #endif
7265
        )) {
7266
        return WC_KEY_SIZE_E;
7267
    }
7268
#endif
7269
7270
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7271
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7272
    /* generate deterministic 'k' value to be used either with SP or normal */
7273
    if (key->deterministic == 1) {
7274
        if (deterministic_sign_helper(in, inlen, key)) {
7275
            WOLFSSL_MSG("Error generating deterministic k to sign");
7276
            return ECC_PRIV_KEY_E;
7277
        }
7278
    }
7279
#endif
7280
7281
7282
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7283
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7284
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7285
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7286
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7287
            sw->eccSign.in = in;
7288
            sw->eccSign.inSz = inlen;
7289
            sw->eccSign.rng = rng;
7290
            sw->eccSign.key = key;
7291
            sw->eccSign.r = r;
7292
            sw->eccSign.s = s;
7293
            return WC_PENDING_E;
7294
        }
7295
    }
7296
#endif
7297
7298
#if defined(WOLFSSL_HAVE_SP_ECC)
7299
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7300
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7301
       return err;
7302
   }
7303
#else
7304
1.98k
   (void)inlen;
7305
1.98k
#endif
7306
7307
1.98k
#if !defined(WOLFSSL_SP_MATH)
7308
7309
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7310
   err = wc_ecc_alloc_mpint(key, &key->e);
7311
   if (err != 0) {
7312
      return err;
7313
   }
7314
   e = key->e;
7315
#else
7316
1.98k
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7317
1.98k
#ifdef MP_INT_SIZE_CHECK_NULL
7318
1.98k
   if (e_lcl == NULL) {
7319
2
      return MEMORY_E;
7320
2
   }
7321
1.98k
#endif
7322
1.98k
   e = e_lcl;
7323
1.98k
#endif
7324
7325
   /* get the hash and load it as a bignum into 'e' */
7326
   /* init the bignums */
7327
1.98k
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7328
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7329
0
      return err;
7330
0
   }
7331
7332
   /* load curve info */
7333
1.98k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7334
1.98k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7335
1.98k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7336
1.98k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7337
1.98k
    if (err == MP_OKAY)
7338
1.98k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7339
#else
7340
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7341
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7342
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7343
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7344
        if (err == MP_OKAY)
7345
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7346
    }
7347
    else
7348
    #endif
7349
    {
7350
        ALLOC_CURVE_SPECS(1, err);
7351
        if (err == MP_OKAY)
7352
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7353
    }
7354
#endif
7355
7356
   /* load digest into e */
7357
1.98k
   if (err == MP_OKAY) {
7358
       /* we may need to truncate if hash is longer than key size */
7359
1.98k
       word32 orderBits = (word32)mp_count_bits(curve->order);
7360
7361
       /* truncate down to byte size, may be all that's needed */
7362
1.98k
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7363
205
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7364
1.98k
       err = mp_read_unsigned_bin(e, in, inlen);
7365
7366
       /* may still need bit truncation too */
7367
1.98k
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7368
158
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7369
1.98k
   }
7370
7371
   /* make up a key and export the public copy */
7372
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7373
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7374
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7375
   #ifdef HAVE_CAVIUM_V
7376
       if (NitroxEccIsCurveSupported(key))
7377
   #endif
7378
       {
7379
           word32 keySz = key->dp->size;
7380
           mp_int* k;
7381
       #ifdef HAVE_CAVIUM_V
7382
           err = wc_ecc_alloc_mpint(key, &key->signK);
7383
           if (err != 0)
7384
              return err;
7385
           k = key->signK;
7386
       #else
7387
           mp_int k_lcl;
7388
           k = &k_lcl;
7389
       #endif
7390
7391
           err = mp_init(k);
7392
7393
            /* make sure r and s are allocated */
7394
       #ifdef HAVE_CAVIUM_V
7395
           /* Nitrox V needs single buffer for R and S */
7396
           if (err == MP_OKAY)
7397
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7398
           /* Nitrox V only needs Prime and Order */
7399
           if (err == MP_OKAY)
7400
               err = wc_ecc_curve_load(key->dp, &curve,
7401
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7402
       #else
7403
           if (err == MP_OKAY)
7404
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7405
           if (err == MP_OKAY)
7406
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7407
       #endif
7408
           if (err == MP_OKAY)
7409
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7410
7411
           /* load e and k */
7412
           if (err == MP_OKAY)
7413
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7414
           if (err == MP_OKAY)
7415
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7416
                  keySz);
7417
           if (err == MP_OKAY)
7418
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7419
           if (err == MP_OKAY)
7420
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7421
7422
       #ifdef HAVE_CAVIUM_V
7423
           if (err == MP_OKAY)
7424
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7425
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7426
                  &curve->order->raw);
7427
       #else
7428
           if (err == MP_OKAY)
7429
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7430
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7431
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7432
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7433
       #endif
7434
7435
       #ifndef HAVE_CAVIUM_V
7436
           mp_clear(e);
7437
           mp_clear(k);
7438
       #endif
7439
           wc_ecc_curve_free(curve);
7440
           FREE_CURVE_SPECS();
7441
7442
           return err;
7443
       }
7444
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7445
   }
7446
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7447
7448
1.98k
   if (err == MP_OKAY) {
7449
1.98k
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7450
7451
1.98k
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7452
1.98k
           err=MEMORY_E);
7453
1.98k
       if (WC_VAR_OK(pubkey))
7454
1.98k
       {
7455
       /* don't use async for key, since we don't support async return here */
7456
1.98k
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7457
1.98k
           if (err == MP_OKAY) {
7458
1.98k
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7459
1.98k
              wc_ecc_free(pubkey);
7460
1.98k
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7461
1.98k
           }
7462
1.98k
       }
7463
1.98k
   }
7464
7465
1.98k
   mp_clear(e);
7466
1.98k
   wc_ecc_curve_free(curve);
7467
1.98k
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7468
1.98k
   FREE_CURVE_SPECS();
7469
1.98k
#endif /* !WOLFSSL_SP_MATH */
7470
7471
1.98k
   return err;
7472
1.98k
}
7473
7474
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7475
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7476
/* helper function to do HMAC operations
7477
 * returns 0 on success and updates "out" buffer
7478
 */
7479
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7480
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7481
        byte* out, enum wc_HashType hashType, void* heap)
7482
{
7483
    Hmac hmac;
7484
    int  ret, init;
7485
7486
    ret = init = wc_HmacInit(&hmac, heap, INVALID_DEVID);
7487
    if (ret == 0)
7488
        ret = wc_HmacSetKey(&hmac, (int)hashType, K, KSz);
7489
7490
    if (ret == 0)
7491
        ret = wc_HmacUpdate(&hmac, V, VSz);
7492
7493
    if (ret == 0 && oct != NULL)
7494
        ret = wc_HmacUpdate(&hmac, oct, 1);
7495
7496
    if (ret == 0)
7497
        ret = wc_HmacUpdate(&hmac, x, xSz);
7498
7499
    if (ret == 0)
7500
        ret = wc_HmacUpdate(&hmac, h1, h1Sz);
7501
7502
    if (ret == 0)
7503
        ret = wc_HmacFinal(&hmac, out);
7504
7505
    if (init == 0)
7506
        wc_HmacFree(&hmac);
7507
7508
    return ret;
7509
}
7510
7511
7512
/* Generates a deterministic key based of the message using RFC6979
7513
 * @param  [in]   hash     Hash value to sign
7514
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7515
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7516
 *                WC_HASH_TYPE_SHA256
7517
 * @param  [in]   priv     Current ECC private key set
7518
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7519
 * @param  [in]   order    ECC order parameter to use with generation
7520
 * @return  0 on success.
7521
 */
7522
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7523
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7524
        void* heap)
7525
{
7526
    int ret = 0;
7527
#ifndef WOLFSSL_SMALL_STACK
7528
    byte h1[MAX_ECC_BYTES];
7529
    byte V[WC_MAX_DIGEST_SIZE];
7530
    byte K[WC_MAX_DIGEST_SIZE];
7531
    byte x[MAX_ECC_BYTES];
7532
    mp_int z1[1];
7533
#else
7534
    byte *h1 = NULL;
7535
    byte *V  = NULL;
7536
    byte *K  = NULL;
7537
    byte *x  = NULL;
7538
    mp_int *z1 = NULL;
7539
#endif
7540
    word32 xSz, VSz, KSz, h1len, qLen;
7541
    byte intOct;
7542
    int qbits = 0;
7543
7544
    if (hash == NULL || k == NULL || order == NULL) {
7545
        return BAD_FUNC_ARG;
7546
    }
7547
7548
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7549
        WOLFSSL_MSG("hash size was too large!");
7550
        return BAD_FUNC_ARG;
7551
    }
7552
7553
    /* if none is provided then detect has type based on hash size */
7554
    if (hashType == WC_HASH_TYPE_NONE) {
7555
        if (hashSz == 64) {
7556
            hashType = WC_HASH_TYPE_SHA512;
7557
        }
7558
        else if (hashSz == 48) {
7559
            hashType = WC_HASH_TYPE_SHA384;
7560
        }
7561
        else if (hashSz == 32) {
7562
            hashType = WC_HASH_TYPE_SHA256;
7563
        }
7564
        else {
7565
            return BAD_FUNC_ARG;
7566
        }
7567
    }
7568
7569
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
7570
        WOLFSSL_MSG("private key larger than max expected!");
7571
        return BAD_FUNC_ARG;
7572
    }
7573
7574
#ifdef WOLFSSL_SMALL_STACK
7575
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
7576
    if (h1 == NULL) {
7577
        ret = MEMORY_E;
7578
    }
7579
7580
    if (ret == 0) {
7581
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7582
        if (V == NULL)
7583
            ret = MEMORY_E;
7584
    }
7585
7586
    if (ret == 0) {
7587
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7588
        if (K == NULL)
7589
            ret = MEMORY_E;
7590
    }
7591
7592
    if (ret == 0) {
7593
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7594
        if (x == NULL)
7595
            ret = MEMORY_E;
7596
    }
7597
7598
    if (ret == 0) {
7599
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
7600
        if (z1 == NULL)
7601
            ret = MEMORY_E;
7602
    }
7603
7604
    /* bail out if any error has been hit at this point */
7605
    if (ret != 0) {
7606
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7607
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7608
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7609
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7610
        return ret;
7611
    }
7612
#endif
7613
7614
    VSz = KSz = hashSz;
7615
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
7616
7617
    /* 3.2 b. Set V = 0x01 0x01 ... */
7618
    XMEMSET(V, 0x01, VSz);
7619
7620
    /* 3.2 c. Set K = 0x00 0x00 ... */
7621
    XMEMSET(K, 0x00, KSz);
7622
7623
    if (ret == 0) {
7624
        ret = mp_init(z1); /* always init z1 and free z1 */
7625
    }
7626
    if (ret == 0) {
7627
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
7628
    }
7629
    if (ret == 0) {
7630
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7631
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
7632
    #endif
7633
        qbits = mp_count_bits(order);
7634
        if (qbits < 0)
7635
            ret = MP_VAL;
7636
    }
7637
7638
    if (ret == 0) {
7639
         /* hash truncate if too long */
7640
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
7641
            /* calculate truncated hash size using bits rounded up byte */
7642
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
7643
        }
7644
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
7645
    }
7646
7647
    /* bits2octets on h1 */
7648
    if (ret == 0) {
7649
        XMEMSET(h1, 0, MAX_ECC_BYTES);
7650
7651
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7652
        /* mod reduce by order using conditional subtract
7653
         * RFC6979 lists a variant that uses the hash directly instead of
7654
         * doing bits2octets(H(m)), when variant macro is used avoid this
7655
         * bits2octets operation */
7656
        if (mp_cmp(z1, order) == MP_GT) {
7657
            int z1Sz;
7658
7659
            mp_sub(z1, order, z1);
7660
            z1Sz = mp_unsigned_bin_size(z1);
7661
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
7662
                ret = BUFFER_E;
7663
            }
7664
            else {
7665
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7666
            }
7667
        }
7668
        else
7669
    #endif
7670
        {
7671
            /* use original hash and keep leading 0's */
7672
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7673
        }
7674
    }
7675
    mp_free(z1);
7676
7677
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
7678
    if (ret == 0) {
7679
        intOct = 0x00;
7680
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
7681
                hashType, heap);
7682
    }
7683
7684
    /* 3.2 step e. V = HMAC_K(V) */
7685
    if (ret == 0) {
7686
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7687
                heap);
7688
    }
7689
7690
7691
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
7692
    if (ret == 0) {
7693
        intOct = 0x01;
7694
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
7695
                heap);
7696
    }
7697
7698
    /* 3.2 step g. V = HMAC_K(V) */
7699
    if (ret == 0) {
7700
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7701
                heap);
7702
    }
7703
7704
    /* 3.2 step h. loop through the next steps until a valid value is found */
7705
    if (ret == 0 ) {
7706
        int err;
7707
7708
        intOct = 0x00;
7709
        do {
7710
            xSz = 0; /* used as tLen */
7711
            err = 0; /* start as good until generated k is tested */
7712
7713
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
7714
            while (xSz < qLen) {
7715
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7716
                        hashType, heap);
7717
                if (ret == 0) {
7718
                    int sz;
7719
7720
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
7721
                    XMEMCPY(x + xSz, V, (size_t)sz);
7722
                    xSz += (word32)sz;
7723
                }
7724
                else {
7725
                    break; /* error case */
7726
                }
7727
            }
7728
7729
            if (ret == 0) {
7730
                mp_clear(k); /* 3.2 step h.1 clear T */
7731
                ret = mp_read_unsigned_bin(k, x, xSz);
7732
            }
7733
7734
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
7735
                /* handle odd case where shift of 'k' is needed with RFC 6979
7736
                 *  k = bits2int(T) in section 3.2 h.3 */
7737
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
7738
            }
7739
7740
            /* 3.2 step h.3 the key should be smaller than the order of base
7741
             * point */
7742
            if (ret == 0) {
7743
                if (mp_cmp(k, order) != MP_LT) {
7744
                    err = MP_VAL;
7745
                } else if (mp_iszero(k) == MP_YES) {
7746
                    /* no 0 key's */
7747
                    err = MP_ZERO_E;
7748
                }
7749
            }
7750
7751
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
7752
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
7753
            if (ret == 0 && err != 0) {
7754
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
7755
                    hashType, heap);
7756
                if (ret == 0) {
7757
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7758
                    hashType, heap);
7759
                }
7760
            }
7761
        } while (ret == 0 && err != 0);
7762
    }
7763
7764
    ForceZero(x, MAX_ECC_BYTES);
7765
#ifdef WOLFSSL_SMALL_STACK
7766
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
7767
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7768
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7769
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7770
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7771
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
7772
    wc_MemZero_Check(x, MAX_ECC_BYTES);
7773
#endif
7774
7775
    return ret;
7776
}
7777
7778
7779
/* Sets the deterministic flag for 'k' generation with sign.
7780
 * returns 0 on success
7781
 */
7782
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
7783
                                enum wc_HashType hashType)
7784
{
7785
    if (key == NULL) {
7786
        return BAD_FUNC_ARG;
7787
    }
7788
7789
    key->deterministic = flag ? 1 : 0;
7790
    key->hashType = hashType;
7791
    return 0;
7792
}
7793
7794
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
7795
{
7796
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
7797
}
7798
7799
#endif /* end sign_ex and deterministic sign */
7800
7801
7802
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
7803
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
7804
754
{
7805
754
    int ret = MP_OKAY;
7806
754
    DECLARE_CURVE_SPECS(1);
7807
7808
754
    if (k == NULL || klen == 0 || key == NULL) {
7809
0
        return BAD_FUNC_ARG;
7810
0
    }
7811
7812
754
    ALLOC_CURVE_SPECS(1, ret);
7813
754
    if (ret == MP_OKAY) {
7814
743
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7815
743
    }
7816
7817
754
    if (ret != 0) {
7818
11
        FREE_CURVE_SPECS();
7819
11
        return ret;
7820
11
    }
7821
7822
743
#ifndef WOLFSSL_NO_MALLOC
7823
743
    if (key->sign_k == NULL) {
7824
743
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7825
743
                                                            DYNAMIC_TYPE_ECC);
7826
743
        if (key->sign_k) {
7827
732
            ret = mp_init(key->sign_k);
7828
732
        }
7829
11
        else {
7830
11
            ret = MEMORY_E;
7831
11
        }
7832
743
    }
7833
743
#endif
7834
7835
743
    if (ret == 0) {
7836
732
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7837
732
    }
7838
743
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7839
51
        ret = MP_VAL;
7840
51
    }
7841
#ifdef WOLFSSL_NO_MALLOC
7842
    if (ret == 0) {
7843
        key->sign_k_set = 1;
7844
    }
7845
#endif
7846
7847
743
    wc_ecc_curve_free(curve);
7848
743
    FREE_CURVE_SPECS();
7849
743
    return ret;
7850
754
}
7851
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
7852
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
7853
7854
#endif /* !HAVE_ECC_SIGN */
7855
7856
#ifdef WOLFSSL_CUSTOM_CURVES
7857
void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
7858
606
{
7859
606
#ifndef WOLFSSL_ECC_CURVE_STATIC
7860
606
    if (curve->prime != NULL)
7861
203
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7862
606
    if (curve->Af != NULL)
7863
181
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7864
606
    if (curve->Bf != NULL)
7865
176
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7866
606
    if (curve->order != NULL)
7867
149
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7868
606
    if (curve->Gx != NULL)
7869
155
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7870
606
    if (curve->Gy != NULL)
7871
155
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7872
606
#endif
7873
7874
606
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7875
7876
606
    (void)heap;
7877
606
}
7878
#endif /* WOLFSSL_CUSTOM_CURVES */
7879
7880
/**
7881
  Free an ECC key from memory
7882
  key   The key you wish to free
7883
*/
7884
WOLFSSL_ABI
7885
int wc_ecc_free(ecc_key* key)
7886
30.7k
{
7887
30.7k
    if (key == NULL) {
7888
1
        return 0;
7889
1
    }
7890
7891
30.7k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7892
30.7k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7893
30.7k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7894
30.7k
#ifndef WOLFSSL_NO_MALLOC
7895
30.7k
    if (key->sign_k != NULL)
7896
218
#endif
7897
218
    {
7898
218
        mp_forcezero(key->sign_k);
7899
218
        mp_free(key->sign_k);
7900
218
#ifndef WOLFSSL_NO_MALLOC
7901
218
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7902
218
#endif
7903
218
    }
7904
30.7k
#endif
7905
7906
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7907
    #ifdef WC_ASYNC_ENABLE_ECC
7908
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
7909
    #endif
7910
    wc_ecc_free_async(key);
7911
#endif
7912
7913
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
7914
    /* free secure memory */
7915
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
7916
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
7917
       caamFreePart(key->partNum);
7918
    }
7919
#endif
7920
7921
#ifdef WOLFSSL_SE050
7922
#ifdef WOLFSSL_SE050_AUTO_ERASE
7923
    wc_se050_erase_object(key->keyId);
7924
#endif
7925
    se050_ecc_free_key(key);
7926
#endif
7927
7928
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7929
    atmel_ecc_free(key->slot);
7930
    key->slot = ATECC_INVALID_SLOT;
7931
#endif /* WOLFSSL_ATECC508A */
7932
7933
#ifdef WOLFSSL_KCAPI_ECC
7934
    KcapiEcc_Free(key);
7935
#endif
7936
7937
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7938
    key->privKey = NULL;
7939
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
7940
    ForceZero(&key->xSec, sizeof(key->xSec));
7941
#endif
7942
7943
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
7944
    wc_MAXQ10XX_EccFree(key);
7945
#endif
7946
7947
30.7k
    mp_clear(key->pubkey.x);
7948
30.7k
    mp_clear(key->pubkey.y);
7949
30.7k
    mp_clear(key->pubkey.z);
7950
7951
#ifdef ALT_ECC_SIZE
7952
    if (key->k)
7953
#endif
7954
30.7k
        mp_forcezero(key->k);
7955
#ifdef WOLFSSL_ECC_BLIND_K
7956
#ifdef ALT_ECC_SIZE
7957
    if (key->kb)
7958
#endif
7959
        mp_forcezero(key->kb);
7960
#ifdef ALT_ECC_SIZE
7961
    if (key->ku)
7962
#endif
7963
        mp_forcezero(key->ku);
7964
#endif
7965
7966
30.7k
#ifdef WOLFSSL_CUSTOM_CURVES
7967
30.7k
    if (key->deallocSet && key->dp != NULL)
7968
0
        wc_ecc_free_curve(key->dp, key->heap);
7969
30.7k
#endif
7970
7971
#ifdef WOLFSSL_CHECK_MEM_ZERO
7972
    wc_MemZero_Check(key, sizeof(ecc_key));
7973
#endif
7974
7975
30.7k
    return 0;
7976
30.7k
}
7977
7978
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7979
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
7980
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
7981
      defined(WOLFSSL_IMXRT1170_CAAM))
7982
7983
/* Handles add failure cases:
7984
 *
7985
 * Before add:
7986
 *   Case 1: A is infinity
7987
 *        -> Copy B into result.
7988
 *   Case 2: B is infinity
7989
 *        -> Copy A into result.
7990
 *   Case 3: x and z are the same in A and B (same x value in affine)
7991
 *     Case 3a: y values the same - same point
7992
 *           -> Double instead of add.
7993
 *     Case 3b: y values different - negative of the other when points on curve
7994
 *           -> Need to set result to infinity.
7995
 *
7996
 * After add:
7997
 *   Case 1: A and B are the same point (maybe different z)
7998
 *           (Result was: x == y == z == 0)
7999
 *        -> Need to double instead.
8000
 *
8001
 *   Case 2: A + B = <infinity> = 0.
8002
 *           (Result was: z == 0, x and/or y not 0)
8003
 *        -> Need to set result to infinity.
8004
 */
8005
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8006
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8007
7.09M
{
8008
7.09M
    int err;
8009
8010
7.09M
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8011
        /* A is infinity. */
8012
317k
        err = wc_ecc_copy_point(B, R);
8013
317k
    }
8014
6.77M
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8015
        /* B is infinity. */
8016
33.5k
        err = wc_ecc_copy_point(A, R);
8017
33.5k
    }
8018
6.74M
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8019
        /* x ordinattes the same. */
8020
1.43k
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8021
            /* A = B */
8022
609
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8023
609
        }
8024
822
        else {
8025
            /* A = -B */
8026
822
            err = mp_set(R->x, 0);
8027
822
            if (err == MP_OKAY)
8028
822
                err = mp_set(R->y, 0);
8029
822
            if (err == MP_OKAY)
8030
822
                err = mp_set(R->z, 1);
8031
822
            if ((err == MP_OKAY) && (infinity != NULL))
8032
291
                *infinity = 1;
8033
822
        }
8034
1.43k
    }
8035
6.74M
    else {
8036
6.74M
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8037
6.74M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8038
            /* When all zero then should have done a double */
8039
27.0k
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8040
750
                if (mp_iszero(B->z)) {
8041
0
                    err = wc_ecc_copy_point(B, R);
8042
0
                    if (err == MP_OKAY) {
8043
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8044
0
                    }
8045
0
                    if (err == MP_OKAY) {
8046
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8047
0
                    }
8048
0
                }
8049
750
                else {
8050
750
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8051
750
                }
8052
750
            }
8053
            /* When only Z zero then result is infinity */
8054
26.3k
            else {
8055
26.3k
                err = mp_set(R->x, 0);
8056
26.3k
                if (err == MP_OKAY)
8057
26.3k
                    err = mp_set(R->y, 0);
8058
26.3k
                if (err == MP_OKAY)
8059
26.3k
                    err = mp_set(R->z, 1);
8060
26.3k
                if ((err == MP_OKAY) && (infinity != NULL))
8061
25.1k
                    *infinity = 1;
8062
26.3k
            }
8063
27.0k
        }
8064
6.74M
    }
8065
8066
7.09M
    return err;
8067
7.09M
}
8068
8069
/* Handles when P is the infinity point.
8070
 *
8071
 * Double infinity -> infinity.
8072
 * Otherwise do normal double - which can't lead to infinity as odd order.
8073
 */
8074
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8075
                                  mp_int* modulus, mp_digit mp)
8076
7.57M
{
8077
7.57M
    int err;
8078
8079
7.57M
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8080
        /* P is infinity. */
8081
264k
        err = wc_ecc_copy_point(P, R);
8082
264k
    }
8083
7.31M
    else {
8084
7.31M
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8085
7.31M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8086
114k
           err = mp_set(R->x, 0);
8087
114k
           if (err == MP_OKAY)
8088
114k
               err = mp_set(R->y, 0);
8089
114k
           if (err == MP_OKAY)
8090
114k
               err = mp_set(R->z, 1);
8091
114k
        }
8092
7.31M
    }
8093
8094
7.57M
    return err;
8095
7.57M
}
8096
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8097
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8098
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8099
            (WOLFSSL_IMXRT1170_CAAM))
8100
        */
8101
8102
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8103
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \
8104
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8105
#ifdef ECC_SHAMIR
8106
8107
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8108
    ecc_point* Bm, mp_int* modulus, void* heap)
8109
3.41k
{
8110
3.41k
    int err = MP_OKAY;
8111
3.41k
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8112
8113
3.41k
    (void)heap;
8114
8115
3.41k
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8116
3.41k
#ifdef MP_INT_SIZE_CHECK_NULL
8117
3.41k
    if (mu == NULL)
8118
2
       err = MEMORY_E;
8119
3.41k
#endif
8120
3.41k
    if (err == MP_OKAY) {
8121
3.40k
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8122
3.40k
    }
8123
3.41k
    if (err == MP_OKAY) {
8124
3.40k
        err = mp_montgomery_calc_normalization(mu, modulus);
8125
8126
3.40k
        if (err == MP_OKAY) {
8127
            /* copy ones ... */
8128
3.40k
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8129
3.40k
        }
8130
8131
3.40k
        if (err == MP_OKAY)
8132
3.40k
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8133
3.40k
        if (err == MP_OKAY)
8134
3.40k
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8135
8136
3.40k
        if (err == MP_OKAY)
8137
3.40k
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8138
3.40k
        if (err == MP_OKAY)
8139
3.40k
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8140
3.40k
        if (err == MP_OKAY)
8141
3.40k
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8142
8143
        /* done with mu */
8144
3.40k
        mp_clear(mu);
8145
3.40k
    }
8146
8147
3.41k
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8148
8149
3.41k
    return err;
8150
3.41k
}
8151
8152
/** Computes kA*A + kB*B = C using Shamir's Trick
8153
  A        First point to multiply
8154
  kA       What to multiple A by
8155
  B        Second point to multiply
8156
  kB       What to multiple B by
8157
  C        [out] Destination point (can overlap with A or B)
8158
  a        ECC curve parameter a
8159
  modulus  Modulus for curve
8160
  return MP_OKAY on success
8161
*/
8162
#ifdef FP_ECC
8163
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8164
                             ecc_point* B, mp_int* kB,
8165
                             ecc_point* C, mp_int* a, mp_int* modulus,
8166
                             void* heap)
8167
#else
8168
int ecc_mul2add(ecc_point* A, mp_int* kA,
8169
                    ecc_point* B, mp_int* kB,
8170
                    ecc_point* C, mp_int* a, mp_int* modulus,
8171
                    void* heap)
8172
#endif
8173
4.52k
{
8174
#ifdef WOLFSSL_SMALL_STACK_CACHE
8175
  ecc_key        *key = NULL;
8176
#endif
8177
4.52k
#ifdef WOLFSSL_SMALL_STACK
8178
4.52k
  ecc_point**    precomp = NULL;
8179
#else
8180
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8181
  #ifdef WOLFSSL_NO_MALLOC
8182
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8183
  #endif
8184
#endif
8185
4.52k
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8186
#ifdef WOLFSSL_NO_MALLOC
8187
  unsigned char tA[ECC_BUFSIZE];
8188
  unsigned char tB[ECC_BUFSIZE];
8189
#else
8190
4.52k
  unsigned char* tA = NULL;
8191
4.52k
  unsigned char* tB = NULL;
8192
4.52k
#endif
8193
4.52k
  int            err = MP_OKAY, first, x, y;
8194
4.52k
  mp_digit       mp = 0;
8195
8196
  /* argchks */
8197
4.52k
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8198
4.52k
                                                         modulus == NULL) {
8199
0
     return ECC_BAD_ARG_E;
8200
0
  }
8201
8202
4.52k
#ifndef WOLFSSL_NO_MALLOC
8203
  /* allocate memory */
8204
4.52k
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8205
4.52k
  if (tA == NULL) {
8206
3
     return MP_MEM;
8207
3
  }
8208
4.51k
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8209
4.51k
  if (tB == NULL) {
8210
3
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8211
3
     return MP_MEM;
8212
3
  }
8213
4.51k
#endif
8214
8215
#ifdef WOLFSSL_SMALL_STACK_CACHE
8216
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8217
  if (key == NULL) {
8218
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8219
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8220
     return MP_MEM;
8221
  }
8222
#endif
8223
4.51k
#ifdef WOLFSSL_SMALL_STACK
8224
4.51k
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8225
4.51k
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8226
4.51k
  if (precomp == NULL) {
8227
3
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8228
3
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8229
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8230
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8231
  #endif
8232
3
     return MP_MEM;
8233
3
  }
8234
4.51k
#endif
8235
#ifdef WOLFSSL_SMALL_STACK_CACHE
8236
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8237
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8238
#ifdef ALT_ECC_SIZE
8239
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8240
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8241
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8242
#endif
8243
8244
  if (key->t1 == NULL || key->t2 == NULL
8245
#ifdef ALT_ECC_SIZE
8246
     || key->x == NULL || key->y == NULL || key->z == NULL
8247
#endif
8248
  ) {
8249
#ifdef ALT_ECC_SIZE
8250
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8251
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8252
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8253
#endif
8254
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8255
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8256
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8257
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8258
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8259
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8260
      return MEMORY_E;
8261
  }
8262
  C->key = key;
8263
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8264
8265
  /* init variables */
8266
4.51k
  XMEMSET(tA, 0, ECC_BUFSIZE);
8267
4.51k
  XMEMSET(tB, 0, ECC_BUFSIZE);
8268
#ifndef WOLFSSL_SMALL_STACK
8269
  XMEMSET(precomp, 0, sizeof(precomp));
8270
#else
8271
4.51k
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8272
4.51k
#endif
8273
#ifdef WOLFSSL_CHECK_MEM_ZERO
8274
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8275
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8276
#endif
8277
8278
  /* get sizes */
8279
4.51k
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8280
4.51k
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8281
4.51k
  len  = MAX(lenA, lenB);
8282
8283
  /* sanity check */
8284
4.51k
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8285
0
    err = BAD_FUNC_ARG;
8286
0
  }
8287
8288
4.51k
  if (err == MP_OKAY) {
8289
    /* extract and justify kA */
8290
4.51k
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8291
8292
    /* extract and justify kB */
8293
4.51k
    if (err == MP_OKAY)
8294
4.51k
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8295
8296
    /* allocate the table */
8297
4.51k
    if (err == MP_OKAY) {
8298
76.3k
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8299
        #ifdef WOLFSSL_NO_MALLOC
8300
            precomp[x] = &lcl_precomp[x];
8301
        #endif
8302
71.8k
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8303
71.8k
            if (err != MP_OKAY)
8304
32
                break;
8305
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8306
            precomp[x]->key = key;
8307
        #endif
8308
71.8k
        }
8309
4.51k
    }
8310
4.51k
  }
8311
8312
4.51k
  if (err == MP_OKAY)
8313
    /* init montgomery reduction */
8314
4.47k
    err = mp_montgomery_setup(modulus, &mp);
8315
8316
4.51k
  if (err == MP_OKAY) {
8317
4.47k
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8318
4.47k
  }
8319
8320
4.51k
  if (err == MP_OKAY) {
8321
    /* precomp [i,0](A + B) table */
8322
4.46k
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8323
4.46k
  }
8324
4.51k
  if (err == MP_OKAY) {
8325
4.46k
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8326
4.46k
                                                          a, modulus, mp, NULL);
8327
4.46k
  }
8328
8329
4.51k
  if (err == MP_OKAY) {
8330
    /* precomp [0,i](A + B) table */
8331
4.46k
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8332
4.46k
  }
8333
4.51k
  if (err == MP_OKAY) {
8334
4.46k
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8335
4.46k
                                                             modulus, mp, NULL);
8336
4.46k
  }
8337
8338
4.51k
  if (err == MP_OKAY) {
8339
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8340
17.8k
    for (x = 1; x < 4; x++) {
8341
53.5k
      for (y = 1; y < 4; y++) {
8342
40.1k
        if (err == MP_OKAY) {
8343
40.0k
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8344
40.0k
                                                  precomp[x+(y<<2)], a, modulus,
8345
40.0k
                                                  mp, NULL);
8346
40.0k
        }
8347
40.1k
      }
8348
13.3k
    }
8349
4.46k
  }
8350
8351
4.51k
  if (err == MP_OKAY) {
8352
4.44k
    nibble  = 3;
8353
4.44k
    first   = 1;
8354
4.44k
    bitbufA = tA[0];
8355
4.44k
    bitbufB = tB[0];
8356
8357
    /* for every byte of the multiplicands */
8358
547k
    for (x = 0; x < (int)len || nibble != 3; ) {
8359
        /* grab a nibble */
8360
543k
        if (++nibble == 4) {
8361
135k
            if (x == (int)len) break;
8362
135k
            bitbufA = tA[x];
8363
135k
            bitbufB = tB[x];
8364
135k
            nibble  = 0;
8365
135k
            x++;
8366
135k
        }
8367
8368
        /* extract two bits from both, shift/update */
8369
543k
        nA = (bitbufA >> 6) & 0x03;
8370
543k
        nB = (bitbufB >> 6) & 0x03;
8371
543k
        bitbufA = (bitbufA << 2) & 0xFF;
8372
543k
        bitbufB = (bitbufB << 2) & 0xFF;
8373
8374
        /* if both zero, if first, continue */
8375
543k
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8376
2.29k
            continue;
8377
2.29k
        }
8378
8379
        /* double twice, only if this isn't the first */
8380
540k
        if (first == 0) {
8381
            /* double twice */
8382
535k
            if (err == MP_OKAY)
8383
535k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8384
535k
            if (err == MP_OKAY)
8385
535k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8386
11
            else
8387
11
                break;
8388
535k
        }
8389
8390
        /* if not both zero */
8391
540k
        if ((nA != 0) || (nB != 0)) {
8392
484k
            unsigned int i = nA + (nB<<2);
8393
484k
            if (first == 1) {
8394
                /* if first, copy from table */
8395
5.78k
                first = 0;
8396
5.78k
                if (err == MP_OKAY)
8397
5.78k
                    err = mp_copy(precomp[i]->x, C->x);
8398
8399
5.78k
                if (err == MP_OKAY)
8400
5.78k
                    err = mp_copy(precomp[i]->y, C->y);
8401
8402
5.78k
                if (err == MP_OKAY)
8403
5.78k
                    err = mp_copy(precomp[i]->z, C->z);
8404
0
                else
8405
0
                    break;
8406
478k
            } else {
8407
                /* if not first, add from table */
8408
478k
                if (err == MP_OKAY)
8409
478k
                    err = ecc_projective_add_point_safe(C, precomp[i],
8410
478k
                                                        C, a, modulus, mp,
8411
478k
                                                        &first);
8412
478k
                if (err != MP_OKAY)
8413
18
                    break;
8414
478k
            }
8415
484k
        }
8416
540k
    }
8417
4.44k
  }
8418
8419
  /* reduce to affine */
8420
4.51k
  if (err == MP_OKAY)
8421
4.41k
    err = ecc_map(C, modulus, mp);
8422
8423
  /* clean up */
8424
76.6k
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8425
72.1k
     wc_ecc_del_point_ex(precomp[x], heap);
8426
72.1k
  }
8427
8428
4.51k
  ForceZero(tA, ECC_BUFSIZE);
8429
4.51k
  ForceZero(tB, ECC_BUFSIZE);
8430
#ifdef WOLFSSL_SMALL_STACK_CACHE
8431
#ifdef ALT_ECC_SIZE
8432
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8433
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8434
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8435
#endif
8436
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8437
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8438
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8439
  C->key = NULL;
8440
#endif
8441
4.51k
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8442
4.51k
#ifndef WOLFSSL_NO_MALLOC
8443
4.51k
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8444
4.51k
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8445
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8446
  wc_MemZero_Check(tB, ECC_BUFSIZE);
8447
  wc_MemZero_Check(tA, ECC_BUFSIZE);
8448
#endif
8449
4.51k
  return err;
8450
4.51k
}
8451
8452
#endif /* ECC_SHAMIR */
8453
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
8454
        * !WOLFSSL_CRYPTOCEL */
8455
8456
8457
#ifdef HAVE_ECC_VERIFY
8458
/* verify
8459
 *
8460
 * w  = s^-1 mod n
8461
 * u1 = xw
8462
 * u2 = rw
8463
 * X = u1*G + u2*Q
8464
 * v = X_x1 mod n
8465
 * accept if v == r
8466
 */
8467
8468
/**
8469
 Verify an ECC signature
8470
 sig         The signature to verify
8471
 siglen      The length of the signature (octets)
8472
 hash        The hash (message digest) that was signed
8473
 hashlen     The length of the hash (octets)
8474
 res         Result of signature, 1==valid, 0==invalid
8475
 key         The corresponding public ECC key
8476
 return      MP_OKAY if successful (even if the signature is not valid)
8477
             Caller should check the *res value to determine if the signature
8478
             is valid or invalid. Other negative values are returned on error.
8479
 */
8480
WOLFSSL_ABI
8481
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
8482
                       word32 hashlen, int* res, ecc_key* key)
8483
5.86k
{
8484
5.86k
    int err;
8485
8486
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8487
    mp_int *r = NULL, *s = NULL;
8488
#else
8489
5.86k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8490
5.86k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8491
5.86k
#endif
8492
#ifdef WOLFSSL_ASYNC_CRYPT
8493
    int isPrivateKeyOnly = 0;
8494
#endif
8495
#ifdef NO_ASN
8496
    word32 keySz;
8497
#endif
8498
8499
5.86k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8500
55
        return ECC_BAD_ARG_E;
8501
55
    }
8502
5.81k
    if (hashlen > WC_MAX_DIGEST_SIZE) {
8503
77
        return BAD_LENGTH_E;
8504
77
    }
8505
8506
5.73k
#ifdef WOLF_CRYPTO_CB
8507
5.73k
    #ifndef WOLF_CRYPTO_CB_FIND
8508
5.73k
    if (key->devId != INVALID_DEVID)
8509
0
    #endif
8510
0
    {
8511
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
8512
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8513
0
            return err;
8514
        /* fall-through when unavailable */
8515
0
    }
8516
5.73k
#endif
8517
8518
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
8519
    (void)siglen;
8520
    (void)hashlen;
8521
    (void)s;
8522
    (void)r;
8523
    (void)err;
8524
    return NO_VALID_DEVID;
8525
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
8526
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8527
    err = wc_ecc_alloc_async(key);
8528
    if (err != 0)
8529
        return err;
8530
    r = key->r;
8531
    s = key->s;
8532
#else
8533
5.73k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8534
5.73k
        DYNAMIC_TYPE_ECC);
8535
5.73k
    #ifdef MP_INT_SIZE_CHECK_NULL
8536
5.73k
    if (r == NULL)
8537
12
        return MEMORY_E;
8538
5.72k
    #endif
8539
5.72k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8540
5.72k
        DYNAMIC_TYPE_ECC);
8541
5.72k
    #ifdef MP_INT_SIZE_CHECK_NULL
8542
5.72k
    if (s == NULL) {
8543
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8544
5
        return MEMORY_E;
8545
5
    }
8546
5.71k
    #endif
8547
5.71k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8548
5.71k
    if (err != 0) {
8549
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8550
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8551
0
        return err;
8552
0
    }
8553
5.71k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8554
5.71k
    if (err != 0) {
8555
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8556
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8557
0
        return err;
8558
0
    }
8559
5.71k
#endif /* WOLFSSL_ASYNC_CRYPT */
8560
8561
5.71k
    switch (key->state) {
8562
5.71k
        case ECC_STATE_NONE:
8563
5.71k
        case ECC_STATE_VERIFY_DECODE:
8564
5.71k
            key->state = ECC_STATE_VERIFY_DECODE;
8565
8566
            /* default to invalid signature */
8567
5.71k
            *res = 0;
8568
8569
5.71k
    #ifndef NO_ASN
8570
            /* Decode ASN.1 ECDSA signature. */
8571
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8572
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
8573
             * If either of those don't allocate correctly, none of
8574
             * the rest of this function will execute, and everything
8575
             * gets cleaned up at the end. */
8576
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
8577
        #else
8578
            /* r and s are initialized. */
8579
5.71k
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8580
5.71k
        #endif
8581
5.71k
            if (err < 0) {
8582
62
                break;
8583
62
            }
8584
    #else
8585
            /* No support for DSA ASN.1 header.
8586
             * Signature must be r+s directly. */
8587
            keySz = 0;
8588
            if (key->dp != NULL) {
8589
                keySz = (word32)key->dp->size;
8590
            }
8591
            if (siglen != keySz * 2) {
8592
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
8593
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
8594
            }
8595
8596
            /* Import signature into r,s */
8597
            mp_init(r);
8598
            mp_init(s);
8599
            mp_read_unsigned_bin(r, sig, keySz);
8600
            mp_read_unsigned_bin(s, sig + keySz, keySz);
8601
    #endif /* !NO_ASN */
8602
5.65k
            FALL_THROUGH;
8603
8604
5.65k
        case ECC_STATE_VERIFY_DO:
8605
5.65k
            key->state = ECC_STATE_VERIFY_DO;
8606
        #ifdef WOLFSSL_ASYNC_CRYPT
8607
            if (key->type == ECC_PRIVATEKEY_ONLY) {
8608
                isPrivateKeyOnly = 1;
8609
            }
8610
        #endif
8611
5.65k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8612
8613
5.65k
        #ifndef WOLFSSL_ASYNC_CRYPT
8614
            /* done with R/S */
8615
5.65k
            mp_clear(r);
8616
5.65k
            mp_clear(s);
8617
5.65k
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8618
5.65k
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8619
5.65k
        #ifdef MP_INT_SIZE_CHECK_NULL
8620
5.65k
            r = NULL;
8621
5.65k
            s = NULL;
8622
5.65k
        #endif
8623
5.65k
        #endif
8624
8625
5.65k
            if (err < 0) {
8626
211
                break;
8627
211
            }
8628
5.44k
            FALL_THROUGH;
8629
8630
5.44k
        case ECC_STATE_VERIFY_RES:
8631
5.44k
            key->state = ECC_STATE_VERIFY_RES;
8632
5.44k
            err = 0;
8633
5.44k
            break;
8634
8635
0
        default:
8636
0
            err = BAD_STATE_E;
8637
5.71k
    }
8638
8639
#ifdef WOLFSSL_ASYNC_CRYPT
8640
    /* if async pending then return and skip done cleanup below */
8641
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8642
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
8643
            key->state++;
8644
        return err;
8645
    }
8646
#endif
8647
8648
    /* cleanup */
8649
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8650
    wc_ecc_free_async(key);
8651
#else
8652
5.71k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8653
5.71k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8654
5.71k
#endif
8655
8656
    /* make sure required variables are reset */
8657
5.71k
    wc_ecc_reset(key);
8658
5.71k
    return err;
8659
5.71k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8660
5.71k
}
8661
8662
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
8663
8664
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
8665
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8666
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
8667
3.57k
{
8668
3.57k
    int err = MP_OKAY;
8669
3.57k
    DECLARE_CURVE_SPECS(1);
8670
8671
3.57k
    ALLOC_CURVE_SPECS(1, err);
8672
3.57k
    if (err == MP_OKAY) {
8673
3.57k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8674
3.57k
    }
8675
3.57k
    if (err != 0) {
8676
2
        FREE_CURVE_SPECS();
8677
2
        return err;
8678
2
    }
8679
8680
3.57k
    if (mp_iszero(r) || mp_iszero(s)) {
8681
23
        err = MP_ZERO_E;
8682
23
    }
8683
3.57k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8684
32
        err = MP_VAL;
8685
32
    }
8686
3.57k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8687
46
        err = MP_VAL;
8688
46
    }
8689
8690
3.57k
    wc_ecc_curve_free(curve);
8691
3.57k
    FREE_CURVE_SPECS();
8692
3.57k
    return err;
8693
3.57k
}
8694
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
8695
8696
#ifdef HAVE_ECC_VERIFY_HELPER
8697
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
8698
    word32 hashlen, int* res, ecc_key* key)
8699
4.89k
{
8700
4.89k
    (void)r;
8701
4.89k
    (void)s;
8702
4.89k
    (void)hash;
8703
4.89k
    (void)hashlen;
8704
4.89k
    (void)res;
8705
4.89k
    (void)key;
8706
8707
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
8708
  if (key->handle != -1) {
8709
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
8710
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8711
  }
8712
  if (wolfSSL_GetHandleCbSet() == 1) {
8713
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
8714
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8715
  }
8716
#endif
8717
8718
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
8719
    if (key->idx == ECC_CUSTOM_IDX || (1
8720
    #ifndef WOLFSSL_SP_NO_256
8721
         && ecc_sets[key->idx].id != ECC_SECP256R1
8722
    #endif
8723
    #ifdef WOLFSSL_SP_SM2
8724
         && ecc_sets[key->idx].id != ECC_SM2P256V1
8725
    #endif
8726
    #ifdef WOLFSSL_SP_384
8727
         && ecc_sets[key->idx].id != ECC_SECP384R1
8728
    #endif
8729
    #ifdef WOLFSSL_SP_521
8730
         && ecc_sets[key->idx].id != ECC_SECP521R1
8731
    #endif
8732
        )) {
8733
        return WC_KEY_SIZE_E;
8734
    }
8735
#endif
8736
8737
#if defined(WOLFSSL_HAVE_SP_ECC)
8738
    if (key->idx != ECC_CUSTOM_IDX) {
8739
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
8740
        /* perform blocking call to non-blocking function */
8741
        ecc_nb_ctx_t nb_ctx;
8742
        int err;
8743
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
8744
        err = NOT_COMPILED_IN; /* set default error */
8745
    #endif
8746
    #ifndef WOLFSSL_SP_NO_256
8747
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
8748
        #ifdef WC_ECC_NONBLOCK
8749
            if (key->nb_ctx) {
8750
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8751
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8752
                    key->heap);
8753
            }
8754
            #ifdef WC_ECC_NONBLOCK_ONLY
8755
            do { /* perform blocking call to non-blocking function */
8756
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
8757
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8758
                    key->heap);
8759
            } while (err == FP_WOULDBLOCK);
8760
            return err;
8761
            #endif
8762
        #endif /* WC_ECC_NONBLOCK */
8763
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8764
            {
8765
                int ret;
8766
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8767
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
8768
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8769
                RESTORE_VECTOR_REGISTERS();
8770
                return ret;
8771
            }
8772
        #endif
8773
        }
8774
    #endif
8775
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
8776
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
8777
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
8778
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
8779
                key->pubkey.y, key->pubkey.z, r, s, res,
8780
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
8781
                                          key->fpIdx, key->fpBuild, key->heap),
8782
                key->heap);
8783
            #endif
8784
            #if !defined(FP_ECC_CONTROL)
8785
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
8786
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8787
            #endif
8788
        }
8789
    #endif
8790
    #ifdef WOLFSSL_SP_384
8791
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
8792
        #ifdef WC_ECC_NONBLOCK
8793
            if (key->nb_ctx) {
8794
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8795
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8796
                    key->heap);
8797
            }
8798
            #ifdef WC_ECC_NONBLOCK_ONLY
8799
            do { /* perform blocking call to non-blocking function */
8800
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
8801
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8802
                    key->heap);
8803
            } while (err == FP_WOULDBLOCK);
8804
            return err;
8805
            #endif
8806
        #endif /* WC_ECC_NONBLOCK */
8807
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8808
            {
8809
                int ret;
8810
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8811
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
8812
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8813
                RESTORE_VECTOR_REGISTERS();
8814
                return ret;
8815
            }
8816
        #endif
8817
        }
8818
    #endif
8819
    #ifdef WOLFSSL_SP_521
8820
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
8821
        #ifdef WC_ECC_NONBLOCK
8822
            if (key->nb_ctx) {
8823
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8824
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8825
                    key->heap);
8826
            }
8827
            #ifdef WC_ECC_NONBLOCK_ONLY
8828
            do { /* perform blocking call to non-blocking function */
8829
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
8830
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8831
                    key->heap);
8832
            } while (err == FP_WOULDBLOCK);
8833
            return err;
8834
            #endif
8835
        #endif /* WC_ECC_NONBLOCK */
8836
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8837
            {
8838
                int ret;
8839
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8840
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
8841
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8842
                RESTORE_VECTOR_REGISTERS();
8843
                return ret;
8844
            }
8845
        #endif
8846
        }
8847
    #endif
8848
    }
8849
#endif
8850
8851
4.89k
    return NOT_COMPILED_IN;
8852
4.89k
}
8853
8854
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
8855
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
8856
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
8857
3.46k
{
8858
3.46k
   int        err;
8859
3.46k
   ecc_point* mG = NULL;
8860
3.46k
   ecc_point* mQ = NULL;
8861
#ifdef WOLFSSL_NO_MALLOC
8862
   ecc_point  lcl_mG;
8863
   ecc_point  lcl_mQ;
8864
#endif
8865
3.46k
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8866
3.46k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8867
3.46k
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8868
3.46k
#endif
8869
3.46k
   mp_int*    e;
8870
3.46k
   mp_int*    v = NULL;      /* Will be w. */
8871
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
8872
   mp_int     u1tmp[1];
8873
   mp_int     u2tmp[1];
8874
#endif
8875
3.46k
   mp_int*    u1 = NULL;     /* Will be e. */
8876
3.46k
   mp_int*    u2 = NULL;     /* Will be w. */
8877
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
8878
   err = wc_ecc_alloc_mpint(key, &key->e);
8879
   if (err != 0) {
8880
      return err;
8881
   }
8882
   e = key->e;
8883
8884
   err = mp_init(e);
8885
#else
8886
3.46k
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8887
3.46k
#ifdef MP_INT_SIZE_CHECK_NULL
8888
3.46k
   if (e_lcl == NULL) {
8889
2
       return MEMORY_E;
8890
2
   }
8891
3.46k
#endif
8892
3.46k
   e = e_lcl;
8893
8894
3.46k
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8895
3.46k
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8896
3.46k
   if (err != MP_OKAY) {
8897
0
#ifdef WOLFSSL_SMALL_STACK
8898
0
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8899
0
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8900
0
   #endif
8901
0
#endif
8902
0
      return MEMORY_E;
8903
0
   }
8904
8905
   /* read hash */
8906
3.46k
   if (err == MP_OKAY) {
8907
       /* we may need to truncate if hash is longer than key size */
8908
3.46k
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
8909
8910
       /* truncate down to byte size, may be all that's needed */
8911
3.46k
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8912
410
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8913
3.46k
       err = mp_read_unsigned_bin(e, hash, hashlen);
8914
8915
       /* may still need bit truncation too */
8916
3.46k
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8917
303
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8918
3.46k
   }
8919
8920
   /* check for async hardware acceleration */
8921
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8922
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8923
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8924
   #ifdef HAVE_CAVIUM_V
8925
      if (NitroxEccIsCurveSupported(key))
8926
   #endif
8927
      {
8928
          word32 keySz = (word32)key->dp->size;
8929
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8930
          if (err == MP_OKAY)
8931
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
8932
          if (err == MP_OKAY)
8933
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
8934
          if (err == MP_OKAY)
8935
          #ifdef HAVE_CAVIUM_V
8936
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
8937
                    &key->pubkey.y->raw, &r->raw, &s->raw,
8938
                    &curve->prime->raw, &curve->order->raw, res);
8939
          #else
8940
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
8941
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
8942
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
8943
                    &curve->Gx->raw, &curve->Gy->raw, res);
8944
          #endif
8945
8946
      #ifndef HAVE_CAVIUM_V
8947
          mp_clear(e);
8948
      #endif
8949
8950
          return err;
8951
      }
8952
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8953
   }
8954
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8955
8956
3.46k
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8957
3.46k
#ifdef MP_INT_SIZE_CHECK_NULL
8958
3.46k
   if (w == NULL) {
8959
2
       err = MEMORY_E;
8960
2
   }
8961
3.46k
#endif
8962
8963
3.46k
   if (err == MP_OKAY) {
8964
#ifdef WOLFSSL_CHECK_VER_FAULTS
8965
    #ifndef WOLFSSL_NO_MALLOC
8966
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8967
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8968
       if (u1 == NULL || u2 == NULL)
8969
            err = MEMORY_E;
8970
    #else
8971
        u1 = u1tmp;
8972
        u2 = u2tmp;
8973
    #endif
8974
#else
8975
3.46k
       u1 = e;
8976
3.46k
       u2 = w;
8977
3.46k
#endif
8978
3.46k
       v = w;
8979
3.46k
   }
8980
3.46k
   if (err == MP_OKAY) {
8981
3.46k
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8982
3.46k
   }
8983
#ifdef WOLFSSL_CHECK_VER_FAULTS
8984
   if (err == MP_OKAY) {
8985
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8986
   }
8987
   if (err == MP_OKAY) {
8988
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8989
   }
8990
#endif
8991
8992
   /* allocate points */
8993
3.46k
   if (err == MP_OKAY) {
8994
   #ifdef WOLFSSL_NO_MALLOC
8995
       mG = &lcl_mG;
8996
   #endif
8997
3.46k
       err = wc_ecc_new_point_ex(&mG, key->heap);
8998
3.46k
   }
8999
3.46k
   if (err == MP_OKAY) {
9000
   #ifdef WOLFSSL_NO_MALLOC
9001
       mQ = &lcl_mQ;
9002
   #endif
9003
3.46k
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9004
3.46k
   }
9005
9006
   /*  w  = s^-1 mod n */
9007
3.46k
   if (err == MP_OKAY)
9008
3.45k
       err = mp_invmod(s, curve->order, w);
9009
9010
   /* u1 = ew */
9011
3.46k
   if (err == MP_OKAY)
9012
3.45k
       err = mp_mulmod(e, w, curve->order, u1);
9013
9014
#ifdef WOLFSSL_CHECK_VER_FAULTS
9015
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9016
        err = BAD_STATE_E;
9017
    }
9018
#endif
9019
9020
   /* u2 = rw */
9021
3.46k
   if (err == MP_OKAY)
9022
3.45k
       err = mp_mulmod(r, w, curve->order, u2);
9023
9024
#ifdef WOLFSSL_CHECK_VER_FAULTS
9025
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9026
        err = BAD_STATE_E;
9027
    }
9028
#endif
9029
9030
   /* find mG and mQ */
9031
3.46k
   if (err == MP_OKAY)
9032
3.43k
       err = mp_copy(curve->Gx, mG->x);
9033
3.46k
   if (err == MP_OKAY)
9034
3.43k
       err = mp_copy(curve->Gy, mG->y);
9035
3.46k
   if (err == MP_OKAY)
9036
3.43k
       err = mp_set(mG->z, 1);
9037
9038
3.46k
   if (err == MP_OKAY)
9039
3.43k
       err = mp_copy(key->pubkey.x, mQ->x);
9040
3.46k
   if (err == MP_OKAY)
9041
3.43k
       err = mp_copy(key->pubkey.y, mQ->y);
9042
3.46k
   if (err == MP_OKAY)
9043
3.43k
       err = mp_copy(key->pubkey.z, mQ->z);
9044
9045
#if defined(FREESCALE_LTC_ECC)
9046
   /* use PKHA to compute u1*mG + u2*mQ */
9047
   if (err == MP_OKAY)
9048
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9049
   if (err == MP_OKAY)
9050
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9051
   if (err == MP_OKAY)
9052
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9053
#else
9054
#ifndef ECC_SHAMIR
9055
    if (err == MP_OKAY)
9056
    {
9057
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9058
        ecc_point mG1, mQ1;
9059
        wc_ecc_copy_point(mQ, &mQ1);
9060
        wc_ecc_copy_point(mG, &mG1);
9061
     #endif
9062
9063
        mp_digit mp = 0;
9064
9065
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9066
            /* compute u1*mG + u2*mQ = mG */
9067
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9068
                                                                     key->heap);
9069
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9070
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9071
                err = BAD_STATE_E;
9072
            }
9073
9074
            /* store new value for comparing with after add operation */
9075
           wc_ecc_copy_point(mG, &mG1);
9076
        #endif
9077
            if (err == MP_OKAY) {
9078
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9079
                                                                     key->heap);
9080
            }
9081
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9082
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9083
                err = BAD_STATE_E;
9084
            }
9085
        #endif
9086
9087
            /* find the montgomery mp */
9088
            if (err == MP_OKAY)
9089
                err = mp_montgomery_setup(curve->prime, &mp);
9090
9091
            /* add them */
9092
            if (err == MP_OKAY)
9093
                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
9094
                                                        curve->prime, mp, NULL);
9095
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9096
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9097
                err = BAD_STATE_E;
9098
            }
9099
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9100
                err = BAD_STATE_E;
9101
            }
9102
        #endif
9103
        }
9104
        else {
9105
            /* compute 0*mG + u2*mQ = mG */
9106
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9107
                                                                     key->heap);
9108
            /* find the montgomery mp */
9109
            if (err == MP_OKAY)
9110
                err = mp_montgomery_setup(curve->prime, &mp);
9111
        }
9112
9113
        /* reduce */
9114
        if (err == MP_OKAY)
9115
            err = ecc_map(mG, curve->prime, mp);
9116
    }
9117
#else
9118
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9119
3.46k
    if (err == MP_OKAY) {
9120
3.43k
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9121
3.43k
                                                                     key->heap);
9122
3.43k
    }
9123
3.46k
#endif /* ECC_SHAMIR */
9124
3.46k
#endif /* FREESCALE_LTC_ECC */
9125
9126
   /* v = X_x1 mod n */
9127
3.46k
   if (err == MP_OKAY)
9128
3.37k
       err = mp_mod(mG->x, curve->order, v);
9129
9130
   /* does v == r */
9131
3.46k
   if (err == MP_OKAY) {
9132
3.37k
       if (mp_cmp(v, r) == MP_EQ)
9133
3.12k
           *res = 1;
9134
#ifdef WOLFSSL_CHECK_VER_FAULTS
9135
       /* redundant comparison as sanity check that first one happened */
9136
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9137
           *res = 0;
9138
#endif
9139
3.37k
   }
9140
9141
   /* cleanup */
9142
3.46k
   wc_ecc_del_point_ex(mG, key->heap);
9143
3.46k
   wc_ecc_del_point_ex(mQ, key->heap);
9144
9145
3.46k
   mp_clear(e);
9146
3.46k
   mp_clear(w);
9147
3.46k
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9148
#ifdef WOLFSSL_CHECK_VER_FAULTS
9149
   mp_clear(u1);
9150
   mp_clear(u2);
9151
#ifndef WOLFSSL_NO_MALLOC
9152
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9153
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9154
#endif
9155
#endif
9156
3.46k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9157
3.46k
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9158
3.46k
#endif
9159
9160
3.46k
   return err;
9161
3.46k
}
9162
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9163
#endif /* HAVE_ECC_VERIFY_HELPER */
9164
9165
/**
9166
   Verify an ECC signature
9167
   r           The signature R component to verify
9168
   s           The signature S component to verify
9169
   hash        The hash (message digest) that was signed
9170
   hashlen     The length of the hash (octets)
9171
   res         Result of signature, 1==valid, 0==invalid
9172
   key         The corresponding public ECC key
9173
   return      MP_OKAY if successful (even if the signature is not valid)
9174
               Caller should check the *res value to determine if the signature
9175
               is valid or invalid. Other negative values are returned on error.
9176
*/
9177
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9178
                    word32 hashlen, int* res, ecc_key* key)
9179
3.57k
{
9180
#if defined(WOLFSSL_STM32_PKA)
9181
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9182
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9183
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9184
#else
9185
3.57k
   int           err;
9186
3.57k
   word32        keySz = 0;
9187
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9188
   byte sigRS[ATECC_KEY_SIZE*2];
9189
#elif defined(WOLFSSL_CRYPTOCELL)
9190
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9191
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9192
   word32 msgLenInBytes = hashlen;
9193
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9194
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9195
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9196
#elif defined(WOLFSSL_KCAPI_ECC)
9197
   byte sigRS[MAX_ECC_BYTES*2];
9198
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9199
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9200
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9201
#elif defined(WOLFSSL_SE050)
9202
#else
9203
3.57k
   int curveLoaded = 0;
9204
3.57k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9205
3.57k
#endif
9206
9207
3.57k
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9208
0
       return ECC_BAD_ARG_E;
9209
9210
   /* default to invalid signature */
9211
3.57k
   *res = 0;
9212
9213
   /* is the IDX valid ?  */
9214
3.57k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9215
0
      return ECC_BAD_ARG_E;
9216
0
   }
9217
9218
3.57k
   err = wc_ecc_check_r_s_range(key, r, s);
9219
3.57k
   if (err != MP_OKAY) {
9220
103
      return err;
9221
103
   }
9222
9223
3.47k
   keySz = (word32)key->dp->size;
9224
9225
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9226
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9227
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9228
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9229
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9230
            sw->eccVerify.r = r;
9231
            sw->eccVerify.s = s;
9232
            sw->eccVerify.hash = hash;
9233
            sw->eccVerify.hashlen = hashlen;
9234
            sw->eccVerify.stat = res;
9235
            sw->eccVerify.key = key;
9236
            return WC_PENDING_E;
9237
        }
9238
    }
9239
#endif
9240
9241
#ifndef HAVE_ECC_VERIFY_HELPER
9242
9243
#ifndef WOLFSSL_SE050
9244
    /* Extract R and S with front zero padding (if required),
9245
     * SE050 does this in port layer  */
9246
    XMEMSET(sigRS, 0, sizeof(sigRS));
9247
    err = mp_to_unsigned_bin(r, sigRS +
9248
                                (keySz - mp_unsigned_bin_size(r)));
9249
    if (err != MP_OKAY) {
9250
        return err;
9251
    }
9252
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9253
                                (keySz - mp_unsigned_bin_size(s)));
9254
    if (err != MP_OKAY) {
9255
        return err;
9256
    }
9257
#endif /* WOLFSSL_SE050 */
9258
9259
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9260
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9261
    if (err != 0) {
9262
       return err;
9263
    }
9264
    (void)hashlen;
9265
#elif defined(WOLFSSL_CRYPTOCELL)
9266
9267
   /* truncate if hash is longer than key size */
9268
   if (msgLenInBytes > keySz) {
9269
       msgLenInBytes = keySz;
9270
   }
9271
   hash_mode = cc310_hashModeECC(msgLenInBytes);
9272
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
9273
       /* hash_mode = */ cc310_hashModeECC(keySz);
9274
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
9275
   }
9276
9277
   /* verify the signature using the public key */
9278
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
9279
                           &key->ctx.pubKey,
9280
                           hash_mode,
9281
                           &sigRS[0],
9282
                           keySz*2,
9283
                           (byte*)hash,
9284
                           msgLenInBytes);
9285
9286
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
9287
       /* signature verification reported invalid signature. */
9288
       *res = 0; /* Redundant, added for code clarity */
9289
       err = MP_OKAY;
9290
   }
9291
   else if (err != SA_SILIB_RET_OK) {
9292
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
9293
       return err;
9294
   }
9295
   else {
9296
       /* valid signature. */
9297
       *res = 1;
9298
       err = MP_OKAY;
9299
   }
9300
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9301
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
9302
                                hash, hashlen,
9303
                                res, key);
9304
#elif defined(WOLFSSL_KCAPI_ECC)
9305
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
9306
    if (err == 0) {
9307
        *res = 1;
9308
    }
9309
#elif defined(WOLFSSL_SE050)
9310
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9311
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9312
    if (hashlen > sizeof(hashcopy))
9313
        return ECC_BAD_ARG_E;
9314
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
9315
    mp_reverse(sigRS, keySz);
9316
    mp_reverse(sigRS + keySz, keySz);
9317
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
9318
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
9319
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
9320
9321
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
9322
                                     xil_curve_type[key->dp->id],
9323
                                     XIL_CAST_U64(hashcopy), keySz,
9324
                                     XIL_CAST_U64(key->keyRaw),
9325
                                     XIL_CAST_U64(sigRS));
9326
9327
    if (err != XST_SUCCESS) {
9328
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
9329
        err = WC_HW_E;
9330
    } else {
9331
        *res = 1;
9332
    }
9333
#endif
9334
9335
#else
9336
  /* checking if private key with no public part */
9337
3.47k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9338
1.23k
      WOLFSSL_MSG("Verify called with private key, generating public part");
9339
1.23k
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9340
1.23k
      if (err != MP_OKAY) {
9341
1
          return err;
9342
1
      }
9343
1.23k
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9344
1.23k
      if (err != MP_OKAY) {
9345
0
          FREE_CURVE_SPECS();
9346
0
          return err;
9347
0
      }
9348
1.23k
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9349
1.23k
      if (err != MP_OKAY) {
9350
4
           WOLFSSL_MSG("Unable to extract public key");
9351
4
           wc_ecc_curve_free(curve);
9352
4
           FREE_CURVE_SPECS();
9353
4
           return err;
9354
4
      }
9355
1.22k
      curveLoaded = 1;
9356
1.22k
  }
9357
9358
3.46k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9359
3.46k
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
9360
0
      if (curveLoaded) {
9361
0
           wc_ecc_curve_free(curve);
9362
0
           FREE_CURVE_SPECS();
9363
0
      }
9364
0
      return err;
9365
0
  }
9366
9367
3.46k
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9368
3.46k
   if (!curveLoaded) {
9369
2.24k
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9370
2.24k
       if (err != 0) {
9371
2
          return err;
9372
2
       }
9373
       /* read in the specs for this curve */
9374
2.24k
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9375
2.24k
       if (err != 0) {
9376
0
          FREE_CURVE_SPECS();
9377
0
          return err;
9378
0
       }
9379
2.24k
   }
9380
9381
3.46k
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9382
3.46k
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9383
9384
3.46k
   (void)curveLoaded;
9385
3.46k
   wc_ecc_curve_free(curve);
9386
3.46k
   FREE_CURVE_SPECS();
9387
3.46k
#endif /* HAVE_ECC_VERIFY_HELPER */
9388
9389
3.46k
   (void)keySz;
9390
3.46k
   (void)hashlen;
9391
9392
3.46k
   return err;
9393
3.46k
#endif /* WOLFSSL_STM32_PKA */
9394
3.46k
}
9395
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
9396
#endif /* HAVE_ECC_VERIFY */
9397
9398
#ifdef HAVE_ECC_KEY_IMPORT
9399
/* import point from der
9400
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
9401
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
9402
                               const int curve_idx, ecc_point* point,
9403
                               int shortKeySize)
9404
79
{
9405
79
    int err = 0;
9406
79
#ifdef HAVE_COMP_KEY
9407
79
    int compressed = 0;
9408
79
#endif
9409
79
    int keysize;
9410
79
    byte pointType;
9411
9412
#ifndef HAVE_COMP_KEY
9413
    (void)shortKeySize;
9414
#endif
9415
9416
79
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9417
79
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9418
0
        return ECC_BAD_ARG_E;
9419
9420
    /* must be odd */
9421
79
    if ((inLen & 1) == 0) {
9422
0
        return ECC_BAD_ARG_E;
9423
0
    }
9424
9425
    /* clear if previously allocated */
9426
79
    mp_clear(point->x);
9427
79
    mp_clear(point->y);
9428
79
    mp_clear(point->z);
9429
9430
    /* init point */
9431
#ifdef ALT_ECC_SIZE
9432
    point->x = (mp_int*)&point->xyz[0];
9433
    point->y = (mp_int*)&point->xyz[1];
9434
    point->z = (mp_int*)&point->xyz[2];
9435
    alt_fp_init(point->x);
9436
    alt_fp_init(point->y);
9437
    alt_fp_init(point->z);
9438
#else
9439
79
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9440
79
#endif
9441
79
    if (err != MP_OKAY)
9442
0
        return MEMORY_E;
9443
9444
79
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9445
9446
    /* check for point type (4, 2, or 3) */
9447
79
    pointType = in[0];
9448
79
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9449
0
                                         pointType != ECC_POINT_COMP_ODD) {
9450
0
        err = ASN_PARSE_E;
9451
0
    }
9452
9453
79
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9454
0
#ifdef HAVE_COMP_KEY
9455
0
        compressed = 1;
9456
#else
9457
        err = NOT_COMPILED_IN;
9458
#endif
9459
0
    }
9460
9461
    /* adjust to skip first byte */
9462
79
    inLen -= 1;
9463
79
    in += 1;
9464
9465
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9466
     * is true */
9467
79
#ifdef HAVE_COMP_KEY
9468
79
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9469
#else
9470
    keysize = (int)(inLen>>1);
9471
#endif
9472
9473
    /* read data */
9474
79
    if (err == MP_OKAY)
9475
79
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9476
9477
79
#ifdef HAVE_COMP_KEY
9478
79
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9479
    #if defined(WOLFSSL_HAVE_SP_ECC)
9480
        #ifndef WOLFSSL_SP_NO_256
9481
        if (curve_idx != ECC_CUSTOM_IDX &&
9482
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
9483
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
9484
        }
9485
        else
9486
        #endif
9487
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9488
        if (curve_idx != ECC_CUSTOM_IDX &&
9489
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
9490
            sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
9491
        }
9492
        else
9493
        #endif
9494
        #ifdef WOLFSSL_SP_384
9495
        if (curve_idx != ECC_CUSTOM_IDX &&
9496
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
9497
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
9498
        }
9499
        else
9500
        #endif
9501
        #ifdef WOLFSSL_SP_521
9502
        if (curve_idx != ECC_CUSTOM_IDX &&
9503
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
9504
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
9505
        }
9506
        else
9507
        #endif
9508
    #endif
9509
0
    #if !defined(WOLFSSL_SP_MATH)
9510
0
        {
9511
0
            int did_init = 0;
9512
0
        #ifdef WOLFSSL_SMALL_STACK
9513
0
            mp_int* t1 = NULL;
9514
0
            mp_int* t2 = NULL;
9515
        #else
9516
            mp_int t1[1], t2[1];
9517
        #endif
9518
0
            DECLARE_CURVE_SPECS(3);
9519
9520
0
            ALLOC_CURVE_SPECS(3, err);
9521
9522
0
        #ifdef WOLFSSL_SMALL_STACK
9523
0
            if (err == MP_OKAY) {
9524
0
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9525
0
                                      DYNAMIC_TYPE_BIGINT);
9526
0
                if (t1 == NULL) {
9527
0
                    err = MEMORY_E;
9528
0
                }
9529
0
            }
9530
0
            if (err == MP_OKAY) {
9531
0
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9532
0
                                      DYNAMIC_TYPE_BIGINT);
9533
0
                if (t2 == NULL) {
9534
0
                    err = MEMORY_E;
9535
0
                }
9536
0
            }
9537
0
        #endif
9538
9539
0
            if (err == MP_OKAY) {
9540
0
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9541
0
                    err = MEMORY_E;
9542
0
                else
9543
0
                    did_init = 1;
9544
0
            }
9545
9546
            /* load curve info */
9547
0
            if (err == MP_OKAY)
9548
0
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9549
0
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9550
0
                        ECC_CURVE_FIELD_BF));
9551
9552
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
9553
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
9554
            /* validate prime is prime for custom curves */
9555
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
9556
                int isPrime = MP_NO;
9557
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
9558
                if (err == MP_OKAY && isPrime == MP_NO)
9559
                    err = MP_VAL;
9560
            }
9561
        #endif
9562
9563
            /* compute x^3 */
9564
0
            if (err == MP_OKAY)
9565
0
                err = mp_sqr(point->x, t1);
9566
0
            if (err == MP_OKAY)
9567
0
                err = mp_mulmod(t1, point->x, curve->prime, t1);
9568
9569
            /* compute x^3 + a*x */
9570
0
            if (err == MP_OKAY)
9571
0
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
9572
0
            if (err == MP_OKAY)
9573
0
                err = mp_add(t1, t2, t1);
9574
9575
            /* compute x^3 + a*x + b */
9576
0
            if (err == MP_OKAY)
9577
0
                err = mp_add(t1, curve->Bf, t1);
9578
9579
            /* compute sqrt(x^3 + a*x + b) */
9580
0
            if (err == MP_OKAY)
9581
0
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
9582
9583
            /* adjust y */
9584
0
            if (err == MP_OKAY) {
9585
0
                if ((mp_isodd(t2) == MP_YES &&
9586
0
                                            pointType == ECC_POINT_COMP_ODD) ||
9587
0
                    (mp_isodd(t2) == MP_NO &&
9588
0
                                            pointType == ECC_POINT_COMP_EVEN)) {
9589
0
                    err = mp_mod(t2, curve->prime, point->y);
9590
0
                }
9591
0
                else {
9592
0
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
9593
0
                }
9594
0
            }
9595
9596
0
            if (did_init) {
9597
0
                mp_clear(t2);
9598
0
                mp_clear(t1);
9599
0
            }
9600
9601
0
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
9602
0
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
9603
9604
0
            wc_ecc_curve_free(curve);
9605
0
            FREE_CURVE_SPECS();
9606
0
        }
9607
    #else
9608
        {
9609
            err = WC_KEY_SIZE_E;
9610
        }
9611
    #endif
9612
0
    }
9613
79
#endif
9614
9615
79
    if (err == MP_OKAY) {
9616
79
#ifdef HAVE_COMP_KEY
9617
79
        if (compressed == 0)
9618
79
#endif
9619
79
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9620
79
    }
9621
79
    if (err == MP_OKAY)
9622
79
        err = mp_set(point->z, 1);
9623
9624
79
    if (err != MP_OKAY) {
9625
0
        mp_clear(point->x);
9626
0
        mp_clear(point->y);
9627
0
        mp_clear(point->z);
9628
0
    }
9629
9630
79
    RESTORE_VECTOR_REGISTERS();
9631
9632
79
    return err;
9633
79
}
9634
9635
/* function for backwards compatibility with previous implementations */
9636
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
9637
                            ecc_point* point)
9638
124
{
9639
124
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9640
124
}
9641
#endif /* HAVE_ECC_KEY_IMPORT */
9642
9643
#ifdef HAVE_ECC_KEY_EXPORT
9644
/* export point to der */
9645
9646
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
9647
                               word32* outLen, int compressed)
9648
0
{
9649
0
    if (compressed == 0)
9650
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
9651
0
#ifdef HAVE_COMP_KEY
9652
0
    else
9653
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
9654
#else
9655
    return NOT_COMPILED_IN;
9656
#endif
9657
0
}
9658
9659
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
9660
                            word32* outLen)
9661
348
{
9662
348
    int    ret = MP_OKAY;
9663
348
    word32 numlen;
9664
348
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9665
9666
348
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9667
0
        return ECC_BAD_ARG_E;
9668
9669
348
    numlen = (word32)ecc_sets[curve_idx].size;
9670
9671
    /* return length needed only */
9672
348
    if (point != NULL && out == NULL && outLen != NULL) {
9673
28
        *outLen = 1 + 2*numlen;
9674
28
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9675
28
    }
9676
9677
320
    if (point == NULL || out == NULL || outLen == NULL)
9678
0
        return ECC_BAD_ARG_E;
9679
9680
320
    if (*outLen < (1 + 2*numlen)) {
9681
17
        *outLen = 1 + 2*numlen;
9682
17
        return BUFFER_E;
9683
17
    }
9684
9685
    /* Sanity check the ordinates' sizes. */
9686
303
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9687
272
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9688
83
        return ECC_BAD_ARG_E;
9689
83
    }
9690
9691
    /* store byte point type */
9692
220
    out[0] = ECC_POINT_UNCOMP;
9693
9694
220
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9695
220
        return MEMORY_E);
9696
9697
    /* pad and store x */
9698
140
    XMEMSET(buf, 0, ECC_BUFSIZE);
9699
140
    ret = mp_to_unsigned_bin(point->x, buf +
9700
140
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9701
140
    if (ret != MP_OKAY)
9702
8
        goto done;
9703
132
    XMEMCPY(out+1, buf, numlen);
9704
9705
    /* pad and store y */
9706
132
    XMEMSET(buf, 0, ECC_BUFSIZE);
9707
132
    ret = mp_to_unsigned_bin(point->y, buf +
9708
132
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9709
132
    if (ret != MP_OKAY)
9710
8
        goto done;
9711
124
    XMEMCPY(out+1+numlen, buf, numlen);
9712
9713
124
    *outLen = 1 + 2*numlen;
9714
9715
140
done:
9716
140
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9717
9718
140
    return ret;
9719
124
}
9720
9721
9722
/* export point to der */
9723
#ifdef HAVE_COMP_KEY
9724
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
9725
                                       byte* out, word32* outLen)
9726
0
{
9727
0
    int    ret = MP_OKAY;
9728
0
    word32 numlen;
9729
0
    word32 output_len;
9730
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9731
9732
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9733
0
        return ECC_BAD_ARG_E;
9734
9735
0
    numlen = (word32)ecc_sets[curve_idx].size;
9736
0
    output_len = 1 + numlen; /* y point type + x */
9737
9738
    /* return length needed only */
9739
0
    if (point != NULL && out == NULL && outLen != NULL) {
9740
0
        *outLen = output_len;
9741
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9742
0
    }
9743
9744
0
    if (point == NULL || out == NULL || outLen == NULL)
9745
0
        return ECC_BAD_ARG_E;
9746
9747
9748
0
    if (*outLen < output_len) {
9749
0
        *outLen = output_len;
9750
0
        return BUFFER_E;
9751
0
    }
9752
9753
    /* Sanity check the ordinate's size. */
9754
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
9755
0
        return ECC_BAD_ARG_E;
9756
0
    }
9757
9758
    /* store byte point type */
9759
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
9760
0
                                            ECC_POINT_COMP_EVEN;
9761
9762
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9763
0
        return MEMORY_E);
9764
9765
    /* pad and store x */
9766
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9767
0
    ret = mp_to_unsigned_bin(point->x, buf +
9768
0
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
9769
0
    if (ret != MP_OKAY)
9770
0
        goto done;
9771
0
    XMEMCPY(out+1, buf, numlen);
9772
9773
0
    *outLen = output_len;
9774
9775
0
done:
9776
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9777
9778
0
    return ret;
9779
0
}
9780
#endif /* HAVE_COMP_KEY */
9781
9782
/* export public ECC key in ANSI X9.63 format */
9783
WOLFSSL_ABI
9784
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
9785
12.7k
{
9786
12.7k
   int    ret = MP_OKAY;
9787
12.7k
   word32 numlen;
9788
12.7k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9789
12.7k
   word32 pubxlen, pubylen;
9790
9791
   /* return length needed only */
9792
12.7k
   if (key != NULL && out == NULL && outLen != NULL) {
9793
      /* if key hasn't been setup assume max bytes for size estimation */
9794
1.91k
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9795
1.91k
      *outLen = 1 + 2 * numlen;
9796
1.91k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9797
1.91k
   }
9798
9799
10.7k
   if (key == NULL || out == NULL || outLen == NULL)
9800
0
      return ECC_BAD_ARG_E;
9801
9802
10.7k
   if (key->type == ECC_PRIVATEKEY_ONLY)
9803
158
       return ECC_PRIVATEONLY_E;
9804
9805
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
9806
    /* check if public key in secure memory */
9807
    if (key->securePubKey > 0) {
9808
        int keySz = wc_ecc_size(key);
9809
9810
        /* store byte point type */
9811
        out[0] = ECC_POINT_UNCOMP;
9812
9813
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
9814
            return WC_HW_E;
9815
9816
        *outLen = 1 + 2*keySz;
9817
        return MP_OKAY;
9818
    }
9819
#endif
9820
9821
10.6k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9822
1.28k
       return ECC_BAD_ARG_E;
9823
1.28k
   }
9824
9825
9.35k
   numlen = (word32)key->dp->size;
9826
9827
    /* verify room in out buffer */
9828
9.35k
   if (*outLen < (1 + 2*numlen)) {
9829
0
      *outLen = 1 + 2*numlen;
9830
0
      return BUFFER_E;
9831
0
   }
9832
9833
   /* verify public key length is less than key size */
9834
9.35k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9835
9.35k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9836
9.35k
   if ((pubxlen > numlen) || (pubylen > numlen)) {
9837
0
      WOLFSSL_MSG("Public key x/y invalid!");
9838
0
      return BUFFER_E;
9839
0
   }
9840
9841
   /* store byte point type */
9842
9.35k
   out[0] = ECC_POINT_UNCOMP;
9843
9844
9.35k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9845
9.35k
       return MEMORY_E);
9846
9847
   /* pad and store x */
9848
9.28k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9849
9.28k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9850
9.28k
   if (ret != MP_OKAY)
9851
7
      goto done;
9852
9.27k
   XMEMCPY(out+1, buf, numlen);
9853
9854
   /* pad and store y */
9855
9.27k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9856
9.27k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9857
9.27k
   if (ret != MP_OKAY)
9858
10
      goto done;
9859
9.26k
   XMEMCPY(out+1+numlen, buf, numlen);
9860
9861
9.26k
   *outLen = 1 + 2*numlen;
9862
9863
9.28k
done:
9864
9.28k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9865
9866
9.28k
   return ret;
9867
9.26k
}
9868
9869
9870
/* export public ECC key in ANSI X9.63 format, extended with
9871
 * compression option */
9872
WOLFSSL_ABI
9873
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
9874
                          int compressed)
9875
7.56k
{
9876
7.56k
    if (compressed == 0)
9877
4.03k
        return wc_ecc_export_x963(key, out, outLen);
9878
3.52k
#ifdef HAVE_COMP_KEY
9879
3.52k
    else
9880
3.52k
        return wc_ecc_export_x963_compressed(key, out, outLen);
9881
#else
9882
    return NOT_COMPILED_IN;
9883
#endif
9884
7.56k
}
9885
#endif /* HAVE_ECC_KEY_EXPORT */
9886
9887
9888
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
9889
9890
/* is ecc point on curve described by dp ? */
9891
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
9892
3.35k
{
9893
3.35k
#if !defined(WOLFSSL_SP_MATH)
9894
3.35k
   int err;
9895
3.35k
#ifdef WOLFSSL_SMALL_STACK
9896
3.35k
   mp_int* t1;
9897
3.35k
   mp_int* t2;
9898
#else
9899
   mp_int  t1[1], t2[1];
9900
#endif
9901
9902
3.35k
#ifdef WOLFSSL_SMALL_STACK
9903
3.35k
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9904
3.35k
   if (t1 == NULL)
9905
75
       return MEMORY_E;
9906
3.27k
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9907
3.27k
   if (t2 == NULL) {
9908
52
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9909
52
       return MEMORY_E;
9910
52
   }
9911
3.22k
#endif
9912
9913
3.22k
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
9914
0
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9915
0
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9916
0
      return err;
9917
0
   }
9918
9919
3.22k
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9920
9921
   /* compute y^2 */
9922
3.22k
   if (err == MP_OKAY)
9923
3.22k
       err = mp_sqr(ecp->y, t1);
9924
9925
   /* compute x^3 */
9926
3.22k
   if (err == MP_OKAY)
9927
3.20k
       err = mp_sqr(ecp->x, t2);
9928
3.22k
   if (err == MP_OKAY)
9929
3.17k
       err = mp_mod(t2, prime, t2);
9930
3.22k
   if (err == MP_OKAY)
9931
3.17k
       err = mp_mul(ecp->x, t2, t2);
9932
9933
   /* compute y^2 - x^3 */
9934
3.22k
   if (err == MP_OKAY)
9935
3.15k
       err = mp_submod(t1, t2, prime, t1);
9936
9937
   /* Determine if curve "a" should be used in calc */
9938
3.22k
#ifdef WOLFSSL_CUSTOM_CURVES
9939
3.22k
   if (err == MP_OKAY) {
9940
      /* Use a and prime to determine if a == 3 */
9941
3.08k
      err = mp_set(t2, 0);
9942
3.08k
      if (err == MP_OKAY)
9943
3.08k
          err = mp_submod(prime, a, prime, t2);
9944
3.08k
   }
9945
3.22k
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
9946
      /* compute y^2 - x^3 + a*x */
9947
1.54k
      if (err == MP_OKAY)
9948
1.54k
          err = mp_mulmod(t2, ecp->x, prime, t2);
9949
1.54k
      if (err == MP_OKAY)
9950
1.54k
          err = mp_addmod(t1, t2, prime, t1);
9951
1.54k
   }
9952
1.67k
   else
9953
1.67k
#endif /* WOLFSSL_CUSTOM_CURVES */
9954
1.67k
   {
9955
      /* assumes "a" == 3 */
9956
1.67k
      (void)a;
9957
9958
      /* compute y^2 - x^3 + 3x */
9959
1.67k
      if (err == MP_OKAY)
9960
1.53k
          err = mp_add(t1, ecp->x, t1);
9961
1.67k
      if (err == MP_OKAY)
9962
1.53k
          err = mp_add(t1, ecp->x, t1);
9963
1.67k
      if (err == MP_OKAY)
9964
1.53k
          err = mp_add(t1, ecp->x, t1);
9965
1.67k
      if (err == MP_OKAY)
9966
1.53k
          err = mp_mod(t1, prime, t1);
9967
1.67k
  }
9968
9969
   /* adjust range (0, prime) */
9970
3.22k
   while (err == MP_OKAY && mp_isneg(t1)) {
9971
0
      err = mp_add(t1, prime, t1);
9972
0
   }
9973
3.22k
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
9974
0
      err = mp_sub(t1, prime, t1);
9975
0
   }
9976
9977
   /* compare to b */
9978
3.22k
   if (err == MP_OKAY) {
9979
3.07k
       if (mp_cmp(t1, b) != MP_EQ) {
9980
1.34k
          err = IS_POINT_E;
9981
1.72k
       } else {
9982
1.72k
          err = MP_OKAY;
9983
1.72k
       }
9984
3.07k
   }
9985
9986
3.22k
   mp_clear(t1);
9987
3.22k
   mp_clear(t2);
9988
9989
3.22k
   RESTORE_VECTOR_REGISTERS();
9990
9991
3.22k
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9992
3.22k
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9993
9994
3.22k
   return err;
9995
#else
9996
   (void)a;
9997
   (void)b;
9998
9999
#ifdef WOLFSSL_HAVE_SP_ECC
10000
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10001
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10002
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10003
   }
10004
#endif
10005
#ifndef WOLFSSL_SP_NO_256
10006
   if (mp_count_bits(prime) == 256) {
10007
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10008
   }
10009
#endif
10010
#ifdef WOLFSSL_SP_384
10011
   if (mp_count_bits(prime) == 384) {
10012
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10013
   }
10014
#endif
10015
#ifdef WOLFSSL_SP_521
10016
   if (mp_count_bits(prime) == 521) {
10017
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10018
   }
10019
#endif
10020
#else
10021
   (void)ecp;
10022
   (void)prime;
10023
#endif
10024
   return WC_KEY_SIZE_E;
10025
#endif
10026
3.22k
}
10027
10028
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10029
5.22k
{
10030
5.22k
    int err = MP_OKAY;
10031
10032
    /* Validate parameters. */
10033
5.22k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10034
0
        err = BAD_FUNC_ARG;
10035
0
    }
10036
10037
5.22k
    if (err == MP_OKAY) {
10038
        /* x must be in the range [0, p-1] */
10039
5.22k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10040
147
            err = ECC_OUT_OF_RANGE_E;
10041
147
        }
10042
5.22k
    }
10043
10044
5.22k
    if (err == MP_OKAY) {
10045
        /* y must be in the range [0, p-1] */
10046
5.07k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10047
155
            err = ECC_OUT_OF_RANGE_E;
10048
155
        }
10049
5.07k
    }
10050
10051
5.22k
    if (err == MP_OKAY) {
10052
        /* z must be one, that is point must be in affine form. */
10053
4.92k
        if (!mp_isone(ecp->z)) {
10054
1.04k
            err = ECC_BAD_ARG_E;
10055
1.04k
        }
10056
4.92k
    }
10057
10058
5.22k
    if (err == MP_OKAY) {
10059
        /* Check x and y are valid for curve equation. */
10060
3.88k
        err = _ecc_is_point(ecp, a, b, prime);
10061
3.88k
    }
10062
10063
5.22k
    return err;
10064
5.22k
}
10065
10066
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10067
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10068
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10069
/* validate privkey * generator == pubkey, 0 on success */
10070
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10071
{
10072
    int        err;
10073
    ecc_point* base = NULL;
10074
    ecc_point* res  = NULL;
10075
#ifdef WOLFSSL_NO_MALLOC
10076
    ecc_point lcl_base;
10077
    ecc_point lcl_res;
10078
#endif
10079
    DECLARE_CURVE_SPECS(3);
10080
10081
    if (key == NULL)
10082
        return BAD_FUNC_ARG;
10083
10084
    ALLOC_CURVE_SPECS(3, err);
10085
    if (err != MP_OKAY) {
10086
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10087
        return err;
10088
    }
10089
10090
#ifdef WOLFSSL_NO_MALLOC
10091
    res = &lcl_res;
10092
#endif
10093
    err = wc_ecc_new_point_ex(&res, key->heap);
10094
10095
#ifdef WOLFSSL_HAVE_SP_ECC
10096
#ifndef WOLFSSL_SP_NO_256
10097
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10098
        if (err == MP_OKAY) {
10099
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10100
        }
10101
    }
10102
    else
10103
#endif
10104
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10105
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10106
        if (err == MP_OKAY) {
10107
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10108
        }
10109
    }
10110
    else
10111
#endif
10112
#ifdef WOLFSSL_SP_384
10113
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10114
        if (err == MP_OKAY) {
10115
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10116
        }
10117
    }
10118
    else
10119
#endif
10120
#ifdef WOLFSSL_SP_521
10121
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10122
        if (err == MP_OKAY) {
10123
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10124
        }
10125
    }
10126
    else
10127
#endif
10128
#endif
10129
    {
10130
        if (err == MP_OKAY) {
10131
        #ifdef WOLFSSL_NO_MALLOC
10132
            base = &lcl_base;
10133
        #endif
10134
            err = wc_ecc_new_point_ex(&base, key->heap);
10135
        }
10136
10137
        if (err == MP_OKAY) {
10138
            /* load curve info */
10139
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10140
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10141
        }
10142
10143
        /* set up base generator */
10144
        if (err == MP_OKAY)
10145
            err = mp_copy(curve->Gx, base->x);
10146
        if (err == MP_OKAY)
10147
            err = mp_copy(curve->Gy, base->y);
10148
        if (err == MP_OKAY)
10149
            err = mp_set(base->z, 1);
10150
10151
#ifdef WOLFSSL_KCAPI_ECC
10152
        if (err == MP_OKAY) {
10153
            word32 pubkey_sz = (word32)key->dp->size*2;
10154
            if (key->handle == NULL) {
10155
                /* if handle loaded, then pubkey_raw already populated */
10156
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10157
            }
10158
            if (err == 0) {
10159
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10160
                                           pubkey_sz/2);
10161
            }
10162
            if (err == MP_OKAY) {
10163
                err = mp_read_unsigned_bin(res->y,
10164
                                           key->pubkey_raw + pubkey_sz/2,
10165
                                           pubkey_sz/2);
10166
            }
10167
            if (err == MP_OKAY) {
10168
                err = mp_set(res->z, 1);
10169
            }
10170
        }
10171
        (void)a;
10172
        (void)prime;
10173
#else
10174
#ifdef ECC_TIMING_RESISTANT
10175
        if (err == MP_OKAY)
10176
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10177
                                          curve->order, key->rng, 1, key->heap);
10178
#else
10179
        if (err == MP_OKAY)
10180
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10181
                                              curve->order, NULL, 1, key->heap);
10182
#endif
10183
#endif /* WOLFSSL_KCAPI_ECC */
10184
    }
10185
10186
    if (err == MP_OKAY) {
10187
        /* compare result to public key */
10188
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10189
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10190
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10191
            /* didn't match */
10192
            err = ECC_PRIV_KEY_E;
10193
        }
10194
    }
10195
10196
    wc_ecc_curve_free(curve);
10197
    wc_ecc_del_point_ex(res, key->heap);
10198
    wc_ecc_del_point_ex(base, key->heap);
10199
    FREE_CURVE_SPECS();
10200
10201
    return err;
10202
}
10203
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10204
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10205
10206
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10207
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10208
10209
/* check privkey generator helper, creates prime needed */
10210
static int ecc_check_privkey_gen_helper(ecc_key* key)
10211
{
10212
    int    err;
10213
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
10214
    DECLARE_CURVE_SPECS(2);
10215
#endif
10216
10217
    if (key == NULL)
10218
        return BAD_FUNC_ARG;
10219
10220
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10221
    /* Hardware based private key, so this operation is not supported */
10222
    err = MP_OKAY; /* just report success */
10223
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10224
    /* Hardware based private key, so this operation is not supported */
10225
    err = MP_OKAY; /* just report success */
10226
#elif defined(WOLFSSL_KCAPI_ECC)
10227
    /* Hardware based private key, so this operation is not supported */
10228
    err = MP_OKAY; /* just report success */
10229
#else
10230
    ALLOC_CURVE_SPECS(2, err);
10231
10232
    /* load curve info */
10233
    if (err == MP_OKAY)
10234
        err = wc_ecc_curve_load(key->dp, &curve,
10235
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10236
10237
    if (err == MP_OKAY)
10238
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10239
10240
    wc_ecc_curve_free(curve);
10241
    FREE_CURVE_SPECS();
10242
10243
#endif /* WOLFSSL_ATECC508A */
10244
10245
    return err;
10246
}
10247
10248
/* Performs a Pairwise Consistency Test on an ECC key pair. */
10249
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10250
{
10251
    int err = 0;
10252
    word32 flags = key->flags;
10253
10254
    /* If flags not set default to cofactor and dec/sign */
10255
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10256
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10257
    }
10258
10259
    if (flags & WC_ECC_FLAG_COFACTOR) {
10260
        err = ecc_check_privkey_gen_helper(key);
10261
    }
10262
10263
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10264
#ifndef WOLFSSL_SMALL_STACK
10265
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10266
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10267
#else
10268
        byte* sig;
10269
#endif
10270
        byte* digest;
10271
        word32 sigLen, digestLen;
10272
        int dynRng = 0, res = 0;
10273
10274
        sigLen = (word32)wc_ecc_sig_size(key);
10275
        digestLen = WC_SHA256_DIGEST_SIZE;
10276
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
10277
            DYNAMIC_TYPE_ECC, return MEMORY_E);
10278
        digest = sig + sigLen;
10279
10280
        if (rng == NULL) {
10281
            dynRng = 1;
10282
            rng = wc_rng_new(NULL, 0, key->heap);
10283
            if (rng == NULL) {
10284
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10285
                return MEMORY_E;
10286
            }
10287
        }
10288
10289
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10290
10291
        if (!err)
10292
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10293
                    rng, key);
10294
        if (!err)
10295
            err = wc_ecc_verify_hash(sig, sigLen,
10296
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10297
10298
        if (res == 0)
10299
            err = ECC_PCT_E;
10300
10301
        if (dynRng) {
10302
            wc_rng_free(rng);
10303
        }
10304
        ForceZero(sig, sigLen + digestLen);
10305
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10306
    }
10307
    (void)rng;
10308
10309
    if (err != 0)
10310
        err = ECC_PCT_E;
10311
10312
    return err;
10313
}
10314
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10315
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10316
10317
#ifndef WOLFSSL_SP_MATH
10318
/* validate order * pubkey = point at infinity, 0 on success */
10319
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10320
        mp_int* prime, mp_int* order)
10321
5.99k
{
10322
5.99k
    ecc_point* inf = NULL;
10323
#ifdef WOLFSSL_NO_MALLOC
10324
    ecc_point  lcl_inf;
10325
#endif
10326
5.99k
    int err;
10327
10328
5.99k
    if (key == NULL)
10329
0
        return BAD_FUNC_ARG;
10330
5.99k
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10331
5.99k
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10332
5.99k
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10333
0
       return IS_POINT_E;
10334
0
   }
10335
10336
#ifdef WOLFSSL_NO_MALLOC
10337
    inf = &lcl_inf;
10338
#endif
10339
5.99k
    err = wc_ecc_new_point_ex(&inf, key->heap);
10340
5.99k
    if (err == MP_OKAY) {
10341
#ifdef WOLFSSL_HAVE_SP_ECC
10342
#ifndef WOLFSSL_SP_NO_256
10343
        if (key->idx != ECC_CUSTOM_IDX &&
10344
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
10345
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
10346
        }
10347
        else
10348
#endif
10349
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10350
        if (key->idx != ECC_CUSTOM_IDX &&
10351
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
10352
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
10353
        }
10354
        else
10355
#endif
10356
#ifdef WOLFSSL_SP_384
10357
        if (key->idx != ECC_CUSTOM_IDX &&
10358
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
10359
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
10360
        }
10361
        else
10362
#endif
10363
#ifdef WOLFSSL_SP_521
10364
        if (key->idx != ECC_CUSTOM_IDX &&
10365
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
10366
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
10367
        }
10368
        else
10369
#endif
10370
#endif
10371
5.97k
#if !defined(WOLFSSL_SP_MATH)
10372
5.97k
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10373
5.97k
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10374
23
            err = ECC_INF_E;
10375
#else
10376
        {
10377
            (void)a;
10378
            (void)prime;
10379
10380
            err = WC_KEY_SIZE_E;
10381
        }
10382
#endif
10383
5.97k
    }
10384
10385
5.99k
    wc_ecc_del_point_ex(inf, key->heap);
10386
10387
5.99k
    return err;
10388
5.99k
}
10389
#endif /* !WOLFSSL_SP_MATH */
10390
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10391
10392
10393
#ifdef OPENSSL_EXTRA
10394
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
10395
{
10396
    int err = MP_OKAY;
10397
    DECLARE_CURVE_SPECS(2);
10398
10399
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
10400
        return BAD_FUNC_ARG;
10401
10402
    ALLOC_CURVE_SPECS(2, err);
10403
10404
    if (err == MP_OKAY)
10405
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10406
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
10407
    if (err == MP_OKAY)
10408
        err = mp_copy(curve->Gx, ecp->x);
10409
    if (err == MP_OKAY)
10410
        err = mp_copy(curve->Gy, ecp->y);
10411
    if (err == MP_OKAY)
10412
        err = mp_set(ecp->z, 1);
10413
10414
    wc_ecc_curve_free(curve);
10415
    FREE_CURVE_SPECS();
10416
10417
    return err;
10418
}
10419
#endif /* OPENSSL_EXTRA */
10420
10421
10422
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
10423
 * ECC Full Public Key Validation Routine. If the parameter
10424
 * partial is set, then it follows section 5.6.2.3.4, the ECC
10425
 * Partial Public Key Validation Routine.
10426
 * If the parameter priv is set, add in a few extra
10427
 * checks on the bounds of the private key. */
10428
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
10429
2.34k
{
10430
2.34k
    int err = MP_OKAY;
10431
2.34k
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10432
2.34k
    mp_int* b = NULL;
10433
2.34k
    #ifdef USE_ECC_B_PARAM
10434
2.34k
        DECLARE_CURVE_SPECS(4);
10435
    #else
10436
        #ifndef WOLFSSL_SMALL_STACK
10437
            mp_int b_lcl;
10438
        #endif
10439
        DECLARE_CURVE_SPECS(3);
10440
    #endif /* USE_ECC_B_PARAM */
10441
2.34k
#endif
10442
10443
2.34k
    ASSERT_SAVED_VECTOR_REGISTERS();
10444
10445
2.34k
    if (key == NULL)
10446
0
        return BAD_FUNC_ARG;
10447
10448
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
10449
    /* consider key check success on HW crypto
10450
     * ex: ATECC508/608A, CryptoCell and Silabs
10451
     *
10452
     * consider key check success on most Crypt Cb only builds
10453
     */
10454
    err = MP_OKAY;
10455
10456
#else
10457
10458
#ifdef WOLFSSL_HAVE_SP_ECC
10459
#ifndef WOLFSSL_SP_NO_256
10460
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10461
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10462
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10463
    }
10464
#endif
10465
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10466
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10467
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10468
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10469
    }
10470
#endif
10471
#ifdef WOLFSSL_SP_384
10472
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10473
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10474
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10475
    }
10476
#endif
10477
#ifdef WOLFSSL_SP_521
10478
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10479
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10480
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10481
    }
10482
#endif
10483
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
10484
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
10485
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
10486
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10487
    }
10488
#endif
10489
#endif
10490
10491
2.34k
#ifndef WOLFSSL_SP_MATH
10492
2.34k
    #ifdef USE_ECC_B_PARAM
10493
2.34k
        ALLOC_CURVE_SPECS(4, err);
10494
    #else
10495
        ALLOC_CURVE_SPECS(3, err);
10496
        #ifndef WOLFSSL_SMALL_STACK
10497
            b = &b_lcl;
10498
        #else
10499
            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10500
            if (b == NULL) {
10501
                FREE_CURVE_SPECS();
10502
                return MEMORY_E;
10503
            }
10504
        #endif
10505
        XMEMSET(b, 0, sizeof(mp_int));
10506
    #endif
10507
10508
    #ifdef WOLFSSL_CAAM
10509
    /* keys can be black encrypted ones which can not be checked like plain text
10510
     * keys */
10511
    if (key->blackKey > 0) {
10512
        /* encrypted key was used */
10513
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10514
        FREE_CURVE_SPECS();
10515
        return 0;
10516
    }
10517
    #endif
10518
10519
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
10520
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
10521
    /* pubkey point cannot be at infinity */
10522
2.34k
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10523
0
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10524
0
        FREE_CURVE_SPECS();
10525
0
        return ECC_INF_E;
10526
0
    }
10527
10528
    /* load curve info */
10529
2.34k
    if (err == MP_OKAY)
10530
2.19k
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10531
2.19k
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10532
2.19k
#ifdef USE_ECC_B_PARAM
10533
2.19k
            | ECC_CURVE_FIELD_BF
10534
2.19k
#endif
10535
2.19k
    ));
10536
10537
#ifndef USE_ECC_B_PARAM
10538
    /* load curve b parameter */
10539
    if (err == MP_OKAY)
10540
        err = mp_init(b);
10541
    if (err == MP_OKAY)
10542
        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
10543
#else
10544
2.34k
    if (err == MP_OKAY)
10545
2.19k
        b = curve->Bf;
10546
2.34k
#endif
10547
10548
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
10549
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
10550
    /* Qx must be in the range [0, p-1] */
10551
2.34k
    if (err == MP_OKAY) {
10552
2.19k
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10553
2.18k
                mp_isneg(key->pubkey.x)) {
10554
11
            err = ECC_OUT_OF_RANGE_E;
10555
11
        }
10556
2.19k
    }
10557
10558
    /* Qy must be in the range [0, p-1] */
10559
2.34k
    if (err == MP_OKAY) {
10560
2.18k
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10561
2.17k
                mp_isneg(key->pubkey.y)) {
10562
10
            err = ECC_OUT_OF_RANGE_E;
10563
10
        }
10564
2.18k
    }
10565
10566
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
10567
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
10568
    /* make sure point is actually on curve */
10569
2.34k
    if (err == MP_OKAY)
10570
2.17k
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10571
10572
2.34k
    if (!partial) {
10573
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10574
        /* pubkey * order must be at infinity */
10575
2.34k
        if (err == MP_OKAY)
10576
1.43k
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10577
1.43k
                    curve->prime, curve->order);
10578
2.34k
    }
10579
10580
2.34k
    if (priv) {
10581
        /* SP 800-56Ar3, section 5.6.2.1.2 */
10582
        /* private keys must be in the range [1, n-1] */
10583
2.34k
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10584
306
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10585
306
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10586
        #ifdef WOLFSSL_KCAPI_ECC
10587
            && key->handle == NULL
10588
        #endif
10589
2.34k
        ) {
10590
0
            err = ECC_PRIV_KEY_E;
10591
0
        }
10592
10593
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
10594
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
10595
        /* private * base generator must equal pubkey */
10596
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
10597
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10598
    #endif
10599
2.34k
    }
10600
10601
2.34k
    wc_ecc_curve_free(curve);
10602
10603
#ifndef USE_ECC_B_PARAM
10604
    mp_clear(b);
10605
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10606
#endif
10607
10608
2.34k
    FREE_CURVE_SPECS();
10609
10610
#else
10611
    /* The single precision math curve is not available */
10612
    err = WC_KEY_SIZE_E;
10613
#endif /* !WOLFSSL_SP_MATH */
10614
2.34k
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10615
10616
2.34k
    (void)partial;
10617
2.34k
    (void)priv;
10618
2.34k
    return err;
10619
2.34k
}
10620
10621
10622
/* perform sanity checks on ecc key validity, 0 on success */
10623
WOLFSSL_ABI
10624
int wc_ecc_check_key(ecc_key* key)
10625
14.0k
{
10626
14.0k
    int ret;
10627
14.0k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10628
14.0k
    ret = _ecc_validate_public_key(key, 0, 1);
10629
14.0k
    RESTORE_VECTOR_REGISTERS();
10630
14.0k
    return ret;
10631
14.0k
}
10632
10633
10634
#ifdef HAVE_ECC_KEY_IMPORT
10635
/* import public ECC key in ANSI X9.63 format */
10636
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
10637
                          int curve_id)
10638
6.78k
{
10639
6.78k
    int err = MP_OKAY;
10640
6.78k
#ifdef HAVE_COMP_KEY
10641
6.78k
    int compressed = 0;
10642
6.78k
#endif
10643
6.78k
    int keysize = 0;
10644
6.78k
    byte pointType;
10645
#ifdef WOLFSSL_CRYPTOCELL
10646
    const CRYS_ECPKI_Domain_t* pDomain;
10647
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10648
#endif
10649
6.78k
    if (in == NULL || key == NULL)
10650
0
        return BAD_FUNC_ARG;
10651
10652
    /* must be odd */
10653
6.78k
    if ((inLen & 1) == 0) {
10654
42
        return ECC_BAD_ARG_E;
10655
42
    }
10656
10657
    /* make sure required variables are reset */
10658
6.74k
    wc_ecc_reset(key);
10659
10660
    /* init key */
10661
    #ifdef ALT_ECC_SIZE
10662
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10663
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10664
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10665
        alt_fp_init(key->pubkey.x);
10666
        alt_fp_init(key->pubkey.y);
10667
        alt_fp_init(key->pubkey.z);
10668
        key->k = (mp_int*)key->ka;
10669
        alt_fp_init(key->k);
10670
    #ifdef WOLFSSL_ECC_BLIND_K
10671
        key->kb = (mp_int*)key->kba;
10672
        key->ku = (mp_int*)key->kua;
10673
        alt_fp_init(key->kb);
10674
        alt_fp_init(key->ku);
10675
    #endif
10676
    #else
10677
6.74k
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10678
6.74k
    #ifndef WOLFSSL_ECC_BLIND_K
10679
6.74k
                                                                      NULL, NULL
10680
    #else
10681
                                                                key->kb, key->ku
10682
    #endif
10683
6.74k
                            );
10684
6.74k
    #endif
10685
6.74k
    if (err != MP_OKAY)
10686
0
        return MEMORY_E;
10687
#ifdef WOLFSSL_ECC_BLIND_K
10688
    mp_forcezero(key->kb);
10689
#endif
10690
10691
6.74k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10692
10693
    /* check for point type (4, 2, or 3) */
10694
6.74k
    pointType = in[0];
10695
6.74k
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10696
1.78k
                                         pointType != ECC_POINT_COMP_ODD) {
10697
222
        err = ASN_PARSE_E;
10698
222
    }
10699
10700
6.74k
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10701
4.28k
    #ifdef HAVE_COMP_KEY
10702
4.28k
        compressed = 1;
10703
    #else
10704
        err = NOT_COMPILED_IN;
10705
    #endif
10706
4.28k
    }
10707
10708
    /* adjust to skip first byte */
10709
6.74k
    inLen -= 1;
10710
6.74k
    in += 1;
10711
10712
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10713
    /* For SECP256R1 only save raw public key for hardware */
10714
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
10715
    #ifdef HAVE_COMP_KEY
10716
        if (!compressed)
10717
    #endif
10718
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10719
    }
10720
#elif defined(WOLFSSL_KCAPI_ECC)
10721
    XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10722
#endif
10723
10724
6.74k
    if (err == MP_OKAY) {
10725
6.51k
    #ifdef HAVE_COMP_KEY
10726
        /* adjust inLen if compressed */
10727
6.51k
        if (compressed)
10728
4.28k
            inLen = inLen*2 + 1;  /* used uncompressed len */
10729
6.51k
    #endif
10730
10731
        /* determine key size */
10732
6.51k
        keysize = (int)(inLen>>1);
10733
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
10734
         *       on created keys or signatures */
10735
6.51k
        err = wc_ecc_set_curve(key, keysize, curve_id);
10736
6.51k
        key->type = ECC_PUBLICKEY;
10737
6.51k
    }
10738
10739
    /* read data */
10740
6.74k
    if (err == MP_OKAY)
10741
6.50k
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10742
10743
6.74k
#ifdef HAVE_COMP_KEY
10744
6.74k
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10745
4.27k
#if !defined(WOLFSSL_SP_MATH)
10746
4.27k
    #ifdef WOLFSSL_SMALL_STACK
10747
4.27k
        mp_int* t1 = NULL;
10748
4.27k
        mp_int* t2 = NULL;
10749
    #else
10750
        mp_int t1[1], t2[1];
10751
    #endif
10752
4.27k
        int did_init = 0;
10753
10754
4.27k
        DECLARE_CURVE_SPECS(3);
10755
4.27k
        ALLOC_CURVE_SPECS(3, err);
10756
10757
4.27k
        #ifdef WOLFSSL_SMALL_STACK
10758
4.27k
        if (err == MP_OKAY) {
10759
4.19k
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10760
4.19k
            if (t1 == NULL) {
10761
48
                err = MEMORY_E;
10762
48
            }
10763
4.19k
        }
10764
4.27k
        if (err == MP_OKAY) {
10765
4.14k
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10766
4.14k
            if (t2 == NULL) {
10767
33
                err = MEMORY_E;
10768
33
            }
10769
4.14k
        }
10770
4.27k
        #endif
10771
4.27k
        if (err == MP_OKAY) {
10772
4.11k
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10773
0
                err = MEMORY_E;
10774
4.11k
            else
10775
4.11k
                did_init = 1;
10776
4.11k
        }
10777
10778
        /* load curve info */
10779
4.27k
        if (err == MP_OKAY)
10780
4.11k
            err = wc_ecc_curve_load(key->dp, &curve,
10781
4.11k
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10782
4.11k
                 ECC_CURVE_FIELD_BF));
10783
10784
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
10785
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10786
        /* validate prime is prime for custom curves */
10787
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
10788
            int isPrime = MP_NO;
10789
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10790
            if (err == MP_OKAY && isPrime == MP_NO)
10791
                err = MP_VAL;
10792
        }
10793
    #endif
10794
10795
        /* compute x^3 */
10796
4.27k
        if (err == MP_OKAY)
10797
4.11k
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10798
4.27k
        if (err == MP_OKAY)
10799
4.00k
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10800
10801
        /* compute x^3 + a*x */
10802
4.27k
        if (err == MP_OKAY)
10803
3.89k
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10804
4.27k
        if (err == MP_OKAY)
10805
3.86k
            err = mp_add(t1, t2, t1);
10806
10807
        /* compute x^3 + a*x + b */
10808
4.27k
        if (err == MP_OKAY)
10809
3.86k
            err = mp_add(t1, curve->Bf, t1);
10810
10811
        /* compute sqrt(x^3 + a*x + b) */
10812
4.27k
        if (err == MP_OKAY)
10813
3.86k
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10814
10815
        /* adjust y */
10816
4.27k
        if (err == MP_OKAY) {
10817
1.79k
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10818
1.34k
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10819
890
                err = mp_mod(t2, curve->prime, t2);
10820
890
            }
10821
907
            else {
10822
907
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10823
907
            }
10824
1.79k
            if (err == MP_OKAY)
10825
1.79k
                err = mp_copy(t2, key->pubkey.y);
10826
1.79k
        }
10827
10828
4.27k
        if (did_init) {
10829
4.11k
            mp_clear(t2);
10830
4.11k
            mp_clear(t1);
10831
4.11k
        }
10832
4.27k
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10833
4.27k
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10834
10835
4.27k
        wc_ecc_curve_free(curve);
10836
4.27k
        FREE_CURVE_SPECS();
10837
#else
10838
    #ifndef WOLFSSL_SP_NO_256
10839
        if (key->dp->id == ECC_SECP256R1) {
10840
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
10841
                key->pubkey.y);
10842
        }
10843
        else
10844
    #endif
10845
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10846
        if (key->dp->id == ECC_SM2P256V1) {
10847
            sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
10848
        }
10849
        else
10850
    #endif
10851
    #ifdef WOLFSSL_SP_384
10852
        if (key->dp->id == ECC_SECP384R1) {
10853
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
10854
                key->pubkey.y);
10855
        }
10856
        else
10857
    #endif
10858
    #ifdef WOLFSSL_SP_521
10859
        if (key->dp->id == ECC_SECP521R1) {
10860
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
10861
                key->pubkey.y);
10862
        }
10863
        else
10864
    #endif
10865
        {
10866
            err = WC_KEY_SIZE_E;
10867
        }
10868
#endif
10869
4.27k
    }
10870
6.74k
#endif /* HAVE_COMP_KEY */
10871
10872
6.74k
    if (err == MP_OKAY) {
10873
4.02k
    #ifdef HAVE_COMP_KEY
10874
4.02k
        if (compressed == 0)
10875
2.23k
    #endif
10876
2.23k
        {
10877
2.23k
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10878
2.23k
                (word32)keysize);
10879
2.23k
        }
10880
4.02k
    }
10881
6.74k
    if (err == MP_OKAY)
10882
4.02k
        err = mp_set(key->pubkey.z, 1);
10883
10884
#ifdef WOLFSSL_CRYPTOCELL
10885
    if (err == MP_OKAY) {
10886
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
10887
10888
        /* create public key from external key buffer */
10889
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
10890
                                               (byte*)in-1, /* re-adjust */
10891
                                               inLen+1,     /* original input */
10892
                                               &key->ctx.pubKey,
10893
                                               &tempBuff);
10894
10895
        if (err != SA_SILIB_RET_OK){
10896
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
10897
        }
10898
    }
10899
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10900
    if (err == MP_OKAY)
10901
        err = silabs_ecc_import(key, keysize, 1, 0);
10902
#elif defined(WOLFSSL_SE050)
10903
    if (err == MP_OKAY) {
10904
        /* reset key ID, in case used before */
10905
        key->keyId = 0;
10906
        key->keyIdSet = 0;
10907
    }
10908
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10909
    #ifndef HAVE_COMP_KEY
10910
    if (err == MP_OKAY) {
10911
    #else
10912
    if (err == MP_OKAY && !compressed) {
10913
    #endif
10914
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
10915
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
10916
    }
10917
#endif
10918
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10919
    if (err == MP_OKAY)
10920
        err = wc_ecc_check_key(key);
10921
#endif
10922
10923
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
10924
    if (err == MP_OKAY) {
10925
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
10926
    }
10927
#endif
10928
10929
6.74k
    if (err != MP_OKAY) {
10930
2.71k
        mp_clear(key->pubkey.x);
10931
2.71k
        mp_clear(key->pubkey.y);
10932
2.71k
        mp_clear(key->pubkey.z);
10933
2.71k
        mp_clear(key->k);
10934
2.71k
    }
10935
10936
6.74k
    RESTORE_VECTOR_REGISTERS();
10937
10938
6.74k
    return err;
10939
6.74k
}
10940
10941
WOLFSSL_ABI
10942
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
10943
193
{
10944
193
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
10945
193
}
10946
#endif /* HAVE_ECC_KEY_IMPORT */
10947
10948
#ifdef HAVE_ECC_KEY_EXPORT
10949
10950
/* export ecc key to component form, d is optional if only exporting public
10951
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
10952
 * return MP_OKAY on success */
10953
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
10954
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
10955
0
{
10956
0
    int err = 0;
10957
0
    word32 keySz;
10958
10959
0
    if (key == NULL) {
10960
0
        return BAD_FUNC_ARG;
10961
0
    }
10962
10963
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
10964
0
        return ECC_BAD_ARG_E;
10965
0
    }
10966
0
    keySz = (word32)key->dp->size;
10967
10968
    /* private key, d */
10969
0
    if (d != NULL) {
10970
0
        if (dLen == NULL ||
10971
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
10972
0
            return BAD_FUNC_ARG;
10973
10974
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10975
        /* Hardware cannot export private portion */
10976
        return NOT_COMPILED_IN;
10977
    #else
10978
    #if defined(WOLFSSL_SECO_CAAM)
10979
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
10980
            /* Hardware cannot export private portion */
10981
            WOLFSSL_MSG("Can not export private key from HSM");
10982
            return NOT_COMPILED_IN;
10983
        }
10984
    #endif
10985
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10986
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
10987
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
10988
                *dLen = keySz + WC_CAAM_MAC_SZ;
10989
                return BUFFER_E;
10990
            }
10991
10992
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
10993
                encType);
10994
            *dLen = keySz + WC_CAAM_MAC_SZ;
10995
        }
10996
        else if (encType == WC_TYPE_BLACK_KEY &&
10997
                key->blackKey != CAAM_BLACK_KEY_ECB &&
10998
                key->blackKey > 0) {
10999
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11000
                *dLen = keySz + WC_CAAM_MAC_SZ;
11001
                return BUFFER_E;
11002
            }
11003
11004
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11005
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11006
                    return WC_HW_E;
11007
            }
11008
11009
            *dLen = keySz + WC_CAAM_MAC_SZ;
11010
        }
11011
        else
11012
    #endif
11013
0
        {
11014
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11015
0
            if (err != MP_OKAY)
11016
0
                return err;
11017
0
        }
11018
0
    #endif
11019
0
    }
11020
11021
    /* public x component */
11022
0
    if (qx != NULL) {
11023
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11024
0
            return BAD_FUNC_ARG;
11025
11026
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11027
0
        if (err != MP_OKAY)
11028
0
            return err;
11029
0
    }
11030
11031
    /* public y component */
11032
0
    if (qy != NULL) {
11033
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11034
0
            return BAD_FUNC_ARG;
11035
11036
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11037
0
        if (err != MP_OKAY)
11038
0
            return err;
11039
0
    }
11040
11041
0
    return err;
11042
0
}
11043
11044
11045
/* export ecc private key only raw, outLen is in/out size as unsigned bin
11046
   return MP_OKAY on success */
11047
WOLFSSL_ABI
11048
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11049
0
{
11050
0
    if (out == NULL || outLen == NULL) {
11051
0
        return BAD_FUNC_ARG;
11052
0
    }
11053
11054
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11055
    /* check if black key in secure memory */
11056
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11057
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11058
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11059
            WC_TYPE_BLACK_KEY);
11060
    }
11061
#endif
11062
11063
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11064
0
        WC_TYPE_UNSIGNED_BIN);
11065
0
}
11066
11067
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11068
 * return MP_OKAY on success, negative on error */
11069
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11070
                             byte* qy, word32* qyLen)
11071
0
{
11072
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11073
0
        return BAD_FUNC_ARG;
11074
0
    }
11075
11076
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11077
0
        WC_TYPE_UNSIGNED_BIN);
11078
0
}
11079
11080
/* export ecc key to raw elements including public (Qx,Qy) and
11081
 *   private (d) as unsigned bin
11082
 * return MP_OKAY on success, negative on error */
11083
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11084
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11085
0
{
11086
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11087
0
        WC_TYPE_UNSIGNED_BIN);
11088
0
}
11089
11090
#endif /* HAVE_ECC_KEY_EXPORT */
11091
11092
#ifdef HAVE_ECC_KEY_IMPORT
11093
/* import private key, public part optional if (pub) passed as NULL */
11094
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11095
                                 const byte* pub, word32 pubSz, ecc_key* key,
11096
                                 int curve_id)
11097
8.39k
{
11098
8.39k
    int ret;
11099
#ifdef WOLFSSL_CRYPTOCELL
11100
    const CRYS_ECPKI_Domain_t* pDomain;
11101
#endif
11102
8.39k
    if (key == NULL || priv == NULL)
11103
112
        return BAD_FUNC_ARG;
11104
11105
    /* public optional, NULL if only importing private */
11106
8.28k
    if (pub != NULL) {
11107
0
    #ifndef NO_ASN
11108
0
        word32 idx = 0;
11109
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
11110
0
        if (ret < 0)
11111
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11112
0
        key->type = ECC_PRIVATEKEY;
11113
    #else
11114
        (void)pubSz;
11115
        ret = NOT_COMPILED_IN;
11116
    #endif
11117
0
    }
11118
8.28k
    else {
11119
        /* make sure required variables are reset */
11120
8.28k
        wc_ecc_reset(key);
11121
11122
        /* set key size */
11123
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11124
         *       on created keys or signatures */
11125
8.28k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11126
8.28k
        key->type = ECC_PRIVATEKEY_ONLY;
11127
8.28k
    }
11128
11129
8.28k
    if (ret != 0)
11130
836
        return ret;
11131
11132
#ifdef WOLFSSL_CRYPTOCELL
11133
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11134
    /* import private key - priv checked for NULL at top */
11135
    if (priv[0] != '\0') {
11136
11137
        /* Create private key from external key buffer*/
11138
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11139
                                      priv,
11140
                                      privSz,
11141
                                      &key->ctx.privKey);
11142
11143
        if (ret != SA_SILIB_RET_OK) {
11144
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11145
            return ret;
11146
        }
11147
11148
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11149
    #ifdef WOLFSSL_ECC_BLIND_K
11150
        if (ret == MP_OKAY) {
11151
            err = ecc_blind_k_rng(key, NULL);
11152
        }
11153
    #endif
11154
    }
11155
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11156
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11157
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11158
        int part = caamFindUnusedPartition();
11159
        if (part >= 0) {
11160
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11161
            if (vaddr == 0) {
11162
                WOLFSSL_MSG("Unable to get partition");
11163
                return MEMORY_E;
11164
            }
11165
11166
            key->partNum  = part;
11167
            key->blackKey = (word32)vaddr;
11168
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11169
                return WC_HW_E;
11170
11171
            if (pub != NULL) {
11172
                /* +1 to account for x963 compressed bit */
11173
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11174
                    return WC_HW_E;
11175
                key->securePubKey = (word32)vaddr + privSz;
11176
            }
11177
        }
11178
        else {
11179
            WOLFSSL_MSG("Unable to find an unused partition");
11180
            return MEMORY_E;
11181
        }
11182
    #else
11183
        key->blackKey = CAAM_BLACK_KEY_CCM;
11184
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11185
    #ifdef WOLFSSL_ECC_BLIND_K
11186
        if (ret == MP_OKAY) {
11187
            err = ecc_blind_k_rng(key, NULL);
11188
        }
11189
    #endif
11190
    #endif
11191
    }
11192
    else {
11193
        key->blackKey = 0;
11194
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11195
    #ifdef WOLFSSL_ECC_BLIND_K
11196
        if (ret == MP_OKAY) {
11197
            err = ecc_blind_k_rng(key, NULL);
11198
        }
11199
    #endif
11200
11201
        /* If using AES-ECB encrypted black keys check here if key is valid,
11202
         * if not valid than assume is an encrypted key. A public key is needed
11203
         * for testing validity. */
11204
        if (key->devId == WOLFSSL_CAAM_DEVID && (
11205
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11206
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11207
            if ((pub != NULL) && (ret == MP_OKAY) &&
11208
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11209
                key->blackKey = CAAM_BLACK_KEY_ECB;
11210
            }
11211
            else if ((pub == NULL) && (ret == MP_OKAY)) {
11212
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11213
                key->blackKey = CAAM_BLACK_KEY_ECB;
11214
            }
11215
            else {
11216
                WOLFSSL_MSG("Importing key that is not a black key!");
11217
            }
11218
        }
11219
    }
11220
#else
11221
11222
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11223
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11224
#endif
11225
11226
7.44k
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11227
#ifdef HAVE_WOLF_BIGINT
11228
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11229
                                                                 privSz) != 0) {
11230
        mp_clear(key->k);
11231
        ret = ASN_GETINT_E;
11232
    }
11233
#endif /* HAVE_WOLF_BIGINT */
11234
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11235
    if (ret == 0) {
11236
        WC_DECLARE_VAR(order, mp_int, 1, 0);
11237
11238
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
11239
            ret=MEMORY_E);
11240
11241
        if (ret == 0) {
11242
            ret = mp_init(order);
11243
        }
11244
        if (ret == 0) {
11245
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11246
        }
11247
    #ifdef WOLFSSL_SM2
11248
        /* SM2 curve: private key must be less than order-1. */
11249
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11250
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11251
            ret = mp_sub_d(order, 1, order);
11252
        }
11253
    #endif
11254
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11255
            ret = ECC_PRIV_KEY_E;
11256
        }
11257
11258
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
11259
    }
11260
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11261
#ifdef WOLFSSL_ECC_BLIND_K
11262
    if (ret == 0) {
11263
        ret = ecc_blind_k_rng(key, NULL);
11264
    }
11265
#endif
11266
11267
7.44k
#endif /* WOLFSSL_CRYPTOCELL */
11268
11269
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11270
    if ((pub != NULL) && (ret == MP_OKAY))
11271
        /* public key needed to perform key validation */
11272
        ret = _ecc_validate_public_key(key, 1, 1);
11273
11274
#endif
11275
11276
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11277
    RESTORE_VECTOR_REGISTERS();
11278
#endif
11279
11280
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11281
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11282
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11283
    }
11284
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11285
    if (ret == 0) {
11286
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11287
    }
11288
#endif
11289
11290
7.44k
    return ret;
11291
8.28k
}
11292
11293
/* ecc private key import, public key in ANSI X9.63 format, private raw */
11294
WOLFSSL_ABI
11295
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11296
                           word32 pubSz, ecc_key* key)
11297
51
{
11298
51
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11299
51
                                                                ECC_CURVE_DEF);
11300
51
}
11301
#endif /* HAVE_ECC_KEY_IMPORT */
11302
11303
#ifndef NO_ASN
11304
/**
11305
   Convert ECC R,S to signature
11306
   r       R component of signature
11307
   s       S component of signature
11308
   out     DER-encoded ECDSA signature
11309
   outlen  [in/out] output buffer size, output signature size
11310
   return  MP_OKAY on success
11311
*/
11312
WOLFSSL_ABI
11313
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11314
2.34k
{
11315
2.34k
    int err;
11316
2.34k
#ifdef WOLFSSL_SMALL_STACK
11317
2.34k
    mp_int* rtmp = NULL;
11318
2.34k
    mp_int* stmp = NULL;
11319
#else
11320
    mp_int  rtmp[1];
11321
    mp_int  stmp[1];
11322
#endif
11323
11324
2.34k
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11325
8
        return ECC_BAD_ARG_E;
11326
11327
2.33k
#ifdef WOLFSSL_SMALL_STACK
11328
2.33k
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11329
2.33k
    if (rtmp == NULL)
11330
5
        return MEMORY_E;
11331
2.33k
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11332
2.33k
    if (stmp == NULL) {
11333
4
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11334
4
        return MEMORY_E;
11335
4
    }
11336
2.32k
#endif
11337
11338
2.32k
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11339
2.32k
    if (err != MP_OKAY) {
11340
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11341
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11342
0
        return err;
11343
0
    }
11344
11345
2.32k
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11346
2.32k
    if (err == MP_OKAY)
11347
2.30k
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11348
11349
2.32k
    if (err == MP_OKAY) {
11350
2.29k
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11351
38
            err = MP_ZERO_E;
11352
2.29k
    }
11353
2.32k
    if (err == MP_OKAY) {
11354
2.26k
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11355
0
            err = MP_READ_E;
11356
0
        }
11357
2.26k
    }
11358
11359
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11360
2.32k
    if (err == MP_OKAY)
11361
2.26k
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11362
11363
2.32k
    mp_clear(rtmp);
11364
2.32k
    mp_clear(stmp);
11365
2.32k
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11366
2.32k
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11367
11368
2.32k
    return err;
11369
2.32k
}
11370
11371
/**
11372
   Convert ECC R,S raw unsigned bin to signature
11373
   r       R component of signature
11374
   rSz     R size
11375
   s       S component of signature
11376
   sSz     S size
11377
   out     DER-encoded ECDSA signature
11378
   outlen  [in/out] output buffer size, output signature size
11379
   return  MP_OKAY on success
11380
*/
11381
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11382
    byte* out, word32* outlen)
11383
350
{
11384
350
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11385
3
        return ECC_BAD_ARG_E;
11386
11387
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11388
347
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11389
350
}
11390
11391
/**
11392
   Convert ECC signature to R,S
11393
   sig     DER-encoded ECDSA signature
11394
   sigLen  length of signature in octets
11395
   r       R component of signature
11396
   rLen    [in/out] output "r" buffer size, output "r" size
11397
   s       S component of signature
11398
   sLen    [in/out] output "s" buffer size, output "s" size
11399
   return  MP_OKAY on success, negative on error
11400
*/
11401
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11402
                     byte* s, word32* sLen)
11403
0
{
11404
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11405
0
        return ECC_BAD_ARG_E;
11406
11407
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11408
0
}
11409
#endif /* !NO_ASN */
11410
11411
#ifdef HAVE_ECC_KEY_IMPORT
11412
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
11413
          const char* qy, const char* d, int curve_id, int encType)
11414
5.42k
{
11415
5.42k
    int err = MP_OKAY;
11416
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11417
    !defined(WOLFSSL_ATECC608A)
11418
    const CRYS_ECPKI_Domain_t* pDomain;
11419
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11420
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11421
#endif
11422
11423
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11424
    defined(WOLFSSL_CRYPTOCELL)
11425
    word32 keySz = 0;
11426
#endif
11427
11428
    /* if d is NULL, only import as public key using Qx,Qy */
11429
5.42k
    if (key == NULL || qx == NULL || qy == NULL) {
11430
0
        return BAD_FUNC_ARG;
11431
0
    }
11432
11433
    /* make sure required variables are reset */
11434
5.42k
    wc_ecc_reset(key);
11435
11436
    /* set curve type and index */
11437
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11438
     *       on created keys or signatures */
11439
5.42k
    err = wc_ecc_set_curve(key, 0, curve_id);
11440
5.42k
    if (err != 0) {
11441
0
        return err;
11442
0
    }
11443
11444
    /* init key */
11445
#ifdef ALT_ECC_SIZE
11446
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11447
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11448
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11449
    alt_fp_init(key->pubkey.x);
11450
    alt_fp_init(key->pubkey.y);
11451
    alt_fp_init(key->pubkey.z);
11452
    key->k = (mp_int*)key->ka;
11453
    alt_fp_init(key->k);
11454
#ifdef WOLFSSL_ECC_BLIND_K
11455
    key->kb = (mp_int*)key->kba;
11456
    key->ku = (mp_int*)key->kua;
11457
    alt_fp_init(key->kb);
11458
    alt_fp_init(key->ku);
11459
#endif
11460
#else
11461
5.42k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11462
5.42k
#ifndef WOLFSSL_ECC_BLIND_K
11463
5.42k
                                                                      NULL, NULL
11464
#else
11465
                                                                key->kb, key->ku
11466
#endif
11467
5.42k
                        );
11468
5.42k
#endif
11469
5.42k
    if (err != MP_OKAY)
11470
0
        return MEMORY_E;
11471
#ifdef WOLFSSL_ECC_BLIND_K
11472
    mp_forcezero(key->kb);
11473
#endif
11474
11475
    /* read Qx */
11476
5.42k
    if (err == MP_OKAY) {
11477
5.42k
        if (encType == WC_TYPE_HEX_STR)
11478
5.42k
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
11479
0
        else
11480
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
11481
0
                (word32)key->dp->size);
11482
11483
5.42k
        if (mp_isneg(key->pubkey.x)) {
11484
0
            WOLFSSL_MSG("Invalid Qx");
11485
0
            err = BAD_FUNC_ARG;
11486
0
        }
11487
5.42k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11488
49
            err = BAD_FUNC_ARG;
11489
49
        }
11490
5.42k
    }
11491
11492
    /* read Qy */
11493
5.42k
    if (err == MP_OKAY) {
11494
5.32k
        if (encType == WC_TYPE_HEX_STR)
11495
5.32k
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
11496
0
        else
11497
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
11498
0
                (word32)key->dp->size);
11499
11500
5.32k
        if (mp_isneg(key->pubkey.y)) {
11501
0
            WOLFSSL_MSG("Invalid Qy");
11502
0
            err = BAD_FUNC_ARG;
11503
0
        }
11504
5.32k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11505
49
            err = BAD_FUNC_ARG;
11506
49
        }
11507
5.32k
    }
11508
11509
5.42k
    if (err == MP_OKAY) {
11510
5.24k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11511
93
            WOLFSSL_MSG("Invalid Qx and Qy");
11512
93
            err = ECC_INF_E;
11513
93
        }
11514
5.24k
    }
11515
11516
5.42k
    if (err == MP_OKAY)
11517
5.15k
        err = mp_set(key->pubkey.z, 1);
11518
11519
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11520
    /* For SECP256R1 only save raw public key for hardware */
11521
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
11522
        keySz = key->dp->size;
11523
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11524
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11525
        if (err == MP_OKAY)
11526
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
11527
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11528
    }
11529
#elif defined(WOLFSSL_CRYPTOCELL)
11530
    if (err == MP_OKAY) {
11531
        keyRaw[0] = ECC_POINT_UNCOMP;
11532
        keySz = (word32)key->dp->size;
11533
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
11534
            WC_TYPE_UNSIGNED_BIN);
11535
        if (err == MP_OKAY) {
11536
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
11537
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11538
        }
11539
11540
        if (err == MP_OKAY) {
11541
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11542
11543
            /* create public key from external key buffer */
11544
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11545
                                                   keyRaw,
11546
                                                   keySz*2 + 1,
11547
                                                   &key->ctx.pubKey,
11548
                                                   &tempBuff);
11549
        }
11550
11551
        if (err != SA_SILIB_RET_OK){
11552
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11553
            return err;
11554
        }
11555
    }
11556
#elif defined(WOLFSSL_KCAPI_ECC)
11557
    if (err == MP_OKAY) {
11558
        word32 keySz = key->dp->size;
11559
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11560
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11561
        if (err == MP_OKAY) {
11562
            err = wc_export_int(key->pubkey.y,
11563
                &key->pubkey_raw[keySz], &keySz, keySz,
11564
                WC_TYPE_UNSIGNED_BIN);
11565
        }
11566
    }
11567
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11568
    if (err == MP_OKAY) {
11569
        const word32 keySize = key->dp->size;
11570
        word32 bufSize = sizeof(key->keyRaw);
11571
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
11572
                            WC_TYPE_UNSIGNED_BIN);
11573
        if (err == MP_OKAY) {
11574
            const word32 offset = bufSize;
11575
            bufSize = sizeof(key->keyRaw) - offset;
11576
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
11577
                                keySize, WC_TYPE_UNSIGNED_BIN);
11578
        }
11579
        if (err == MP_OKAY) {
11580
            mp_reverse(key->keyRaw, keySize);
11581
            mp_reverse(&key->keyRaw[keySize], keySize);
11582
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
11583
                                           keySize * 2);
11584
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
11585
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
11586
                                              xil_curve_type[key->dp->id],
11587
                                              XIL_CAST_U64(key->keyRaw));
11588
            if (err) {
11589
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
11590
                err = WC_HW_E;
11591
            }
11592
#endif
11593
        }
11594
    }
11595
#endif
11596
11597
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11598
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11599
#endif
11600
11601
    /* import private key */
11602
5.42k
    if (err == MP_OKAY) {
11603
5.15k
        if (d != NULL) {
11604
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11605
            /* Hardware doesn't support loading private key */
11606
            err = NOT_COMPILED_IN;
11607
11608
        #elif defined(WOLFSSL_CRYPTOCELL)
11609
            key->type = ECC_PRIVATEKEY;
11610
11611
            if (encType == WC_TYPE_HEX_STR)
11612
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11613
            else
11614
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
11615
                    key->dp->size);
11616
            if (err == MP_OKAY) {
11617
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
11618
                    WC_TYPE_UNSIGNED_BIN);
11619
            }
11620
        #ifdef WOLFSSL_ECC_BLIND_K
11621
            if (err == 0) {
11622
                err = ecc_blind_k_rng(key, NULL);
11623
            }
11624
        #endif
11625
11626
            if (err == MP_OKAY) {
11627
                /* Create private key from external key buffer*/
11628
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
11629
                                              keyRaw,
11630
                                              keySz,
11631
                                              &key->ctx.privKey);
11632
11633
                if (err != SA_SILIB_RET_OK){
11634
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11635
                    return err;
11636
                }
11637
            }
11638
11639
        #else
11640
0
            key->type = ECC_PRIVATEKEY;
11641
0
            if (encType == WC_TYPE_HEX_STR)
11642
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11643
0
            else {
11644
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11645
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11646
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11647
                    key->dp->size + WC_CAAM_MAC_SZ);
11648
                }
11649
                else
11650
            #endif /* WOLFSSL_QNX_CAAM */
11651
0
                {
11652
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11653
0
                        (word32)key->dp->size);
11654
0
                }
11655
0
            }
11656
        #ifdef WOLFSSL_ECC_BLIND_K
11657
            if (err == 0) {
11658
                err = ecc_blind_k_rng(key, NULL);
11659
            }
11660
        #endif
11661
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11662
            if (err == MP_OKAY) {
11663
                const word32 key_size = key->dp->size;
11664
                word32 buf_size = key_size;
11665
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
11666
                                    WC_TYPE_UNSIGNED_BIN);
11667
                mp_reverse(key->privKey, key_size);
11668
            }
11669
#endif
11670
11671
0
        #endif /* #else-case of custom HW-specific implementations */
11672
0
            if (mp_iszero(key->k) || mp_isneg(key->k)) {
11673
0
                WOLFSSL_MSG("Invalid private key");
11674
0
                err = BAD_FUNC_ARG;
11675
0
            }
11676
5.15k
        } else {
11677
5.15k
            key->type = ECC_PUBLICKEY;
11678
5.15k
        }
11679
5.15k
    }
11680
11681
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11682
    if (err == MP_OKAY) {
11683
        err = wc_ecc_check_key(key);
11684
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
11685
                                  mp_iszero(key->pubkey.y))) {
11686
            err = BAD_FUNC_ARG;
11687
        }
11688
    }
11689
#endif
11690
11691
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11692
    RESTORE_VECTOR_REGISTERS();
11693
#endif
11694
11695
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11696
    if (err == MP_OKAY) {
11697
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11698
    }
11699
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11700
    if (err == MP_OKAY) {
11701
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
11702
    }
11703
#endif
11704
11705
5.42k
    if (err != MP_OKAY) {
11706
277
        mp_clear(key->pubkey.x);
11707
277
        mp_clear(key->pubkey.y);
11708
277
        mp_clear(key->pubkey.z);
11709
277
        mp_clear(key->k);
11710
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11711
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11712
#endif
11713
277
    }
11714
11715
5.42k
    return err;
11716
5.42k
}
11717
11718
/**
11719
   Import raw ECC key
11720
   key       The destination ecc_key structure
11721
   qx        x component of the public key, as ASCII hex string
11722
   qy        y component of the public key, as ASCII hex string
11723
   d         private key, as ASCII hex string, optional if importing public
11724
             key only
11725
   curve_id  The id of the curve.
11726
   @return    MP_OKAY on success
11727
*/
11728
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
11729
                   const char* d, int curve_id)
11730
0
{
11731
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
11732
0
        WC_TYPE_HEX_STR);
11733
0
}
11734
11735
/* Import x, y and optional private (d) as unsigned binary */
11736
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
11737
                   const byte* d, int curve_id)
11738
0
{
11739
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
11740
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
11741
0
}
11742
11743
/**
11744
   Import raw ECC key
11745
   key       The destination ecc_key structure
11746
   qx        x component of the public key, as ASCII hex string
11747
   qy        y component of the public key, as ASCII hex string
11748
   d         private key, as ASCII hex string, optional if importing public
11749
             key only
11750
   curveName ECC curve name, from ecc_sets[]
11751
   return    MP_OKAY on success
11752
*/
11753
WOLFSSL_ABI
11754
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
11755
                   const char* d, const char* curveName)
11756
11.8k
{
11757
11.8k
    int err, x;
11758
11759
    /* if d is NULL, only import as public key using Qx,Qy */
11760
11.8k
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
11761
0
        return BAD_FUNC_ARG;
11762
0
    }
11763
11764
    /* set curve type and index */
11765
142k
    for (x = 0; ecc_sets[x].size != 0; x++) {
11766
142k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11767
142k
                     XSTRLEN(curveName)) == 0) {
11768
11.8k
            break;
11769
11.8k
        }
11770
142k
    }
11771
11772
11.8k
    if (ecc_sets[x].size == 0) {
11773
0
        WOLFSSL_MSG("ecc_set curve name not found");
11774
0
        err = ASN_PARSE_E;
11775
11.8k
    } else {
11776
11.8k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
11777
11.8k
            WC_TYPE_HEX_STR);
11778
11.8k
    }
11779
11780
0
    return err;
11781
11.8k
}
11782
#endif /* HAVE_ECC_KEY_IMPORT */
11783
11784
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
11785
/* public key size in octets */
11786
static int ecc_public_key_size(ecc_key* key, word32* sz)
11787
352
{
11788
352
    if (key == NULL || key->dp == NULL)
11789
0
        return BAD_FUNC_ARG;
11790
11791
    /* 'Uncompressed' | x | y */
11792
352
    *sz = 1 + 2 * (word32)key->dp->size;
11793
11794
352
    return 0;
11795
352
}
11796
#endif
11797
11798
/* key size in octets */
11799
WOLFSSL_ABI
11800
int wc_ecc_size(ecc_key* key)
11801
319
{
11802
319
    if (key == NULL || key->dp == NULL)
11803
0
        return 0;
11804
11805
319
    return key->dp->size;
11806
319
}
11807
11808
/* maximum signature size based on key size */
11809
WOLFSSL_ABI
11810
int wc_ecc_sig_size_calc(int sz)
11811
0
{
11812
0
    int maxSigSz = 0;
11813
11814
    /* calculate based on key bits */
11815
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
11816
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
11817
11818
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11819
0
    if (maxSigSz < (128 + 2)) {
11820
0
        maxSigSz -= 1;
11821
0
    }
11822
11823
0
    return maxSigSz;
11824
0
}
11825
11826
/* maximum signature size based on actual key curve */
11827
WOLFSSL_ABI
11828
int wc_ecc_sig_size(const ecc_key* key)
11829
694
{
11830
694
    int maxSigSz;
11831
694
    int orderBits, keySz;
11832
11833
694
    if (key == NULL || key->dp == NULL)
11834
0
        return 0;
11835
11836
    /* the signature r and s will always be less than order */
11837
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
11838
        extra byte for r and s, so add 2 */
11839
694
    keySz = key->dp->size;
11840
694
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11841
694
    if (orderBits > keySz * 8) {
11842
0
        keySz = (orderBits + 7) >> 3;
11843
0
    }
11844
    /* maximum possible signature header size is 7 bytes */
11845
694
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11846
694
    if ((orderBits % 8) == 0) {
11847
        /* MSB can be set, so add 2 */
11848
416
        maxSigSz += ECC_MAX_PAD_SZ;
11849
416
    }
11850
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11851
694
    if (maxSigSz < (128 + 2)) {
11852
416
        maxSigSz -= 1;
11853
416
    }
11854
11855
694
    return maxSigSz;
11856
694
}
11857
11858
11859
#ifdef FP_ECC
11860
11861
/* fixed point ECC cache */
11862
/* number of entries in the cache */
11863
#ifndef FP_ENTRIES
11864
    #define FP_ENTRIES 15
11865
#endif
11866
11867
/* number of bits in LUT */
11868
#ifndef FP_LUT
11869
    #define FP_LUT     8U
11870
#endif
11871
11872
#ifdef ECC_SHAMIR
11873
    /* Sharmir requires a bigger LUT, TAO */
11874
    #if (FP_LUT > 12) || (FP_LUT < 4)
11875
        #error FP_LUT must be between 4 and 12 inclusively
11876
    #endif
11877
#else
11878
    #if (FP_LUT > 12) || (FP_LUT < 2)
11879
        #error FP_LUT must be between 2 and 12 inclusively
11880
    #endif
11881
#endif
11882
11883
11884
#if !defined(WOLFSSL_SP_MATH)
11885
11886
/** Our FP cache */
11887
typedef struct {
11888
   ecc_point* g;               /* cached COPY of base point */
11889
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
11890
   int        LUT_set;         /* flag to determine if the LUT has been computed */
11891
   mp_int     mu;              /* copy of the montgomery constant */
11892
   int        lru_count;       /* amount of times this entry has been used */
11893
   int        lock;            /* flag to indicate cache eviction */
11894
                               /* permitted (0) or not (1) */
11895
} fp_cache_t;
11896
11897
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
11898
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
11899
11900
#ifndef HAVE_THREAD_LS
11901
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
11902
#ifndef WOLFSSL_MUTEX_INITIALIZER
11903
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
11904
#endif
11905
#endif /* HAVE_THREAD_LS */
11906
11907
/* simple table to help direct the generation of the LUT */
11908
static const struct {
11909
   int ham, terma, termb;
11910
} lut_orders[] = {
11911
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
11912
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
11913
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
11914
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
11915
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
11916
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
11917
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
11918
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
11919
#if FP_LUT > 6
11920
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
11921
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
11922
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
11923
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
11924
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
11925
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
11926
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
11927
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
11928
#if FP_LUT > 7
11929
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
11930
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
11931
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
11932
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
11933
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
11934
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
11935
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
11936
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
11937
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
11938
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
11939
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
11940
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
11941
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
11942
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
11943
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
11944
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
11945
#if FP_LUT > 8
11946
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
11947
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
11948
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
11949
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
11950
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
11951
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
11952
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
11953
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
11954
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
11955
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
11956
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
11957
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
11958
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
11959
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
11960
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
11961
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
11962
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
11963
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
11964
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
11965
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
11966
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
11967
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
11968
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
11969
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
11970
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
11971
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
11972
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
11973
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
11974
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
11975
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
11976
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
11977
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
11978
#if FP_LUT > 9
11979
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
11980
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
11981
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
11982
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
11983
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
11984
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
11985
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
11986
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
11987
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
11988
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
11989
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
11990
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
11991
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
11992
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
11993
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
11994
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
11995
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
11996
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
11997
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
11998
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
11999
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12000
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12001
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12002
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12003
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12004
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12005
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12006
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12007
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12008
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12009
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12010
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12011
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12012
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12013
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12014
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12015
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12016
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12017
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12018
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12019
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12020
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12021
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12022
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12023
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12024
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12025
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12026
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12027
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12028
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12029
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12030
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12031
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12032
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12033
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12034
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12035
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12036
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12037
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12038
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12039
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12040
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12041
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12042
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12043
#if FP_LUT > 10
12044
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12045
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12046
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12047
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12048
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12049
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12050
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12051
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12052
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12053
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12054
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12055
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12056
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12057
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12058
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12059
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12060
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12061
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12062
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12063
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12064
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12065
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12066
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12067
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12068
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12069
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12070
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12071
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12072
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12073
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12074
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12075
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12076
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12077
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12078
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12079
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12080
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12081
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12082
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12083
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12084
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12085
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12086
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12087
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12088
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12089
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12090
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12091
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12092
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12093
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12094
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12095
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12096
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12097
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12098
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12099
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12100
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12101
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12102
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12103
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12104
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12105
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12106
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12107
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12108
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12109
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12110
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12111
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12112
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12113
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12114
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12115
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12116
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12117
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12118
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12119
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12120
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12121
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12122
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12123
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12124
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12125
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12126
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12127
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12128
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12129
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12130
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12131
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12132
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12133
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12134
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12135
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12136
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12137
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12138
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12139
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12140
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12141
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12142
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12143
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12144
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12145
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12146
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12147
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12148
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12149
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12150
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12151
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12152
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12153
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12154
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12155
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12156
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12157
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12158
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12159
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12160
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12161
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12162
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12163
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12164
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12165
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12166
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12167
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12168
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12169
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12170
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12171
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12172
#if FP_LUT > 11
12173
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12174
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12175
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12176
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12177
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12178
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12179
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12180
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12181
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12182
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12183
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12184
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12185
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12186
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12187
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12188
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12189
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12190
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12191
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12192
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12193
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12194
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12195
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12196
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12197
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12198
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12199
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12200
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12201
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12202
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12203
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12204
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12205
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12206
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12207
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12208
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12209
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12210
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12211
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12212
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12213
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12214
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12215
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12216
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12217
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12218
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12219
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12220
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12221
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12222
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12223
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12224
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12225
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12226
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12227
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12228
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12229
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12230
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12231
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12232
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12233
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12234
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12235
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12236
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12237
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12238
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12239
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12240
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12241
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12242
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12243
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12244
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12245
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12246
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12247
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12248
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12249
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12250
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12251
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12252
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12253
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12254
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12255
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12256
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12257
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12258
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12259
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12260
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12261
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12262
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12263
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12264
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12265
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12266
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12267
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12268
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12269
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12270
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12271
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12272
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12273
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12274
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12275
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12276
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12277
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12278
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12279
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12280
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12281
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12282
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12283
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12284
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12285
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12286
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12287
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12288
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12289
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12290
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12291
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12292
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12293
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12294
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12295
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12296
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12297
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12298
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12299
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12300
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12301
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12302
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12303
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12304
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12305
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12306
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12307
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12308
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12309
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12310
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12311
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12312
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12313
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12314
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12315
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12316
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12317
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12318
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12319
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12320
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12321
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12322
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12323
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12324
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12325
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12326
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12327
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12328
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12329
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12330
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12331
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12332
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12333
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12334
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12335
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12336
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12337
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12338
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12339
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12340
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
12341
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
12342
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
12343
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
12344
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
12345
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
12346
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
12347
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
12348
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
12349
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
12350
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
12351
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
12352
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
12353
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
12354
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
12355
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
12356
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
12357
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
12358
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
12359
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
12360
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
12361
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
12362
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
12363
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
12364
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
12365
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
12366
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
12367
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
12368
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
12369
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
12370
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
12371
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
12372
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
12373
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
12374
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
12375
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
12376
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
12377
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
12378
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
12379
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
12380
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
12381
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
12382
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
12383
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
12384
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
12385
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
12386
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
12387
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
12388
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
12389
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
12390
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
12391
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
12392
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
12393
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
12394
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
12395
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
12396
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
12397
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
12398
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
12399
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
12400
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
12401
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
12402
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
12403
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
12404
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
12405
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
12406
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
12407
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
12408
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
12409
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
12410
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
12411
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
12412
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
12413
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
12414
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
12415
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
12416
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
12417
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
12418
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
12419
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
12420
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
12421
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
12422
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
12423
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
12424
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
12425
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
12426
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
12427
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
12428
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
12429
#endif
12430
#endif
12431
#endif
12432
#endif
12433
#endif
12434
#endif
12435
};
12436
12437
12438
/* find a hole and free as required, return -1 if no hole found */
12439
static int find_hole(void)
12440
{
12441
#ifdef WOLFSSL_NO_MALLOC
12442
   return -1;
12443
#else
12444
   int      x, y, z;
12445
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
12446
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
12447
          z = x;
12448
          y = fp_cache[x].lru_count;
12449
       }
12450
   }
12451
12452
   /* decrease all */
12453
   for (x = 0; x < FP_ENTRIES; x++) {
12454
      if (fp_cache[x].lru_count > 3) {
12455
         --(fp_cache[x].lru_count);
12456
      }
12457
   }
12458
12459
   /* free entry z */
12460
   if (z >= 0 && fp_cache[z].g) {
12461
      mp_clear(&fp_cache[z].mu);
12462
      wc_ecc_del_point(fp_cache[z].g);
12463
      fp_cache[z].g  = NULL;
12464
      for (x = 0; x < (1<<FP_LUT); x++) {
12465
         wc_ecc_del_point(fp_cache[z].LUT[x]);
12466
         fp_cache[z].LUT[x] = NULL;
12467
      }
12468
      fp_cache[z].LUT_set = 0;
12469
      fp_cache[z].lru_count = 0;
12470
   }
12471
   return z;
12472
#endif /* !WOLFSSL_NO_MALLOC */
12473
}
12474
12475
/* determine if a base is already in the cache and if so, where */
12476
static int find_base(ecc_point* g)
12477
{
12478
   int x;
12479
   for (x = 0; x < FP_ENTRIES; x++) {
12480
      if (fp_cache[x].g != NULL &&
12481
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
12482
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
12483
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
12484
         break;
12485
      }
12486
   }
12487
   if (x == FP_ENTRIES) {
12488
      x = -1;
12489
   }
12490
   return x;
12491
}
12492
12493
/* add a new base to the cache */
12494
static int add_entry(int idx, ecc_point *g)
12495
{
12496
   unsigned x, y;
12497
12498
   /* allocate base and LUT */
12499
   fp_cache[idx].g = wc_ecc_new_point();
12500
   if (fp_cache[idx].g == NULL) {
12501
      return MP_MEM;
12502
   }
12503
12504
   /* copy x and y */
12505
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
12506
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
12507
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
12508
      wc_ecc_del_point(fp_cache[idx].g);
12509
      fp_cache[idx].g = NULL;
12510
      return MP_MEM;
12511
   }
12512
12513
   for (x = 0; x < (1U<<FP_LUT); x++) {
12514
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
12515
      if (fp_cache[idx].LUT[x] == NULL) {
12516
         for (y = 0; y < x; y++) {
12517
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
12518
            fp_cache[idx].LUT[y] = NULL;
12519
         }
12520
         wc_ecc_del_point(fp_cache[idx].g);
12521
         fp_cache[idx].g         = NULL;
12522
         fp_cache[idx].lru_count = 0;
12523
         return MP_MEM;
12524
      }
12525
   }
12526
12527
   fp_cache[idx].LUT_set   = 0;
12528
   fp_cache[idx].lru_count = 0;
12529
12530
   return MP_OKAY;
12531
}
12532
#endif
12533
12534
#if !defined(WOLFSSL_SP_MATH)
12535
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
12536
 *
12537
 * The algorithm builds patterns in increasing bit order by first making all
12538
 * single bit input patterns, then all two bit input patterns and so on
12539
 */
12540
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
12541
    mp_int* mu)
12542
{
12543
   int err;
12544
   unsigned x, y, bitlen, lut_gap;
12545
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
12546
   int infinity;
12547
12548
#ifdef WOLFSSL_SMALL_STACK
12549
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12550
       return MEMORY_E;
12551
#endif
12552
12553
   err = mp_init(tmp);
12554
   if (err != MP_OKAY) {
12555
       err = MP_MEM;
12556
       goto errout;
12557
   }
12558
12559
   /* sanity check to make sure lut_order table is of correct size,
12560
      should compile out to a NOP if true */
12561
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
12562
       err = BAD_FUNC_ARG;
12563
       goto errout;
12564
   }
12565
12566
   /* get bitlen and round up to next multiple of FP_LUT */
12567
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12568
   x       = bitlen % FP_LUT;
12569
   if (x) {
12570
       bitlen += FP_LUT - x;
12571
   }
12572
   lut_gap = bitlen / FP_LUT;
12573
12574
   /* init the mu */
12575
   err = mp_init_copy(&fp_cache[idx].mu, mu);
12576
   if (err != MP_OKAY)
12577
       goto errout;
12578
12579
   /* copy base */
12580
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
12581
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
12582
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
12583
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
12584
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
12585
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
12586
       err = MP_MULMOD_E;
12587
       goto errout;
12588
   }
12589
12590
   /* make all single bit entries */
12591
   for (x = 1; x < FP_LUT; x++) {
12592
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
12593
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
12594
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
12595
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
12596
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
12597
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
12598
          err = MP_INIT_E;
12599
          goto errout;
12600
      } else {
12601
12602
         /* now double it bitlen/FP_LUT times */
12603
         for (y = 0; y < lut_gap; y++) {
12604
             if ((err = ecc_projective_dbl_point_safe(
12605
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12606
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12607
                                      a, modulus, mp)) != MP_OKAY) {
12608
                 goto errout;
12609
             }
12610
         }
12611
     }
12612
  }
12613
12614
   /* now make all entries in increase order of hamming weight */
12615
   for (x = 2; x <= FP_LUT; x++) {
12616
       if (err != MP_OKAY)
12617
           goto errout;
12618
       for (y = 0; y < (1UL<<FP_LUT); y++) {
12619
           if (lut_orders[y].ham != (int)x) continue;
12620
12621
           /* perform the add */
12622
           if ((err = ecc_projective_add_point_safe(
12623
                           fp_cache[idx].LUT[lut_orders[y].terma],
12624
                           fp_cache[idx].LUT[lut_orders[y].termb],
12625
                           fp_cache[idx].LUT[y], a, modulus, mp,
12626
                           &infinity)) != MP_OKAY) {
12627
               goto errout;
12628
           }
12629
       }
12630
   }
12631
12632
   /* now map all entries back to affine space to make point addition faster */
12633
   for (x = 1; x < (1UL<<FP_LUT); x++) {
12634
       if (err != MP_OKAY)
12635
           break;
12636
12637
       /* convert z to normal from montgomery */
12638
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
12639
12640
       /* invert it */
12641
       if (err == MP_OKAY)
12642
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
12643
                         fp_cache[idx].LUT[x]->z);
12644
12645
       if (err == MP_OKAY)
12646
         /* now square it */
12647
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
12648
12649
       if (err == MP_OKAY)
12650
         /* fix x */
12651
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
12652
                         fp_cache[idx].LUT[x]->x);
12653
12654
       if (err == MP_OKAY)
12655
         /* get 1/z^3 */
12656
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
12657
12658
       if (err == MP_OKAY)
12659
         /* fix y */
12660
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
12661
                         fp_cache[idx].LUT[x]->y);
12662
12663
       if (err == MP_OKAY)
12664
         /* free z */
12665
         mp_clear(fp_cache[idx].LUT[x]->z);
12666
   }
12667
12668
  errout:
12669
12670
   mp_clear(tmp);
12671
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12672
12673
   if (err == MP_OKAY) {
12674
       fp_cache[idx].LUT_set = 1;
12675
       return MP_OKAY;
12676
   }
12677
12678
   /* err cleanup */
12679
   for (y = 0; y < (1U<<FP_LUT); y++) {
12680
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
12681
      fp_cache[idx].LUT[y] = NULL;
12682
   }
12683
   wc_ecc_del_point(fp_cache[idx].g);
12684
   fp_cache[idx].g         = NULL;
12685
   fp_cache[idx].LUT_set   = 0;
12686
   fp_cache[idx].lru_count = 0;
12687
   mp_clear(&fp_cache[idx].mu);
12688
12689
   return err;
12690
}
12691
12692
/* perform a fixed point ECC mulmod */
12693
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
12694
                        mp_int* modulus, mp_digit mp, int map)
12695
{
12696
#ifdef WOLFCRYPT_HAVE_SAKKE
12697
    #define KB_SIZE 256
12698
#else
12699
    #define KB_SIZE 128
12700
#endif
12701
12702
#ifdef WOLFSSL_SMALL_STACK
12703
   unsigned char* kb = NULL;
12704
   mp_int*        tk = NULL;
12705
   mp_int*        order = NULL;
12706
#else
12707
   unsigned char kb[KB_SIZE];
12708
   mp_int        tk[1];
12709
   mp_int        order[1];
12710
#endif
12711
   int      x, err;
12712
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
12713
   int first;
12714
   int tk_zeroize = 0;
12715
12716
#ifdef WOLFSSL_SMALL_STACK
12717
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12718
   if (tk == NULL) {
12719
      err = MEMORY_E; goto done;
12720
   }
12721
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12722
   if (order == NULL) {
12723
      err = MEMORY_E; goto done;
12724
   }
12725
#endif
12726
12727
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
12728
       err = MP_INIT_E; goto done;
12729
   }
12730
12731
   if ((err = mp_copy(k, tk)) != MP_OKAY)
12732
       goto done;
12733
   tk_zeroize = 1;
12734
12735
#ifdef WOLFSSL_CHECK_MEM_ZERO
12736
   mp_memzero_add("accel_fp_mul tk", tk);
12737
#endif
12738
12739
   /* if it's smaller than modulus we fine */
12740
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
12741
      /* find order */
12742
       y = (unsigned)mp_unsigned_bin_size(modulus);
12743
      for (x = 0; ecc_sets[x].size; x++) {
12744
         if (y <= (unsigned)ecc_sets[x].size) break;
12745
      }
12746
12747
      /* back off if we are on the 521 bit curve */
12748
      if (y == 66) --x;
12749
12750
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12751
                                                MP_RADIX_HEX)) != MP_OKAY) {
12752
         goto done;
12753
      }
12754
12755
      /* k must be less than modulus */
12756
      if (mp_cmp(tk, order) != MP_LT) {
12757
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
12758
            goto done;
12759
         }
12760
      }
12761
   }
12762
12763
   /* get bitlen and round up to next multiple of FP_LUT */
12764
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12765
   x       = bitlen % FP_LUT;
12766
   if (x) {
12767
      bitlen += FP_LUT - (unsigned)x;
12768
   }
12769
   lut_gap = bitlen / FP_LUT;
12770
12771
   /* get the k value */
12772
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
12773
      err = BUFFER_E; goto done;
12774
   }
12775
12776
   /* store k */
12777
#ifdef WOLFSSL_SMALL_STACK
12778
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12779
   if (kb == NULL) {
12780
      err = MEMORY_E; goto done;
12781
   }
12782
#endif
12783
12784
   XMEMSET(kb, 0, KB_SIZE);
12785
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
12786
   #ifdef WOLFSSL_CHECK_MEM_ZERO
12787
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
12788
   #endif
12789
      /* let's reverse kb so it's little endian */
12790
      x = 0;
12791
      y = (unsigned)mp_unsigned_bin_size(tk);
12792
      if (y > 0) {
12793
          y -= 1;
12794
      }
12795
12796
      while ((unsigned)x < y) {
12797
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
12798
         ++x; --y;
12799
      }
12800
12801
      /* at this point we can start, yipee */
12802
      first = 1;
12803
      for (x = (int)lut_gap-1; x >= 0; x--) {
12804
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
12805
             by x bits from the start */
12806
          bitpos = (unsigned)x;
12807
          for (y = z = 0; y < FP_LUT; y++) {
12808
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
12809
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
12810
                                    the mult in each loop */
12811
          }
12812
12813
          /* double if not first */
12814
          if (!first) {
12815
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
12816
                                                              mp)) != MP_OKAY) {
12817
                break;
12818
             }
12819
          }
12820
12821
          /* add if not first, otherwise copy */
12822
          if (!first && z) {
12823
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
12824
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
12825
                break;
12826
             }
12827
          } else if (z) {
12828
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
12829
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
12830
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
12831
                 err = MP_MEM;
12832
                 break;
12833
             }
12834
             first = 0;
12835
          }
12836
      }
12837
   }
12838
12839
   if (err == MP_OKAY) {
12840
      (void) z; /* Acknowledge the unused assignment */
12841
      ForceZero(kb, KB_SIZE);
12842
12843
      /* map R back from projective space */
12844
      if (map) {
12845
         err = ecc_map(R, modulus, mp);
12846
      } else {
12847
         err = MP_OKAY;
12848
      }
12849
   }
12850
12851
done:
12852
   /* cleanup */
12853
   mp_clear(order);
12854
   /* Ensure it was initialized. */
12855
   if (tk_zeroize) {
12856
       mp_forcezero(tk);
12857
   }
12858
12859
#ifdef WOLFSSL_SMALL_STACK
12860
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12861
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12862
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12863
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
12864
   wc_MemZero_Check(kb, KB_SIZE);
12865
   mp_memzero_check(tk);
12866
#endif
12867
12868
#undef KB_SIZE
12869
12870
   return err;
12871
}
12872
#endif
12873
12874
#ifdef ECC_SHAMIR
12875
#if !defined(WOLFSSL_SP_MATH)
12876
/* perform a fixed point ECC mulmod */
12877
static int accel_fp_mul2add(int idx1, int idx2,
12878
                            mp_int* kA, mp_int* kB,
12879
                            ecc_point *R, mp_int* a,
12880
                            mp_int* modulus, mp_digit mp)
12881
{
12882
#define KB_SIZE 128
12883
12884
#ifdef WOLFSSL_SMALL_STACK
12885
   unsigned char* kb[2] = {NULL, NULL};
12886
   mp_int*        tka = NULL;
12887
   mp_int*        tkb = NULL;
12888
   mp_int*        order = NULL;
12889
#else
12890
   unsigned char kb[2][KB_SIZE];
12891
   mp_int        tka[1];
12892
   mp_int        tkb[1];
12893
   mp_int        order[1];
12894
#endif
12895
   int      x, err;
12896
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
12897
   int first;
12898
12899
#ifdef WOLFSSL_SMALL_STACK
12900
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12901
   if (tka == NULL) {
12902
      err = MEMORY_E; goto done;
12903
   }
12904
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12905
   if (tkb == NULL) {
12906
      err = MEMORY_E; goto done;
12907
   }
12908
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12909
   if (order == NULL) {
12910
      err = MEMORY_E; goto done;
12911
   }
12912
#endif
12913
12914
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
12915
      err = MP_INIT_E; goto done;
12916
   }
12917
12918
   /* if it's smaller than modulus we fine */
12919
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
12920
      /* find order */
12921
      y = (unsigned)mp_unsigned_bin_size(modulus);
12922
      for (x = 0; ecc_sets[x].size; x++) {
12923
         if (y <= (unsigned)ecc_sets[x].size) break;
12924
      }
12925
12926
      /* back off if we are on the 521 bit curve */
12927
      if (y == 66) --x;
12928
12929
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12930
                                                MP_RADIX_HEX)) != MP_OKAY) {
12931
         goto done;
12932
      }
12933
12934
      /* kA must be less than modulus */
12935
      if (mp_cmp(kA, order) != MP_LT) {
12936
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
12937
            goto done;
12938
         }
12939
      } else {
12940
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12941
            goto done;
12942
         }
12943
      }
12944
   } else {
12945
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12946
         goto done;
12947
      }
12948
   }
12949
#ifdef WOLFSSL_CHECK_MEM_ZERO
12950
   mp_memzero_add("accel_fp_mul2add tka", tka);
12951
#endif
12952
12953
   /* if it's smaller than modulus we fine */
12954
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
12955
      /* find order */
12956
      y = (unsigned)mp_unsigned_bin_size(modulus);
12957
      for (x = 0; ecc_sets[x].size; x++) {
12958
         if (y <= (unsigned)ecc_sets[x].size) break;
12959
      }
12960
12961
      /* back off if we are on the 521 bit curve */
12962
      if (y == 66) --x;
12963
12964
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12965
                                                MP_RADIX_HEX)) != MP_OKAY) {
12966
         goto done;
12967
      }
12968
12969
      /* kB must be less than modulus */
12970
      if (mp_cmp(kB, order) != MP_LT) {
12971
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
12972
            goto done;
12973
         }
12974
      } else {
12975
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12976
            goto done;
12977
         }
12978
      }
12979
   } else {
12980
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12981
         goto done;
12982
      }
12983
   }
12984
#ifdef WOLFSSL_CHECK_MEM_ZERO
12985
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
12986
#endif
12987
12988
   /* get bitlen and round up to next multiple of FP_LUT */
12989
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12990
   x       = bitlen % FP_LUT;
12991
   if (x) {
12992
      bitlen += FP_LUT - (unsigned)x;
12993
   }
12994
   lut_gap = bitlen / FP_LUT;
12995
12996
   /* get the k value */
12997
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
12998
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
12999
      err = BUFFER_E; goto done;
13000
   }
13001
13002
   /* store k */
13003
#ifdef WOLFSSL_SMALL_STACK
13004
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13005
   if (kb[0] == NULL) {
13006
      err = MEMORY_E; goto done;
13007
   }
13008
#endif
13009
13010
   XMEMSET(kb[0], 0, KB_SIZE);
13011
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13012
      goto done;
13013
   }
13014
#ifdef WOLFSSL_CHECK_MEM_ZERO
13015
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13016
#endif
13017
13018
   /* let's reverse kb so it's little endian */
13019
   x = 0;
13020
   y = (unsigned)mp_unsigned_bin_size(tka);
13021
   if (y > 0) {
13022
       y -= 1;
13023
   }
13024
   mp_clear(tka);
13025
   while ((unsigned)x < y) {
13026
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13027
      ++x; --y;
13028
   }
13029
13030
   /* store b */
13031
#ifdef WOLFSSL_SMALL_STACK
13032
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13033
   if (kb[1] == NULL) {
13034
      err = MEMORY_E; goto done;
13035
   }
13036
#endif
13037
13038
   XMEMSET(kb[1], 0, KB_SIZE);
13039
#ifdef WOLFSSL_CHECK_MEM_ZERO
13040
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13041
#endif
13042
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13043
      x = 0;
13044
      y = (unsigned)mp_unsigned_bin_size(tkb);
13045
      if (y > 0) {
13046
          y -= 1;
13047
      }
13048
13049
      while ((unsigned)x < y) {
13050
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13051
         ++x; --y;
13052
      }
13053
13054
      /* at this point we can start, yipee */
13055
      first = 1;
13056
      for (x = (int)lut_gap-1; x >= 0; x--) {
13057
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13058
             offset by x bits from the start */
13059
          bitpos = (unsigned)x;
13060
          for (y = zA = zB = 0; y < FP_LUT; y++) {
13061
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13062
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13063
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13064
                                      the mult in each loop */
13065
          }
13066
13067
          /* double if not first */
13068
          if (!first) {
13069
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13070
                                                              mp)) != MP_OKAY) {
13071
                break;
13072
             }
13073
13074
             /* add if not first, otherwise copy */
13075
             if (zA) {
13076
                if ((err = ecc_projective_add_point_safe(R,
13077
                                             fp_cache[idx1].LUT[zA], R, a,
13078
                                             modulus, mp, &first)) != MP_OKAY) {
13079
                   break;
13080
                }
13081
             }
13082
13083
             if (zB) {
13084
                if ((err = ecc_projective_add_point_safe(R,
13085
                                             fp_cache[idx2].LUT[zB], R, a,
13086
                                             modulus, mp, &first)) != MP_OKAY) {
13087
                   break;
13088
                }
13089
             }
13090
          } else {
13091
             if (zA) {
13092
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13093
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13094
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13095
                     err = MP_MEM;
13096
                     break;
13097
                 }
13098
                    first = 0;
13099
             }
13100
             if (zB && first == 0) {
13101
                if ((err = ecc_projective_add_point_safe(R,
13102
                                        fp_cache[idx2].LUT[zB], R, a,
13103
                                        modulus, mp, &first)) != MP_OKAY){
13104
                   break;
13105
                }
13106
             } else if (zB && first == 1) {
13107
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13108
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13109
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13110
                     err = MP_MEM;
13111
                     break;
13112
                 }
13113
                    first = 0;
13114
             }
13115
          }
13116
      }
13117
   }
13118
13119
done:
13120
   /* cleanup */
13121
   mp_forcezero(tkb);
13122
   mp_forcezero(tka);
13123
   mp_clear(order);
13124
13125
#ifdef WOLFSSL_SMALL_STACK
13126
   if (kb[0])
13127
#endif
13128
      ForceZero(kb[0], KB_SIZE);
13129
#ifdef WOLFSSL_SMALL_STACK
13130
   if (kb[1])
13131
#endif
13132
      ForceZero(kb[1], KB_SIZE);
13133
13134
#ifdef WOLFSSL_SMALL_STACK
13135
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13136
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13137
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13138
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13139
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13140
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13141
   wc_MemZero_Check(kb[1], KB_SIZE);
13142
   wc_MemZero_Check(kb[0], KB_SIZE);
13143
   mp_memzero_check(tkb);
13144
   mp_memzero_check(tka);
13145
#endif
13146
13147
#undef KB_SIZE
13148
13149
    if (err != MP_OKAY)
13150
        return err;
13151
13152
   return ecc_map(R, modulus, mp);
13153
}
13154
13155
13156
/** ECC Fixed Point mulmod global with heap hint used
13157
  Computes kA*A + kB*B = C using Shamir's Trick
13158
  A        First point to multiply
13159
  kA       What to multiple A by
13160
  B        Second point to multiply
13161
  kB       What to multiple B by
13162
  C        [out] Destination point (can overlap with A or B)
13163
  a        ECC curve parameter a
13164
  modulus  Modulus for curve
13165
  return MP_OKAY on success
13166
*/
13167
int ecc_mul2add(ecc_point* A, mp_int* kA,
13168
                ecc_point* B, mp_int* kB,
13169
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13170
{
13171
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13172
   mp_digit mp = 0;
13173
#ifdef WOLFSSL_SMALL_STACK
13174
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13175
13176
   if (mu == NULL)
13177
       return MP_MEM;
13178
#else
13179
   mp_int   mu[1];
13180
#endif
13181
13182
   err = mp_init(mu);
13183
   if (err != MP_OKAY) {
13184
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13185
       return err;
13186
   }
13187
13188
#ifndef HAVE_THREAD_LS
13189
#ifndef WOLFSSL_MUTEX_INITIALIZER
13190
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13191
        wc_InitMutex(&ecc_fp_lock);
13192
        initMutex = 1;
13193
   }
13194
#endif
13195
13196
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13197
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13198
      return BAD_MUTEX_E;
13199
   }
13200
#endif /* HAVE_THREAD_LS */
13201
13202
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13203
13204
      /* find point */
13205
      idx1 = find_base(A);
13206
13207
      /* no entry? */
13208
      if (idx1 == -1) {
13209
         /* find hole and add it */
13210
         if ((idx1 = find_hole()) >= 0) {
13211
            err = add_entry(idx1, A);
13212
         }
13213
      }
13214
      if (err == MP_OKAY && idx1 != -1) {
13215
         /* increment LRU */
13216
         ++(fp_cache[idx1].lru_count);
13217
      }
13218
13219
      if (err == MP_OKAY) {
13220
        /* find point */
13221
        idx2 = find_base(B);
13222
13223
        /* no entry? */
13224
        if (idx2 == -1) {
13225
           /* find hole and add it */
13226
           if ((idx2 = find_hole()) >= 0)
13227
              err = add_entry(idx2, B);
13228
         }
13229
      }
13230
13231
      if (err == MP_OKAY && idx2 != -1) {
13232
         /* increment LRU */
13233
         ++(fp_cache[idx2].lru_count);
13234
      }
13235
13236
      if (err == MP_OKAY) {
13237
        /* if it's >= 2 AND the LUT is not set build the LUT */
13238
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13239
           /* compute mp */
13240
           err = mp_montgomery_setup(modulus, &mp);
13241
13242
           if (err == MP_OKAY) {
13243
             mpInit = 1;
13244
             err = mp_montgomery_calc_normalization(mu, modulus);
13245
           }
13246
13247
           if (err == MP_OKAY)
13248
             /* build the LUT */
13249
             err = build_lut(idx1, a, modulus, mp, mu);
13250
        }
13251
      }
13252
13253
      if (err == MP_OKAY) {
13254
        /* if it's >= 2 AND the LUT is not set build the LUT */
13255
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13256
           if (mpInit == 0) {
13257
                /* compute mp */
13258
                err = mp_montgomery_setup(modulus, &mp);
13259
                if (err == MP_OKAY) {
13260
                    mpInit = 1;
13261
                    err = mp_montgomery_calc_normalization(mu, modulus);
13262
                }
13263
            }
13264
13265
            if (err == MP_OKAY)
13266
              /* build the LUT */
13267
              err = build_lut(idx2, a, modulus, mp, mu);
13268
        }
13269
      }
13270
13271
13272
      if (err == MP_OKAY) {
13273
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13274
                                     fp_cache[idx2].LUT_set) {
13275
           if (mpInit == 0) {
13276
              /* compute mp */
13277
              err = mp_montgomery_setup(modulus, &mp);
13278
           }
13279
           if (err == MP_OKAY)
13280
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13281
        } else {
13282
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13283
        }
13284
      }
13285
13286
      RESTORE_VECTOR_REGISTERS();
13287
13288
#ifndef HAVE_THREAD_LS
13289
    wc_UnLockMutex(&ecc_fp_lock);
13290
#endif /* HAVE_THREAD_LS */
13291
    mp_clear(mu);
13292
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13293
13294
    return err;
13295
}
13296
#endif
13297
#endif /* ECC_SHAMIR */
13298
13299
/** ECC Fixed Point mulmod global
13300
    k        The multiplicand
13301
    G        Base point to multiply
13302
    R        [out] Destination of product
13303
    a        ECC curve parameter a
13304
    modulus  The modulus for the curve
13305
    map      [boolean] If non-zero maps the point back to affine coordinates,
13306
             otherwise it's left in jacobian-montgomery form
13307
    return MP_OKAY if successful
13308
*/
13309
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13310
    mp_int* modulus, int map, void* heap)
13311
{
13312
#if !defined(WOLFSSL_SP_MATH)
13313
   int   idx, err = MP_OKAY;
13314
   mp_digit mp = 0;
13315
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13316
   int      mpSetup = 0;
13317
#ifndef HAVE_THREAD_LS
13318
   int got_ecc_fp_lock = 0;
13319
#endif
13320
13321
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13322
       return ECC_BAD_ARG_E;
13323
   }
13324
13325
   /* k can't have more bits than modulus count plus 1 */
13326
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13327
      return ECC_OUT_OF_RANGE_E;
13328
   }
13329
13330
#ifdef WOLFSSL_SMALL_STACK
13331
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13332
       return MP_MEM;
13333
#endif
13334
13335
   if (mp_init(mu) != MP_OKAY) {
13336
       err = MP_INIT_E;
13337
       goto out;
13338
   }
13339
13340
#ifndef HAVE_THREAD_LS
13341
#ifndef WOLFSSL_MUTEX_INITIALIZER
13342
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13343
        wc_InitMutex(&ecc_fp_lock);
13344
        initMutex = 1;
13345
   }
13346
#endif
13347
13348
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13349
      err = BAD_MUTEX_E;
13350
      goto out;
13351
   }
13352
   got_ecc_fp_lock = 1;
13353
#endif /* HAVE_THREAD_LS */
13354
13355
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13356
13357
      /* find point */
13358
      idx = find_base(G);
13359
13360
      /* no entry? */
13361
      if (idx == -1) {
13362
         /* find hole and add it */
13363
         idx = find_hole();
13364
13365
         if (idx >= 0)
13366
            err = add_entry(idx, G);
13367
      }
13368
      if (err == MP_OKAY && idx >= 0) {
13369
         /* increment LRU */
13370
         ++(fp_cache[idx].lru_count);
13371
      }
13372
13373
13374
      if (err == MP_OKAY) {
13375
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13376
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13377
           /* compute mp */
13378
           err = mp_montgomery_setup(modulus, &mp);
13379
13380
           if (err == MP_OKAY) {
13381
             /* compute mu */
13382
             mpSetup = 1;
13383
             err = mp_montgomery_calc_normalization(mu, modulus);
13384
           }
13385
13386
           if (err == MP_OKAY)
13387
             /* build the LUT */
13388
             err = build_lut(idx, a, modulus, mp, mu);
13389
        }
13390
      }
13391
13392
      if (err == MP_OKAY) {
13393
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13394
           if (mpSetup == 0) {
13395
              /* compute mp */
13396
              err = mp_montgomery_setup(modulus, &mp);
13397
           }
13398
           if (err == MP_OKAY)
13399
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13400
        } else {
13401
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
13402
        }
13403
      }
13404
13405
      RESTORE_VECTOR_REGISTERS();
13406
13407
  out:
13408
13409
#ifndef HAVE_THREAD_LS
13410
    if (got_ecc_fp_lock)
13411
        wc_UnLockMutex(&ecc_fp_lock);
13412
#endif /* HAVE_THREAD_LS */
13413
    mp_clear(mu);
13414
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13415
13416
    return err;
13417
13418
#else /* WOLFSSL_SP_MATH */
13419
13420
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13421
        return ECC_BAD_ARG_E;
13422
    }
13423
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13424
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13425
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13426
        return IS_POINT_E;
13427
    }
13428
13429
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13430
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13431
        int ret;
13432
        SAVE_VECTOR_REGISTERS(return _svr_ret);
13433
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13434
        RESTORE_VECTOR_REGISTERS();
13435
        return ret;
13436
    }
13437
#endif
13438
#ifndef WOLFSSL_SP_NO_256
13439
    if (mp_count_bits(modulus) == 256) {
13440
        int ret;
13441
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13442
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13443
        RESTORE_VECTOR_REGISTERS();
13444
        return ret;
13445
    }
13446
#endif
13447
#ifdef WOLFSSL_SP_384
13448
    if (mp_count_bits(modulus) == 384) {
13449
        int ret;
13450
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13451
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13452
        RESTORE_VECTOR_REGISTERS();
13453
        return ret;
13454
    }
13455
#endif
13456
#ifdef WOLFSSL_SP_521
13457
    if (mp_count_bits(modulus) == 521) {
13458
        int ret;
13459
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13460
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13461
        RESTORE_VECTOR_REGISTERS();
13462
        return ret;
13463
    }
13464
#endif
13465
    return WC_KEY_SIZE_E;
13466
#endif /* WOLFSSL_SP_MATH */
13467
}
13468
13469
/** ECC Fixed Point mulmod global
13470
    k        The multiplicand
13471
    G        Base point to multiply
13472
    R        [out] Destination of product
13473
    a        ECC curve parameter a
13474
    modulus  The modulus for the curve
13475
    map      [boolean] If non-zero maps the point back to affine coordinates,
13476
             otherwise it's left in jacobian-montgomery form
13477
    return MP_OKAY if successful
13478
*/
13479
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13480
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
13481
{
13482
#if !defined(WOLFSSL_SP_MATH)
13483
   int   idx, err = MP_OKAY;
13484
   mp_digit mp = 0;
13485
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13486
   int      mpSetup = 0;
13487
#ifndef HAVE_THREAD_LS
13488
   int got_ecc_fp_lock = 0;
13489
#endif
13490
13491
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13492
                                                                order == NULL) {
13493
       return ECC_BAD_ARG_E;
13494
   }
13495
13496
   /* k can't have more bits than order */
13497
   if (mp_count_bits(k) > mp_count_bits(order)) {
13498
      return ECC_OUT_OF_RANGE_E;
13499
   }
13500
13501
#ifdef WOLFSSL_SMALL_STACK
13502
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13503
       return MP_MEM;
13504
#endif
13505
13506
   if (mp_init(mu) != MP_OKAY) {
13507
       err = MP_INIT_E;
13508
       goto out;
13509
   }
13510
13511
#ifndef HAVE_THREAD_LS
13512
#ifndef WOLFSSL_MUTEX_INITIALIZER
13513
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13514
        wc_InitMutex(&ecc_fp_lock);
13515
        initMutex = 1;
13516
   }
13517
#endif
13518
13519
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13520
      err = BAD_MUTEX_E;
13521
      goto out;
13522
   }
13523
   got_ecc_fp_lock = 1;
13524
#endif /* HAVE_THREAD_LS */
13525
13526
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13527
13528
      /* find point */
13529
      idx = find_base(G);
13530
13531
      /* no entry? */
13532
      if (idx == -1) {
13533
         /* find hole and add it */
13534
         idx = find_hole();
13535
13536
         if (idx >= 0)
13537
            err = add_entry(idx, G);
13538
      }
13539
      if (err == MP_OKAY && idx >= 0) {
13540
         /* increment LRU */
13541
         ++(fp_cache[idx].lru_count);
13542
      }
13543
13544
13545
      if (err == MP_OKAY) {
13546
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13547
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13548
           /* compute mp */
13549
           err = mp_montgomery_setup(modulus, &mp);
13550
13551
           if (err == MP_OKAY) {
13552
             /* compute mu */
13553
             mpSetup = 1;
13554
             err = mp_montgomery_calc_normalization(mu, modulus);
13555
           }
13556
13557
           if (err == MP_OKAY)
13558
             /* build the LUT */
13559
             err = build_lut(idx, a, modulus, mp, mu);
13560
        }
13561
      }
13562
13563
      if (err == MP_OKAY) {
13564
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13565
           if (mpSetup == 0) {
13566
              /* compute mp */
13567
              err = mp_montgomery_setup(modulus, &mp);
13568
           }
13569
           if (err == MP_OKAY)
13570
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13571
        } else {
13572
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
13573
        }
13574
      }
13575
13576
      RESTORE_VECTOR_REGISTERS();
13577
13578
  out:
13579
13580
#ifndef HAVE_THREAD_LS
13581
    if (got_ecc_fp_lock)
13582
        wc_UnLockMutex(&ecc_fp_lock);
13583
#endif /* HAVE_THREAD_LS */
13584
    mp_clear(mu);
13585
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13586
13587
    return err;
13588
13589
#else /* WOLFSSL_SP_MATH */
13590
13591
    (void)rng;
13592
13593
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13594
                                                                order == NULL) {
13595
        return ECC_BAD_ARG_E;
13596
    }
13597
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13598
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13599
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13600
        return IS_POINT_E;
13601
    }
13602
13603
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13604
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13605
        int ret;
13606
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13607
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13608
        RESTORE_VECTOR_REGISTERS();
13609
        return ret;
13610
    }
13611
#endif
13612
#ifndef WOLFSSL_SP_NO_256
13613
    if (mp_count_bits(modulus) == 256) {
13614
        int ret;
13615
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13616
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13617
        RESTORE_VECTOR_REGISTERS();
13618
        return ret;
13619
    }
13620
#endif
13621
#ifdef WOLFSSL_SP_384
13622
    if (mp_count_bits(modulus) == 384) {
13623
        int ret;
13624
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13625
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13626
        RESTORE_VECTOR_REGISTERS();
13627
        return ret;
13628
    }
13629
#endif
13630
#ifdef WOLFSSL_SP_521
13631
    if (mp_count_bits(modulus) == 521) {
13632
        int ret;
13633
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13634
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13635
        RESTORE_VECTOR_REGISTERS();
13636
        return ret;
13637
    }
13638
#endif
13639
    return WC_KEY_SIZE_E;
13640
#endif /* WOLFSSL_SP_MATH */
13641
}
13642
13643
#if !defined(WOLFSSL_SP_MATH)
13644
/* helper function for freeing the cache ...
13645
   must be called with the cache mutex locked */
13646
static void wc_ecc_fp_free_cache(void)
13647
{
13648
   unsigned x, y;
13649
   for (x = 0; x < FP_ENTRIES; x++) {
13650
      if (fp_cache[x].g != NULL) {
13651
         for (y = 0; y < (1U<<FP_LUT); y++) {
13652
            wc_ecc_del_point(fp_cache[x].LUT[y]);
13653
            fp_cache[x].LUT[y] = NULL;
13654
         }
13655
         wc_ecc_del_point(fp_cache[x].g);
13656
         fp_cache[x].g         = NULL;
13657
         mp_clear(&fp_cache[x].mu);
13658
         fp_cache[x].LUT_set   = 0;
13659
         fp_cache[x].lru_count = 0;
13660
         fp_cache[x].lock = 0;
13661
      }
13662
   }
13663
}
13664
#endif
13665
13666
13667
/** Init the Fixed Point cache */
13668
void wc_ecc_fp_init(void)
13669
{
13670
#ifndef WOLFSSL_SP_MATH
13671
#ifndef HAVE_THREAD_LS
13672
#ifndef WOLFSSL_MUTEX_INITIALIZER
13673
   if (initMutex == 0) {
13674
        wc_InitMutex(&ecc_fp_lock);
13675
        initMutex = 1;
13676
   }
13677
#endif
13678
#endif
13679
#endif
13680
}
13681
13682
13683
/** Free the Fixed Point cache */
13684
WOLFSSL_ABI
13685
void wc_ecc_fp_free(void)
13686
{
13687
#if !defined(WOLFSSL_SP_MATH)
13688
#ifndef HAVE_THREAD_LS
13689
#ifndef WOLFSSL_MUTEX_INITIALIZER
13690
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13691
        wc_InitMutex(&ecc_fp_lock);
13692
        initMutex = 1;
13693
   }
13694
#endif
13695
13696
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
13697
#endif /* HAVE_THREAD_LS */
13698
13699
       wc_ecc_fp_free_cache();
13700
13701
#ifndef HAVE_THREAD_LS
13702
       wc_UnLockMutex(&ecc_fp_lock);
13703
#ifndef WOLFSSL_MUTEX_INITIALIZER
13704
       wc_FreeMutex(&ecc_fp_lock);
13705
       initMutex = 0;
13706
#endif
13707
   }
13708
#endif /* HAVE_THREAD_LS */
13709
#endif
13710
}
13711
13712
13713
#endif /* FP_ECC */
13714
13715
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
13716
4.97k
{
13717
4.97k
    int err = 0;
13718
13719
4.97k
#ifdef ECC_TIMING_RESISTANT
13720
4.97k
    if (key == NULL) {
13721
0
        err = BAD_FUNC_ARG;
13722
0
    }
13723
4.97k
    else {
13724
4.97k
        key->rng = rng;
13725
4.97k
    }
13726
#else
13727
    (void)key;
13728
    (void)rng;
13729
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
13730
#endif
13731
13732
4.97k
    return err;
13733
4.97k
}
13734
13735
#ifdef HAVE_ECC_ENCRYPT
13736
13737
13738
enum ecCliState {
13739
    ecCLI_INIT      = 1,
13740
    ecCLI_SALT_GET  = 2,
13741
    ecCLI_SALT_SET  = 3,
13742
    ecCLI_SENT_REQ  = 4,
13743
    ecCLI_RECV_RESP = 5,
13744
    ecCLI_BAD_STATE = 99
13745
};
13746
13747
enum ecSrvState {
13748
    ecSRV_INIT      = 1,
13749
    ecSRV_SALT_GET  = 2,
13750
    ecSRV_SALT_SET  = 3,
13751
    ecSRV_RECV_REQ  = 4,
13752
    ecSRV_SENT_RESP = 5,
13753
    ecSRV_BAD_STATE = 99
13754
};
13755
13756
13757
struct ecEncCtx {
13758
    const byte* kdfSalt;   /* optional salt for kdf */
13759
    const byte* kdfInfo;   /* optional info for kdf */
13760
    const byte* macSalt;   /* optional salt for mac */
13761
    word32    kdfSaltSz;   /* size of kdfSalt */
13762
    word32    kdfInfoSz;   /* size of kdfInfo */
13763
    word32    macSaltSz;   /* size of macSalt */
13764
    void*     heap;        /* heap hint for memory used */
13765
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13766
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13767
    byte      encAlgo;     /* which encryption type */
13768
    byte      kdfAlgo;     /* which key derivation function type */
13769
    byte      macAlgo;     /* which mac function type */
13770
    byte      protocol;    /* are we REQ_RESP client or server ? */
13771
    byte      cliSt;       /* protocol state, for sanity checks */
13772
    byte      srvSt;       /* protocol state, for sanity checks */
13773
    WC_RNG*   rng;
13774
};
13775
13776
/* optional set info, can be called before or after set_peer_salt */
13777
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
13778
0
{
13779
0
    if (ctx == NULL)
13780
0
        return BAD_FUNC_ARG;
13781
13782
0
    ctx->encAlgo = encAlgo;
13783
0
    ctx->kdfAlgo = kdfAlgo;
13784
0
    ctx->macAlgo = macAlgo;
13785
13786
0
    return 0;
13787
0
}
13788
13789
13790
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
13791
0
{
13792
0
    if (ctx == NULL || ctx->protocol == 0)
13793
0
        return NULL;
13794
13795
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13796
0
        if (ctx->cliSt == ecCLI_INIT) {
13797
0
            ctx->cliSt =  ecCLI_SALT_GET;
13798
0
            return ctx->clientSalt;
13799
0
        }
13800
0
        else {
13801
0
            ctx->cliSt = ecCLI_BAD_STATE;
13802
0
            return NULL;
13803
0
        }
13804
0
    }
13805
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13806
0
        if (ctx->srvSt == ecSRV_INIT) {
13807
0
            ctx->srvSt =  ecSRV_SALT_GET;
13808
0
            return ctx->serverSalt;
13809
0
        }
13810
0
        else {
13811
0
            ctx->srvSt = ecSRV_BAD_STATE;
13812
0
            return NULL;
13813
0
        }
13814
0
    }
13815
13816
0
    return NULL;
13817
0
}
13818
13819
13820
/* optional set info, can be called before or after set_peer_salt */
13821
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
13822
0
{
13823
0
    if (ctx == NULL || info == 0 || sz < 0)
13824
0
        return BAD_FUNC_ARG;
13825
13826
0
    ctx->kdfInfo   = info;
13827
0
    ctx->kdfInfoSz = (word32)sz;
13828
13829
0
    return 0;
13830
0
}
13831
13832
13833
static const char* exchange_info = "Secure Message Exchange";
13834
13835
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
13836
0
{
13837
0
    byte tmp[EXCHANGE_SALT_SZ/2];
13838
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
13839
13840
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13841
0
        return BAD_FUNC_ARG;
13842
13843
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13844
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
13845
0
        if (ctx->cliSt == ecCLI_SALT_GET)
13846
0
            ctx->cliSt =  ecCLI_SALT_SET;
13847
0
        else {
13848
0
            ctx->cliSt =  ecCLI_BAD_STATE;
13849
0
            return BAD_STATE_E;
13850
0
        }
13851
0
    }
13852
0
    else {
13853
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
13854
0
        if (ctx->srvSt == ecSRV_SALT_GET)
13855
0
            ctx->srvSt =  ecSRV_SALT_SET;
13856
0
        else {
13857
0
            ctx->srvSt =  ecSRV_BAD_STATE;
13858
0
            return BAD_STATE_E;
13859
0
        }
13860
0
    }
13861
13862
    /* mix half and half */
13863
    /* tmp stores 2nd half of client before overwrite */
13864
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
13865
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
13866
0
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
13867
13868
0
    ctx->kdfSalt   = ctx->clientSalt;
13869
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
13870
13871
0
    ctx->macSalt   = ctx->serverSalt;
13872
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
13873
13874
0
    if (ctx->kdfInfo == NULL) {
13875
        /* default info */
13876
0
        ctx->kdfInfo   = (const byte*)exchange_info;
13877
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
13878
0
    }
13879
13880
0
    return 0;
13881
0
}
13882
13883
/* Set the salt pointer into context.
13884
 *
13885
 * @param  [in, out]  ctx   ECIES context object.
13886
 * @param  [in]       salt  Salt to use with KDF.
13887
 * @param  [in]       sz    Length of salt in bytes.
13888
 * @return  0 on success.
13889
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13890
 */
13891
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13892
0
{
13893
0
    if (ctx == NULL || (salt == NULL && sz != 0))
13894
0
        return BAD_FUNC_ARG;
13895
13896
    /* truncate salt if exceeds max */
13897
0
    if (sz > EXCHANGE_SALT_SZ)
13898
0
        sz = EXCHANGE_SALT_SZ;
13899
13900
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
13901
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
13902
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13903
0
        ctx->cliSt = ecCLI_SALT_SET;
13904
0
        ctx->kdfSalt = ctx->clientSalt;
13905
0
    }
13906
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13907
0
        ctx->srvSt = ecSRV_SALT_SET;
13908
0
        ctx->kdfSalt = ctx->serverSalt;
13909
0
    }
13910
13911
0
    if (salt != NULL) {
13912
0
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
13913
0
    }
13914
0
    ctx->kdfSaltSz = sz;
13915
13916
0
    return 0;
13917
0
}
13918
13919
/* Set your own salt. By default we generate a random salt for ourselves.
13920
 * This allows overriding that after init or reset.
13921
 *
13922
 * @param  [in, out]  ctx   ECIES context object.
13923
 * @param  [in]       salt  Salt to use for ourselves
13924
 * @param  [in]       sz    Length of salt in bytes.
13925
 * @return  0 on success.
13926
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13927
 */
13928
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13929
0
{
13930
0
    byte* saltBuffer;
13931
13932
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13933
0
        return BAD_FUNC_ARG;
13934
13935
0
    if (sz > EXCHANGE_SALT_SZ)
13936
0
        sz = EXCHANGE_SALT_SZ;
13937
0
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
13938
0
        ctx->clientSalt :
13939
0
        ctx->serverSalt;
13940
0
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
13941
0
    XMEMCPY(saltBuffer, salt, sz);
13942
13943
0
    return 0;
13944
0
}
13945
13946
13947
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
13948
0
{
13949
0
    byte* saltBuffer;
13950
13951
0
    if (ctx == NULL || flags == 0)
13952
0
        return BAD_FUNC_ARG;
13953
13954
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
13955
13956
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
13957
0
}
13958
13959
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
13960
671
{
13961
671
    if (ctx) {
13962
671
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
13963
13964
671
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13965
671
        #ifdef WOLFSSL_AES_128
13966
671
            ctx->encAlgo  = ecAES_128_CBC;
13967
        #else
13968
            ctx->encAlgo  = ecAES_256_CBC;
13969
        #endif
13970
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
13971
        #ifdef WOLFSSL_AES_256
13972
            ctx->encAlgo  = ecAES_256_CTR;
13973
        #else
13974
            ctx->encAlgo  = ecAES_128_CTR;
13975
        #endif
13976
    #else
13977
        #error "No valid encryption algorithm for ECIES configured."
13978
    #endif
13979
671
        ctx->kdfAlgo  = ecHKDF_SHA256;
13980
671
        ctx->macAlgo  = ecHMAC_SHA256;
13981
671
        ctx->protocol = (byte)flags;
13982
671
        ctx->rng      = rng;
13983
13984
671
        if (flags == REQ_RESP_CLIENT)
13985
0
            ctx->cliSt = ecCLI_INIT;
13986
671
        if (flags == REQ_RESP_SERVER)
13987
0
            ctx->srvSt = ecSRV_INIT;
13988
671
    }
13989
671
}
13990
13991
13992
/* allow ecc context reset so user doesn't have to init/free for reuse */
13993
WOLFSSL_ABI
13994
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
13995
0
{
13996
0
    if (ctx == NULL || rng == NULL)
13997
0
        return BAD_FUNC_ARG;
13998
13999
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
14000
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
14001
0
}
14002
14003
14004
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14005
0
{
14006
0
    int       ret = 0;
14007
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14008
0
                                                              DYNAMIC_TYPE_ECC);
14009
14010
0
    if (ctx) {
14011
0
        ctx->protocol = (byte)flags;
14012
0
        ctx->heap     = heap;
14013
0
    }
14014
14015
0
    ret = wc_ecc_ctx_reset(ctx, rng);
14016
0
    if (ret != 0) {
14017
0
        wc_ecc_ctx_free(ctx);
14018
0
        ctx = NULL;
14019
0
    }
14020
14021
0
    return ctx;
14022
0
}
14023
14024
14025
/* alloc/init and set defaults, return new Context  */
14026
WOLFSSL_ABI
14027
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14028
0
{
14029
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14030
0
}
14031
14032
14033
/* free any resources, clear any keys */
14034
WOLFSSL_ABI
14035
void wc_ecc_ctx_free(ecEncCtx* ctx)
14036
0
{
14037
0
    if (ctx) {
14038
0
        void* heap = ctx->heap;
14039
0
        ForceZero(ctx, sizeof(ecEncCtx));
14040
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14041
0
        (void)heap;
14042
0
    }
14043
0
}
14044
14045
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14046
                             int* keysLen, word32* digestSz, word32* blockSz)
14047
671
{
14048
671
    if (ctx) {
14049
671
        switch (ctx->encAlgo) {
14050
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14051
671
            case ecAES_128_CBC:
14052
671
                *encKeySz = KEY_SIZE_128;
14053
671
                *ivSz     = IV_SIZE_128;
14054
671
                *blockSz  = WC_AES_BLOCK_SIZE;
14055
671
                break;
14056
0
            case ecAES_256_CBC:
14057
0
                *encKeySz = KEY_SIZE_256;
14058
0
                *ivSz     = IV_SIZE_128;
14059
0
                *blockSz  = WC_AES_BLOCK_SIZE;
14060
0
                break;
14061
0
        #endif
14062
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14063
0
            case ecAES_128_CTR:
14064
0
                *encKeySz = KEY_SIZE_128;
14065
0
                *ivSz     = 12;
14066
0
                *blockSz  = 1;
14067
0
                break;
14068
0
            case ecAES_256_CTR:
14069
0
                *encKeySz = KEY_SIZE_256;
14070
0
                *ivSz     = 12;
14071
0
                *blockSz  = 1;
14072
0
                break;
14073
0
        #endif
14074
0
            default:
14075
0
                return BAD_FUNC_ARG;
14076
671
        }
14077
14078
671
        switch (ctx->macAlgo) {
14079
671
            case ecHMAC_SHA256:
14080
671
                *digestSz = WC_SHA256_DIGEST_SIZE;
14081
671
                break;
14082
0
            default:
14083
0
                return BAD_FUNC_ARG;
14084
671
        }
14085
671
    } else
14086
0
        return BAD_FUNC_ARG;
14087
14088
#ifdef WOLFSSL_ECIES_OLD
14089
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14090
#else
14091
671
    *keysLen  = *encKeySz + (int)*digestSz;
14092
671
#endif
14093
14094
671
    return 0;
14095
671
}
14096
14097
14098
/* ecc encrypt with shared secret run through kdf
14099
   ctx holds non default algos and inputs
14100
   msgSz should be the right size for encAlgo, i.e., already padded
14101
   return 0 on success */
14102
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14103
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14104
349
{
14105
349
    int          ret = 0;
14106
349
    word32       blockSz = 0;
14107
349
#ifndef WOLFSSL_ECIES_OLD
14108
349
#ifndef WOLFSSL_ECIES_GEN_IV
14109
349
    byte         iv[ECC_MAX_IV_SIZE];
14110
349
#endif
14111
349
    word32       pubKeySz = 0;
14112
349
#endif
14113
349
    word32       digestSz = 0;
14114
349
    ecEncCtx     localCtx;
14115
349
#ifdef WOLFSSL_SMALL_STACK
14116
349
    byte*        sharedSecret;
14117
349
    byte*        keys;
14118
#else
14119
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14120
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14121
#else
14122
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14123
#endif
14124
    byte         keys[ECC_BUFSIZE];         /* max size */
14125
#endif
14126
349
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14127
349
    word32       sharedSz = ECC_MAXSIZE;
14128
#else
14129
    /* 'Uncompressed' byte | public key x | public key y | secret */
14130
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14131
#endif
14132
349
    int          keysLen = 0;
14133
349
    int          encKeySz = 0;
14134
349
    int          ivSz = 0;
14135
349
    int          offset = 0;         /* keys offset if doing msg exchange */
14136
349
    byte*        encKey = NULL;
14137
349
    byte*        encIv = NULL;
14138
349
    byte*        macKey = NULL;
14139
14140
349
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14141
319
                           outSz  == NULL)
14142
30
        return BAD_FUNC_ARG;
14143
14144
319
    if (ctx == NULL) {  /* use defaults */
14145
319
        ecc_ctx_init(&localCtx, 0, NULL);
14146
319
        ctx = &localCtx;
14147
319
    }
14148
14149
319
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14150
319
                            &blockSz);
14151
319
    if (ret != 0)
14152
0
        return ret;
14153
14154
319
#ifndef WOLFSSL_ECIES_OLD
14155
319
    if (!compressed) {
14156
319
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14157
319
    }
14158
0
    else {
14159
0
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14160
0
    }
14161
#else
14162
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14163
#endif
14164
14165
319
    if (ctx->protocol == REQ_RESP_SERVER) {
14166
0
        offset = keysLen;
14167
0
        keysLen *= 2;
14168
14169
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
14170
0
            return BAD_STATE_E;
14171
14172
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14173
0
    }
14174
319
    else if (ctx->protocol == REQ_RESP_CLIENT) {
14175
0
        if (ctx->cliSt != ecCLI_SALT_SET)
14176
0
            return BAD_STATE_E;
14177
14178
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14179
0
    }
14180
14181
319
    if (keysLen > ECC_BUFSIZE) /* keys size */
14182
0
        return BUFFER_E;
14183
14184
319
    if ((msgSz % blockSz) != 0)
14185
53
        return BAD_PADDING_E;
14186
14187
#ifdef WOLFSSL_ECIES_OLD
14188
    if (*outSz < (msgSz + digestSz))
14189
        return BUFFER_E;
14190
#elif defined(WOLFSSL_ECIES_GEN_IV)
14191
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14192
        return BUFFER_E;
14193
#else
14194
266
    if (*outSz < (pubKeySz + msgSz + digestSz))
14195
17
        return BUFFER_E;
14196
249
#endif
14197
14198
249
#ifdef ECC_TIMING_RESISTANT
14199
249
    if (ctx->rng != NULL && privKey->rng == NULL)
14200
0
        privKey->rng = ctx->rng;
14201
249
#endif
14202
14203
249
#ifndef WOLFSSL_ECIES_OLD
14204
249
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14205
249
#ifdef ECC_TIMING_RESISTANT
14206
249
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14207
#else
14208
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14209
#endif
14210
249
        if (ret != 0)
14211
39
            return ret;
14212
249
    }
14213
210
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14214
210
    if (ret != 0)
14215
1
        return ret;
14216
209
    out += pubKeySz;
14217
209
#endif
14218
14219
209
#ifdef WOLFSSL_SMALL_STACK
14220
209
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14221
209
    if (sharedSecret == NULL)
14222
1
        return MEMORY_E;
14223
14224
208
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14225
208
    if (keys == NULL) {
14226
1
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14227
1
        return MEMORY_E;
14228
1
    }
14229
207
#endif
14230
14231
207
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14232
14233
#ifdef WOLFSSL_ECIES_ISO18033
14234
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14235
    sharedSz -= pubKeySz;
14236
#endif
14237
14238
207
    do {
14239
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14240
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14241
        if (ret != 0)
14242
            break;
14243
    #endif
14244
207
    #ifndef WOLFSSL_ECIES_ISO18033
14245
207
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14246
    #else
14247
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14248
                                                                     &sharedSz);
14249
    #endif
14250
207
    }
14251
207
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14252
14253
207
    if (ret == 0) {
14254
    #ifdef WOLFSSL_ECIES_ISO18033
14255
        /* KDF data is encoded public key and secret. */
14256
        sharedSz += pubKeySz;
14257
    #endif
14258
202
        switch (ctx->kdfAlgo) {
14259
202
            case ecHKDF_SHA256 :
14260
202
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14261
202
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14262
202
                           keys, (word32)keysLen);
14263
202
                break;
14264
0
            case ecHKDF_SHA1 :
14265
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14266
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14267
0
                           keys, (word32)keysLen);
14268
0
                break;
14269
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14270
0
            case ecKDF_X963_SHA1 :
14271
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14272
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14273
0
                break;
14274
0
            case ecKDF_X963_SHA256 :
14275
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14276
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14277
0
                break;
14278
0
            case ecKDF_SHA1 :
14279
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14280
0
                           NULL, 0, keys, (word32)keysLen);
14281
0
                break;
14282
0
            case ecKDF_SHA256 :
14283
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14284
0
                           NULL, 0, keys, (word32)keysLen);
14285
0
                break;
14286
0
#endif
14287
14288
14289
0
            default:
14290
0
                ret = BAD_FUNC_ARG;
14291
0
                break;
14292
202
        }
14293
202
    }
14294
14295
207
    if (ret == 0) {
14296
    #ifdef WOLFSSL_ECIES_OLD
14297
        encKey = keys + offset;
14298
        encIv  = encKey + encKeySz;
14299
        macKey = encKey + encKeySz + ivSz;
14300
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14301
        encKey = keys + offset;
14302
        encIv  = out;
14303
        out += ivSz;
14304
        macKey = encKey + encKeySz;
14305
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14306
    #else
14307
189
        XMEMSET(iv, 0, (size_t)ivSz);
14308
189
        encKey = keys + offset;
14309
189
        encIv  = iv;
14310
189
        macKey = encKey + encKeySz;
14311
189
    #endif
14312
189
    }
14313
14314
207
    if (ret == 0) {
14315
189
       switch (ctx->encAlgo) {
14316
189
            case ecAES_128_CBC:
14317
189
            case ecAES_256_CBC:
14318
189
            {
14319
189
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14320
189
            #ifdef WOLFSSL_SMALL_STACK
14321
189
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14322
189
                                          DYNAMIC_TYPE_AES);
14323
189
                if (aes == NULL) {
14324
1
                    ret = MEMORY_E;
14325
1
                    break;
14326
1
                }
14327
            #else
14328
                Aes aes[1];
14329
            #endif
14330
188
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14331
188
                if (ret == 0) {
14332
188
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14333
188
                                                                AES_ENCRYPTION);
14334
188
                    if (ret == 0) {
14335
188
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14336
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14337
                                                    defined(WC_ASYNC_ENABLE_AES)
14338
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14339
                                            WC_ASYNC_FLAG_NONE);
14340
                    #endif
14341
188
                    }
14342
188
                    wc_AesFree(aes);
14343
188
                }
14344
188
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14345
        #else
14346
                ret = NOT_COMPILED_IN;
14347
        #endif
14348
188
                break;
14349
189
            }
14350
0
            case ecAES_128_CTR:
14351
0
            case ecAES_256_CTR:
14352
0
            {
14353
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14354
0
                byte ctr_iv[WC_AES_BLOCK_SIZE];
14355
            #ifndef WOLFSSL_SMALL_STACK
14356
                Aes aes[1];
14357
            #else
14358
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14359
0
                                            DYNAMIC_TYPE_AES);
14360
0
                if (aes == NULL) {
14361
0
                    ret = MEMORY_E;
14362
0
                    break;
14363
0
                }
14364
0
            #endif
14365
14366
                /* Include 4 byte counter starting at all zeros. */
14367
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14368
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14369
0
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14370
14371
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14372
0
                if (ret == 0) {
14373
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14374
0
                                                                AES_ENCRYPTION);
14375
0
                    if (ret == 0) {
14376
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
14377
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14378
                                                    defined(WC_ASYNC_ENABLE_AES)
14379
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14380
                                            WC_ASYNC_FLAG_NONE);
14381
                    #endif
14382
0
                    }
14383
0
                    wc_AesFree(aes);
14384
0
                }
14385
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14386
        #else
14387
                ret = NOT_COMPILED_IN;
14388
        #endif
14389
0
                break;
14390
0
            }
14391
0
            default:
14392
0
                ret = BAD_FUNC_ARG;
14393
0
                break;
14394
189
        }
14395
189
    }
14396
14397
207
    if (ret == 0) {
14398
188
        switch (ctx->macAlgo) {
14399
188
            case ecHMAC_SHA256:
14400
188
            {
14401
188
            #ifdef WOLFSSL_SMALL_STACK
14402
188
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14403
188
                                             DYNAMIC_TYPE_HMAC);
14404
188
                if (hmac == NULL) {
14405
1
                    ret = MEMORY_E;
14406
1
                    break;
14407
1
                }
14408
            #else
14409
                Hmac hmac[1];
14410
            #endif
14411
187
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14412
187
                if (ret == 0) {
14413
187
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14414
187
                                                         WC_SHA256_DIGEST_SIZE);
14415
187
                    if (ret == 0) {
14416
187
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14417
187
                        ret = wc_HmacUpdate(hmac, out, msgSz);
14418
                    #else
14419
                        /* IV is before encrypted message. */
14420
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
14421
                    #endif
14422
187
                    }
14423
187
                    if (ret == 0)
14424
186
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14425
187
                    if (ret == 0)
14426
186
                        ret = wc_HmacFinal(hmac, out+msgSz);
14427
187
                    wc_HmacFree(hmac);
14428
187
                }
14429
187
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14430
187
                break;
14431
188
            }
14432
14433
0
            default:
14434
0
                ret = BAD_FUNC_ARG;
14435
0
                break;
14436
188
        }
14437
188
    }
14438
14439
207
    if (ret == 0) {
14440
#ifdef WOLFSSL_ECIES_OLD
14441
        *outSz = msgSz + digestSz;
14442
#elif defined(WOLFSSL_ECIES_GEN_IV)
14443
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
14444
#else
14445
186
        *outSz = pubKeySz + msgSz + digestSz;
14446
186
#endif
14447
186
    }
14448
14449
207
    RESTORE_VECTOR_REGISTERS();
14450
14451
207
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14452
207
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14453
14454
207
    return ret;
14455
207
}
14456
14457
/* ecc encrypt with shared secret run through kdf
14458
   ctx holds non default algos and inputs
14459
   msgSz should be the right size for encAlgo, i.e., already padded
14460
   return 0 on success */
14461
WOLFSSL_ABI
14462
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14463
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14464
349
{
14465
349
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14466
349
}
14467
14468
/* ecc decrypt with shared secret run through kdf
14469
   ctx holds non default algos and inputs
14470
   return 0 on success */
14471
WOLFSSL_ABI
14472
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14473
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14474
381
{
14475
381
    int          ret = 0;
14476
381
    word32       blockSz = 0;
14477
381
#ifndef WOLFSSL_ECIES_OLD
14478
381
#ifndef WOLFSSL_ECIES_GEN_IV
14479
381
    byte         iv[ECC_MAX_IV_SIZE];
14480
381
#endif
14481
381
    word32       pubKeySz = 0;
14482
381
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
14483
381
#endif
14484
381
    word32       digestSz = 0;
14485
381
    ecEncCtx     localCtx;
14486
381
#ifdef WOLFSSL_SMALL_STACK
14487
381
    byte*        sharedSecret;
14488
381
    byte*        keys;
14489
#else
14490
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14491
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14492
#else
14493
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14494
#endif
14495
    byte         keys[ECC_BUFSIZE];         /* max size */
14496
#endif
14497
381
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14498
381
    word32       sharedSz = ECC_MAXSIZE;
14499
#else
14500
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14501
#endif
14502
381
    int          keysLen = 0;
14503
381
    int          encKeySz = 0;
14504
381
    int          ivSz = 0;
14505
381
    int          offset = 0;       /* in case using msg exchange */
14506
381
    byte*        encKey = NULL;
14507
381
    const byte*  encIv = NULL;
14508
381
    byte*        macKey = NULL;
14509
14510
14511
381
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14512
29
        return BAD_FUNC_ARG;
14513
#ifdef WOLFSSL_ECIES_OLD
14514
    if (pubKey == NULL)
14515
        return BAD_FUNC_ARG;
14516
#endif
14517
14518
352
    if (ctx == NULL) {  /* use defaults */
14519
352
        ecc_ctx_init(&localCtx, 0, NULL);
14520
352
        ctx = &localCtx;
14521
352
    }
14522
14523
352
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14524
352
                            &blockSz);
14525
352
    if (ret != 0)
14526
0
        return ret;
14527
14528
352
#ifndef WOLFSSL_ECIES_OLD
14529
352
    ret = ecc_public_key_size(privKey, &pubKeySz);
14530
352
    if (ret != 0)
14531
0
        return ret;
14532
352
#ifdef HAVE_COMP_KEY
14533
352
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14534
138
        pubKeySz = (pubKeySz / 2) + 1;
14535
138
    }
14536
352
#endif /* HAVE_COMP_KEY */
14537
352
#endif /* WOLFSSL_ECIES_OLD */
14538
14539
352
    if (ctx->protocol == REQ_RESP_CLIENT) {
14540
0
        offset = keysLen;
14541
0
        keysLen *= 2;
14542
14543
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
14544
0
            return BAD_STATE_E;
14545
14546
0
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14547
0
    }
14548
352
    else if (ctx->protocol == REQ_RESP_SERVER) {
14549
0
        if (ctx->srvSt != ecSRV_SALT_SET)
14550
0
            return BAD_STATE_E;
14551
14552
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
14553
0
    }
14554
14555
352
    if (keysLen > ECC_BUFSIZE) /* keys size */
14556
0
        return BUFFER_E;
14557
14558
#ifdef WOLFSSL_ECIES_OLD
14559
    if (((msgSz - digestSz) % blockSz) != 0)
14560
        return BAD_PADDING_E;
14561
14562
    if (*outSz < (msgSz - digestSz))
14563
        return BUFFER_E;
14564
#elif defined(WOLFSSL_ECIES_GEN_IV)
14565
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
14566
        return BAD_PADDING_E;
14567
14568
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
14569
        return BAD_FUNC_ARG;
14570
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
14571
        return BUFFER_E;
14572
#else
14573
352
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14574
122
        return BAD_PADDING_E;
14575
14576
230
    if (msgSz < pubKeySz + blockSz + digestSz)
14577
20
        return BAD_FUNC_ARG;
14578
210
    if (*outSz < (msgSz - digestSz - pubKeySz))
14579
16
        return BUFFER_E;
14580
194
#endif
14581
14582
194
#ifdef ECC_TIMING_RESISTANT
14583
194
    if (ctx->rng != NULL && privKey->rng == NULL)
14584
0
        privKey->rng = ctx->rng;
14585
194
#endif
14586
14587
194
#ifdef WOLFSSL_SMALL_STACK
14588
194
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14589
194
    if (sharedSecret == NULL) {
14590
14
    #ifndef WOLFSSL_ECIES_OLD
14591
14
        if (pubKey == peerKey)
14592
0
            wc_ecc_free(peerKey);
14593
14
    #endif
14594
14
        return MEMORY_E;
14595
14
    }
14596
14597
180
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14598
180
    if (keys == NULL) {
14599
8
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14600
8
    #ifndef WOLFSSL_ECIES_OLD
14601
8
        if (pubKey == peerKey)
14602
0
            wc_ecc_free(peerKey);
14603
8
    #endif
14604
8
        return MEMORY_E;
14605
8
    }
14606
172
#endif
14607
14608
172
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14609
14610
172
#ifndef WOLFSSL_ECIES_OLD
14611
172
    if (pubKey == NULL) {
14612
0
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
14613
0
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
14614
0
        pubKey = peerKey;
14615
0
    }
14616
172
    else {
14617
        /* if a public key was passed in we should free it here before init
14618
         * and import */
14619
172
        wc_ecc_free(pubKey);
14620
172
    }
14621
172
    if (ret == 0) {
14622
172
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14623
172
    }
14624
172
    if (ret == 0) {
14625
172
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14626
172
    }
14627
172
    if (ret == 0) {
14628
        /* Point is not MACed. */
14629
86
        msg += pubKeySz;
14630
86
        msgSz -= pubKeySz;
14631
86
    }
14632
172
#endif
14633
14634
172
    if (ret == 0) {
14635
    #ifdef WOLFSSL_ECIES_ISO18033
14636
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14637
        sharedSz -= pubKeySz;
14638
    #endif
14639
14640
86
        do {
14641
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14642
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
14643
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
14644
            if (ret != 0)
14645
                break;
14646
        #endif
14647
86
        #ifndef WOLFSSL_ECIES_ISO18033
14648
86
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14649
86
                                                                    &sharedSz);
14650
        #else
14651
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14652
                                                          pubKeySz, &sharedSz);
14653
        #endif
14654
86
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14655
86
    }
14656
172
    if (ret == 0) {
14657
    #ifdef WOLFSSL_ECIES_ISO18033
14658
        /* KDF data is encoded public key and secret. */
14659
        sharedSz += pubKeySz;
14660
    #endif
14661
77
        switch (ctx->kdfAlgo) {
14662
77
            case ecHKDF_SHA256 :
14663
77
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14664
77
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14665
77
                           keys, (word32)keysLen);
14666
77
                break;
14667
0
            case ecHKDF_SHA1 :
14668
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14669
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14670
0
                           keys, (word32)keysLen);
14671
0
                break;
14672
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14673
0
            case ecKDF_X963_SHA1 :
14674
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14675
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14676
0
                break;
14677
0
            case ecKDF_X963_SHA256 :
14678
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14679
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14680
0
                break;
14681
0
            case ecKDF_SHA1 :
14682
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14683
0
                           NULL, 0, keys, (word32)keysLen);
14684
0
                break;
14685
0
            case ecKDF_SHA256 :
14686
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14687
0
                           NULL, 0, keys, (word32)keysLen);
14688
0
                break;
14689
0
#endif
14690
14691
0
            default:
14692
0
                ret = BAD_FUNC_ARG;
14693
0
                break;
14694
77
         }
14695
77
    }
14696
14697
172
    if (ret == 0) {
14698
    #ifdef WOLFSSL_ECIES_OLD
14699
        encKey = keys + offset;
14700
        encIv  = encKey + encKeySz;
14701
        macKey = encKey + encKeySz + ivSz;
14702
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14703
        encKey = keys + offset;
14704
        encIv  = msg;
14705
        msg   += ivSz;
14706
        msgSz -= ivSz;
14707
        macKey = encKey + encKeySz;
14708
    #else
14709
77
        XMEMSET(iv, 0, (size_t)ivSz);
14710
77
        encKey = keys + offset;
14711
77
        encIv  = iv;
14712
77
        macKey = encKey + encKeySz;
14713
77
    #endif
14714
14715
77
        switch (ctx->macAlgo) {
14716
77
            case ecHMAC_SHA256:
14717
77
            {
14718
77
                byte verify[WC_SHA256_DIGEST_SIZE];
14719
77
            #ifdef WOLFSSL_SMALL_STACK
14720
77
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14721
77
                                             DYNAMIC_TYPE_HMAC);
14722
77
                if (hmac == NULL) {
14723
0
                    ret = MEMORY_E;
14724
0
                    break;
14725
0
                }
14726
            #else
14727
                Hmac hmac[1];
14728
            #endif
14729
77
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14730
77
                if (ret == 0) {
14731
77
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14732
77
                                                         WC_SHA256_DIGEST_SIZE);
14733
77
                    if (ret == 0)
14734
77
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14735
77
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
14736
                    #else
14737
                        /* IV is before encrypted message. */
14738
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
14739
                    #endif
14740
77
                    if (ret == 0)
14741
77
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14742
14743
77
                    if (ret == 0)
14744
77
                        ret = wc_HmacFinal(hmac, verify);
14745
77
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14746
77
                                                             digestSz) != 0)) {
14747
56
                        ret = HASH_TYPE_E;
14748
56
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14749
56
                    }
14750
14751
77
                    wc_HmacFree(hmac);
14752
77
                }
14753
77
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14754
77
                break;
14755
77
            }
14756
14757
0
            default:
14758
0
                ret = BAD_FUNC_ARG;
14759
0
                break;
14760
77
        }
14761
77
    }
14762
14763
172
    if (ret == 0) {
14764
21
        switch (ctx->encAlgo) {
14765
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14766
21
            case ecAES_128_CBC:
14767
21
            case ecAES_256_CBC:
14768
21
            {
14769
21
            #ifdef WOLFSSL_SMALL_STACK
14770
21
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14771
21
                                          DYNAMIC_TYPE_AES);
14772
21
                if (aes == NULL) {
14773
0
                    ret = MEMORY_E;
14774
0
                    break;
14775
0
                }
14776
            #else
14777
                Aes aes[1];
14778
            #endif
14779
21
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14780
21
                if (ret == 0) {
14781
21
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14782
21
                                                                AES_DECRYPTION);
14783
21
                    if (ret == 0) {
14784
21
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
14785
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14786
                                                    defined(WC_ASYNC_ENABLE_AES)
14787
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14788
                                                            WC_ASYNC_FLAG_NONE);
14789
                    #endif
14790
21
                    }
14791
21
                    wc_AesFree(aes);
14792
21
                }
14793
21
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14794
21
                break;
14795
21
            }
14796
0
        #endif
14797
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14798
0
            case ecAES_128_CTR:
14799
0
            case ecAES_256_CTR:
14800
0
            {
14801
0
            #ifdef WOLFSSL_SMALL_STACK
14802
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14803
0
                                          DYNAMIC_TYPE_AES);
14804
0
                if (aes == NULL) {
14805
0
                    ret = MEMORY_E;
14806
0
                    break;
14807
0
                }
14808
             #else
14809
                Aes aes[1];
14810
             #endif
14811
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14812
0
                if (ret == 0) {
14813
0
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
14814
                    /* Make a 16 byte IV from the bytes passed in. */
14815
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14816
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14817
0
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14818
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14819
0
                                                                AES_ENCRYPTION);
14820
0
                    if (ret == 0) {
14821
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
14822
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14823
                                                    defined(WC_ASYNC_ENABLE_AES)
14824
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14825
                                                            WC_ASYNC_FLAG_NONE);
14826
                    #endif
14827
0
                    }
14828
0
                    wc_AesFree(aes);
14829
0
                }
14830
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14831
0
                break;
14832
0
            }
14833
0
        #endif
14834
0
            default:
14835
0
                ret = BAD_FUNC_ARG;
14836
0
                break;
14837
21
        }
14838
21
    }
14839
14840
172
    if (ret == 0)
14841
21
       *outSz = msgSz - digestSz;
14842
14843
172
    RESTORE_VECTOR_REGISTERS();
14844
14845
172
#ifndef WOLFSSL_ECIES_OLD
14846
172
    if (pubKey == peerKey)
14847
0
        wc_ecc_free(peerKey);
14848
172
#endif
14849
172
#ifdef WOLFSSL_SMALL_STACK
14850
172
#ifndef WOLFSSL_ECIES_OLD
14851
172
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14852
172
#endif
14853
172
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14854
172
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14855
172
#endif
14856
14857
172
    return ret;
14858
172
}
14859
14860
14861
#endif /* HAVE_ECC_ENCRYPT */
14862
14863
14864
#ifdef HAVE_COMP_KEY
14865
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
14866
    !defined(WOLFSSL_CRYPTOCELL)
14867
14868
#ifndef WOLFSSL_SP_MATH
14869
#if !defined(SQRTMOD_USE_MOD_EXP)
14870
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
14871
 */
14872
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
14873
588
{
14874
588
#ifdef WOLFSSL_SMALL_STACK
14875
588
    mp_int*  a1 = NULL;
14876
588
    mp_int*  n1 = NULL;
14877
#else
14878
    mp_int   a1[1], n1[1];
14879
#endif
14880
588
    int      res;
14881
588
    int      s = 1;
14882
588
    int      k;
14883
588
    mp_int*  t[2];
14884
588
    mp_int*  ts;
14885
588
    mp_digit residue;
14886
14887
588
    if (mp_isneg(a) == MP_YES) {
14888
0
        return MP_VAL;
14889
0
    }
14890
588
    if (mp_isneg(n) == MP_YES) {
14891
0
        return MP_VAL;
14892
0
    }
14893
588
    if (mp_iseven(n) == MP_YES) {
14894
0
        return MP_VAL;
14895
0
    }
14896
14897
588
#ifdef WOLFSSL_SMALL_STACK
14898
588
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14899
588
    if (a1 == NULL) {
14900
4
        return MP_MEM;
14901
4
    }
14902
584
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14903
584
    if (n1 == NULL) {
14904
6
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
14905
6
        return MP_MEM;
14906
6
    }
14907
578
#endif
14908
14909
578
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
14910
0
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14911
0
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14912
0
        return res;
14913
0
    }
14914
14915
578
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
14916
14917
578
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
14918
0
        goto done;
14919
0
    }
14920
14921
578
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
14922
0
        goto done;
14923
0
    }
14924
14925
578
    t[0] = a1;
14926
578
    t[1] = n1;
14927
14928
    /* Keep reducing until first number is 0. */
14929
16.9k
    while (!mp_iszero(t[0])) {
14930
        /* Divide by 2 until odd. */
14931
16.3k
        k = mp_cnt_lsb(t[0]);
14932
16.3k
        if (k > 0) {
14933
9.03k
            mp_rshb(t[0], k);
14934
14935
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
14936
             * Odd number of divides results in a negate.
14937
             */
14938
9.03k
            residue = t[1]->dp[0] & 7;
14939
9.03k
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
14940
3.13k
                s = -s;
14941
3.13k
            }
14942
9.03k
        }
14943
14944
        /* Swap t[0] and t[1]. */
14945
16.3k
        ts   = t[0];
14946
16.3k
        t[0] = t[1];
14947
16.3k
        t[1] = ts;
14948
14949
        /* Negate s if both numbers == 3 mod 4. */
14950
16.3k
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
14951
4.07k
             s = -s;
14952
4.07k
        }
14953
14954
        /* Reduce first number modulo second. */
14955
16.3k
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
14956
1.80k
            res = mp_sub(t[0], t[1], t[0]);
14957
1.80k
        }
14958
14.5k
        else {
14959
14.5k
            res = mp_mod(t[0], t[1], t[0]);
14960
14.5k
        }
14961
16.3k
        if (res != MP_OKAY) {
14962
17
            goto done;
14963
17
        }
14964
16.3k
    }
14965
14966
    /* When the two numbers have divisors in common. */
14967
561
    if (!mp_isone(t[1])) {
14968
0
        s = 0;
14969
0
    }
14970
561
    *c = s;
14971
14972
578
done:
14973
14974
578
    RESTORE_VECTOR_REGISTERS();
14975
14976
    /* cleanup */
14977
578
    mp_clear(n1);
14978
578
    mp_clear(a1);
14979
14980
578
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14981
578
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14982
14983
578
  return res;
14984
561
}
14985
#endif /* !SQRTMOD_USE_MOD_EXP */
14986
14987
14988
/* Solves the modular equation x^2 = n (mod p)
14989
 * where prime number is greater than 2 (odd prime).
14990
 * The result is returned in the third argument x
14991
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
14992
 */
14993
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
14994
3.86k
{
14995
#if defined(SQRTMOD_USE_MOD_EXP)
14996
  int res;
14997
  mp_digit i;
14998
  mp_int e;
14999
15000
  /* first handle the simple cases n = 0 or n = 1 */
15001
  if (mp_cmp_d(n, 0) == MP_EQ) {
15002
      mp_zero(ret);
15003
      return MP_OKAY;
15004
  }
15005
  if (mp_cmp_d(n, 1) == MP_EQ) {
15006
      return mp_set(ret, 1);
15007
  }
15008
15009
  if (mp_iseven(prime)) {
15010
      return MP_VAL;
15011
  }
15012
15013
  SAVE_VECTOR_REGISTERS(return _svr_ret;);
15014
15015
  res = mp_init(&e);
15016
  if (res == MP_OKAY)
15017
      res = mp_mod_d(prime, 8, &i);
15018
  if (res == MP_OKAY && i == 1) {
15019
      return MP_VAL;
15020
  }
15021
  /* prime mod 8 = 5 */
15022
  else if (res == MP_OKAY && i == 5) {
15023
      res = mp_sub_d(prime, 1, &e);
15024
      if (res == MP_OKAY)
15025
          res = mp_div_2d(&e, 2, &e, NULL);
15026
  }
15027
  /* prime mod 4 = 3 */
15028
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
15029
      res = mp_add_d(prime, 1, &e);
15030
      if (res == MP_OKAY)
15031
          res = mp_div_2d(&e, 2, &e, NULL);
15032
  }
15033
  if (res == MP_OKAY)
15034
      res = mp_exptmod(n, &e, prime, ret);
15035
15036
  mp_clear(&e);
15037
15038
  RESTORE_VECTOR_REGISTERS();
15039
15040
  return res;
15041
#else
15042
3.86k
  int res, legendre, done = 0;
15043
3.86k
  mp_digit i;
15044
3.86k
#ifdef WOLFSSL_SMALL_STACK
15045
3.86k
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15046
3.86k
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15047
3.86k
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15048
3.86k
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15049
3.86k
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15050
3.86k
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15051
3.86k
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15052
3.86k
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15053
3.86k
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15054
3.86k
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15055
#else
15056
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
15057
#endif
15058
15059
3.86k
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15060
15061
3.86k
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15062
3.86k
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15063
0
    res = MP_INIT_E;
15064
0
    goto out;
15065
0
  }
15066
15067
3.86k
#ifdef WOLFSSL_SMALL_STACK
15068
3.86k
  if ((t1 == NULL) ||
15069
3.70k
      (C == NULL) ||
15070
3.66k
      (Q == NULL) ||
15071
3.65k
      (S == NULL) ||
15072
3.64k
      (Z == NULL) ||
15073
3.63k
      (M == NULL) ||
15074
3.61k
      (T == NULL) ||
15075
3.60k
      (R == NULL) ||
15076
3.60k
      (N == NULL) ||
15077
3.59k
      (two == NULL)) {
15078
273
    res = MP_MEM;
15079
273
    goto out;
15080
273
  }
15081
3.58k
#endif
15082
15083
  /* first handle the simple cases n = 0 or n = 1 */
15084
3.58k
  if (mp_cmp_d(n, 0) == MP_EQ) {
15085
4
    mp_zero(ret);
15086
4
    res = MP_OKAY;
15087
4
    goto out;
15088
4
  }
15089
3.58k
  if (mp_cmp_d(n, 1) == MP_EQ) {
15090
6
    res = mp_set(ret, 1);
15091
6
    goto out;
15092
6
  }
15093
15094
  /* prime must be odd */
15095
3.57k
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15096
2
    res = MP_VAL;
15097
2
    goto out;
15098
2
  }
15099
15100
  /* reduce n to less than prime */
15101
3.57k
  res = mp_mod(n, prime, N);
15102
3.57k
  if (res != MP_OKAY) {
15103
12
    goto out;
15104
12
  }
15105
  /* when N is zero, sqrt is zero */
15106
3.56k
  if (mp_iszero(N)) {
15107
9
    mp_set(ret, 0);
15108
9
    goto out;
15109
9
  }
15110
15111
  /* is quadratic non-residue mod prime */
15112
3.55k
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15113
565
    goto out;
15114
565
  }
15115
2.98k
  if (legendre == -1) {
15116
589
    res = MP_VAL;
15117
589
    goto out;
15118
589
  }
15119
15120
  /* SPECIAL CASE: if prime mod 4 == 3
15121
   * compute directly: res = n^(prime+1)/4 mod prime
15122
   * Handbook of Applied Cryptography algorithm 3.36
15123
   */
15124
2.40k
  res = mp_mod_d(prime, 4, &i);
15125
2.40k
  if (res == MP_OKAY && i == 3) {
15126
1.66k
    res = mp_add_d(prime, 1, t1);
15127
15128
1.66k
    if (res == MP_OKAY)
15129
1.66k
      res = mp_div_2(t1, t1);
15130
1.66k
    if (res == MP_OKAY)
15131
1.66k
      res = mp_div_2(t1, t1);
15132
1.66k
    if (res == MP_OKAY)
15133
1.66k
      res = mp_exptmod(N, t1, prime, ret);
15134
15135
1.66k
    done = 1;
15136
1.66k
  }
15137
15138
  /* NOW: TonelliShanks algorithm */
15139
2.40k
  if (res == MP_OKAY && done == 0) {
15140
15141
    /* factor out powers of 2 from prime-1, defining Q and S
15142
    *                                      as: prime-1 = Q*2^S */
15143
    /* Q = prime - 1 */
15144
737
    res = mp_copy(prime, Q);
15145
737
    if (res == MP_OKAY)
15146
737
      res = mp_sub_d(Q, 1, Q);
15147
15148
    /* S = 0 */
15149
737
    if (res == MP_OKAY)
15150
737
      mp_zero(S);
15151
15152
43.2k
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15153
      /* Q = Q / 2 */
15154
42.5k
      res = mp_div_2(Q, Q);
15155
15156
      /* S = S + 1 */
15157
42.5k
      if (res == MP_OKAY)
15158
42.5k
        res = mp_add_d(S, 1, S);
15159
42.5k
    }
15160
15161
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15162
    /* Z = 2 */
15163
737
    if (res == MP_OKAY)
15164
737
      res = mp_set_int(Z, 2);
15165
15166
4.82k
    while (res == MP_OKAY) {
15167
4.79k
      res = mp_jacobi(Z, prime, &legendre);
15168
4.79k
      if (res == MP_OKAY && legendre == -1)
15169
698
        break;
15170
15171
4.09k
#if defined(WOLFSSL_CUSTOM_CURVES)
15172
      /* P224R1 succeeds with a value of 11. */
15173
4.09k
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15174
        /* This is to clamp the loop in case 'prime' is not really prime */
15175
2
        res = MP_VAL;
15176
2
        break;
15177
2
      }
15178
4.09k
#endif
15179
15180
      /* Z = Z + 1 */
15181
4.09k
      if (res == MP_OKAY)
15182
4.05k
        res = mp_add_d(Z, 1, Z);
15183
15184
4.09k
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
15185
        /* This is to clamp the loop in case 'prime' is not really prime */
15186
2
        res = MP_VAL;
15187
2
        break;
15188
2
      }
15189
4.09k
    }
15190
15191
    /* C = Z ^ Q mod prime */
15192
737
    if (res == MP_OKAY)
15193
698
      res = mp_exptmod(Z, Q, prime, C);
15194
15195
    /* t1 = (Q + 1) / 2 */
15196
737
    if (res == MP_OKAY)
15197
607
      res = mp_add_d(Q, 1, t1);
15198
737
    if (res == MP_OKAY)
15199
607
      res = mp_div_2(t1, t1);
15200
15201
    /* R = n ^ ((Q + 1) / 2) mod prime */
15202
737
    if (res == MP_OKAY)
15203
607
      res = mp_exptmod(N, t1, prime, R);
15204
15205
    /* T = n ^ Q mod prime */
15206
737
    if (res == MP_OKAY)
15207
604
      res = mp_exptmod(N, Q, prime, T);
15208
15209
    /* M = S */
15210
737
    if (res == MP_OKAY)
15211
598
      res = mp_copy(S, M);
15212
15213
737
    if (res == MP_OKAY)
15214
598
      res = mp_set_int(two, 2);
15215
15216
15.4k
    while (res == MP_OKAY && done == 0) {
15217
14.7k
      res = mp_copy(T, t1);
15218
15219
      /* reduce to 1 and count */
15220
14.7k
      i = 0;
15221
690k
      while (res == MP_OKAY) {
15222
690k
        if (mp_cmp_d(t1, 1) == MP_EQ)
15223
14.6k
            break;
15224
676k
        res = mp_exptmod(t1, two, prime, t1);
15225
676k
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
15226
          /* This is to clamp the loop in case 'prime' is not really prime */
15227
22
          res = MP_VAL;
15228
22
          break;
15229
22
        }
15230
676k
        if (res == MP_OKAY)
15231
676k
          i++;
15232
676k
      }
15233
14.7k
      if (res == MP_OKAY && i == 0) {
15234
444
        res = mp_copy(R, ret);
15235
444
        done = 1;
15236
444
      }
15237
15238
14.7k
      if (done == 0) {
15239
        /* t1 = 2 ^ (M - i - 1) */
15240
14.2k
        if (res == MP_OKAY)
15241
14.1k
          res = mp_sub_d(M, i, t1);
15242
14.2k
        if (res == MP_OKAY)
15243
14.1k
          res = mp_sub_d(t1, 1, t1);
15244
14.2k
        if (res == MP_OKAY)
15245
14.1k
          res = mp_exptmod(two, t1, prime, t1);
15246
15247
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15248
14.2k
        if (res == MP_OKAY)
15249
14.1k
          res = mp_exptmod(C, t1, prime, t1);
15250
15251
        /* C = (t1 * t1) mod prime */
15252
14.2k
        if (res == MP_OKAY)
15253
14.1k
          res = mp_sqrmod(t1, prime, C);
15254
15255
        /* R = (R * t1) mod prime */
15256
14.2k
        if (res == MP_OKAY)
15257
14.1k
          res = mp_mulmod(R, t1, prime, R);
15258
15259
        /* T = (T * C) mod prime */
15260
14.2k
        if (res == MP_OKAY)
15261
14.1k
          res = mp_mulmod(T, C, prime, T);
15262
15263
        /* M = i */
15264
14.2k
        if (res == MP_OKAY)
15265
14.1k
          res = mp_set(M, i);
15266
14.2k
      }
15267
14.7k
    }
15268
737
  }
15269
15270
3.86k
  out:
15271
15272
3.86k
  RESTORE_VECTOR_REGISTERS();
15273
15274
3.86k
#ifdef WOLFSSL_SMALL_STACK
15275
3.86k
  if (t1) {
15276
3.70k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15277
3.70k
      mp_clear(t1);
15278
3.70k
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15279
3.70k
  }
15280
3.86k
  if (C) {
15281
3.68k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15282
3.68k
      mp_clear(C);
15283
3.68k
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15284
3.68k
  }
15285
3.86k
  if (Q) {
15286
3.68k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15287
3.68k
      mp_clear(Q);
15288
3.68k
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15289
3.68k
  }
15290
3.86k
  if (S) {
15291
3.67k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15292
3.67k
      mp_clear(S);
15293
3.67k
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15294
3.67k
  }
15295
3.86k
  if (Z) {
15296
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15297
3.66k
      mp_clear(Z);
15298
3.66k
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15299
3.66k
  }
15300
3.86k
  if (M) {
15301
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15302
3.66k
      mp_clear(M);
15303
3.66k
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15304
3.66k
  }
15305
3.86k
  if (T) {
15306
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15307
3.66k
      mp_clear(T);
15308
3.66k
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15309
3.66k
  }
15310
3.86k
  if (R) {
15311
3.65k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15312
3.65k
      mp_clear(R);
15313
3.65k
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15314
3.65k
  }
15315
3.86k
  if (N) {
15316
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15317
3.66k
      mp_clear(N);
15318
3.66k
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15319
3.66k
  }
15320
3.86k
  if (two) {
15321
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15322
3.66k
      mp_clear(two);
15323
3.66k
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15324
3.66k
  }
15325
#else
15326
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
15327
    mp_clear(t1);
15328
    mp_clear(C);
15329
    mp_clear(Q);
15330
    mp_clear(S);
15331
    mp_clear(Z);
15332
    mp_clear(M);
15333
    mp_clear(T);
15334
    mp_clear(R);
15335
    mp_clear(N);
15336
    mp_clear(two);
15337
  }
15338
#endif
15339
15340
3.86k
  return res;
15341
2.40k
#endif
15342
2.40k
}
15343
#endif /* !WOLFSSL_SP_MATH */
15344
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
15345
15346
#ifdef HAVE_ECC_KEY_EXPORT
15347
/* export public ECC key in ANSI X9.63 format compressed */
15348
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
15349
2.48k
{
15350
2.48k
   word32 numlen;
15351
2.48k
   int    ret = MP_OKAY;
15352
15353
2.48k
   if (key == NULL || outLen == NULL)
15354
0
       return BAD_FUNC_ARG;
15355
15356
2.48k
   if (key->type == ECC_PRIVATEKEY_ONLY)
15357
62
       return ECC_PRIVATEONLY_E;
15358
15359
2.42k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15360
388
       return ECC_BAD_ARG_E;
15361
388
   }
15362
15363
2.03k
   numlen = (word32)key->dp->size;
15364
15365
2.03k
   if (*outLen < (1 + numlen)) {
15366
1.01k
      *outLen = 1 + numlen;
15367
1.01k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15368
1.01k
   }
15369
15370
1.01k
   if (out == NULL)
15371
0
       return BAD_FUNC_ARG;
15372
15373
1.01k
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15374
0
       return ECC_BAD_ARG_E;
15375
15376
   /* store first byte */
15377
1.01k
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15378
15379
   /* pad and store x */
15380
1.01k
   XMEMSET(out+1, 0, numlen);
15381
1.01k
   ret = mp_to_unsigned_bin(
15382
1.01k
       key->pubkey.x,
15383
1.01k
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15384
1.01k
   *outLen = 1 + numlen;
15385
15386
1.01k
   return ret;
15387
1.01k
}
15388
#endif /* HAVE_ECC_KEY_EXPORT */
15389
#endif /* HAVE_COMP_KEY */
15390
15391
#ifdef HAVE_OID_ENCODING
15392
int wc_ecc_oid_cache_init(void)
15393
{
15394
    int ret = 0;
15395
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15396
    ret = wc_InitMutex(&ecc_oid_cache_lock);
15397
#endif
15398
    return ret;
15399
}
15400
15401
void wc_ecc_oid_cache_free(void)
15402
{
15403
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15404
    wc_FreeMutex(&ecc_oid_cache_lock);
15405
#endif
15406
}
15407
#endif /* HAVE_OID_ENCODING */
15408
15409
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
15410
6.53k
{
15411
6.53k
    int x;
15412
6.53k
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
15413
#ifdef HAVE_OID_ENCODING
15414
    oid_cache_t* o = NULL;
15415
#endif
15416
15417
6.53k
    if (oidSum == 0) {
15418
34
        return BAD_FUNC_ARG;
15419
34
    }
15420
15421
#ifdef HAVE_OID_ENCODING
15422
    #ifndef WOLFSSL_MUTEX_INITIALIZER
15423
        /* extra sanity check if wolfCrypt_Init not called */
15424
        if (eccOidLockInit == 0) {
15425
            wc_InitMutex(&ecc_oid_cache_lock);
15426
            eccOidLockInit = 1;
15427
        }
15428
    #endif
15429
15430
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
15431
        return BAD_MUTEX_E;
15432
    }
15433
#endif
15434
15435
    /* find matching OID sum (based on encoded value) */
15436
28.9k
    for (x = 0; ecc_sets[x].size != 0; x++) {
15437
26.3k
        if (ecc_sets[x].oidSum == oidSum) {
15438
        #ifdef HAVE_OID_ENCODING
15439
            /* check cache */
15440
            ret = 0;
15441
            o = &ecc_oid_cache[x];
15442
            if (o->oidSz == 0) {
15443
                o->oidSz = sizeof(o->oid);
15444
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
15445
                                                            o->oid, &o->oidSz);
15446
            }
15447
            if (oidSz) {
15448
                *oidSz = o->oidSz;
15449
            }
15450
            if (oid) {
15451
                *oid = o->oid;
15452
            }
15453
15454
            /* on success return curve id */
15455
            if (ret == 0) {
15456
                ret = ecc_sets[x].id;
15457
            }
15458
            break;
15459
        #else
15460
3.96k
            if (oidSz) {
15461
3.96k
                *oidSz = ecc_sets[x].oidSz;
15462
3.96k
            }
15463
3.96k
            if (oid) {
15464
3.96k
                *oid = ecc_sets[x].oid;
15465
3.96k
            }
15466
3.96k
            ret = ecc_sets[x].id;
15467
3.96k
            break;
15468
3.96k
        #endif
15469
3.96k
        }
15470
26.3k
    }
15471
15472
#ifdef HAVE_OID_ENCODING
15473
    wc_UnLockMutex(&ecc_oid_cache_lock);
15474
#endif
15475
15476
6.50k
    return ret;
15477
6.53k
}
15478
15479
#ifdef WOLFSSL_CUSTOM_CURVES
15480
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15481
149
{
15482
149
    if (key == NULL || dp == NULL) {
15483
0
        return BAD_FUNC_ARG;
15484
0
    }
15485
15486
149
    key->idx = ECC_CUSTOM_IDX;
15487
149
    key->dp = dp;
15488
15489
149
    return 0;
15490
149
}
15491
#endif /* WOLFSSL_CUSTOM_CURVES */
15492
15493
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15494
15495
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
15496
0
{
15497
0
    int i;
15498
15499
    /* in network byte order so start at end and work back */
15500
0
    for (i = 3; i >= 0; i--) {
15501
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
15502
0
            return;
15503
0
    }
15504
0
}
15505
15506
/* ASN X9.63 Key Derivation Function (SEC1) */
15507
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
15508
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
15509
0
{
15510
0
    int ret;
15511
0
    word32 digestSz, copySz, remaining = outSz;
15512
0
    byte* outIdx;
15513
0
    byte  counter[4];
15514
0
    byte  tmp[WC_MAX_DIGEST_SIZE];
15515
15516
0
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
15517
15518
0
    if (secret == NULL || secretSz == 0 || out == NULL)
15519
0
        return BAD_FUNC_ARG;
15520
15521
    /* X9.63 allowed algos only */
15522
0
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
15523
0
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
15524
0
        type != WC_HASH_TYPE_SHA512)
15525
0
        return BAD_FUNC_ARG;
15526
15527
0
    ret = wc_HashGetDigestSize(type);
15528
0
    if (ret < 0)
15529
0
        return ret;
15530
0
    digestSz = (word32)ret;
15531
15532
0
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
15533
0
        return MEMORY_E);
15534
15535
0
    ret = wc_HashInit(hash, type);
15536
0
    if (ret != 0) {
15537
0
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15538
0
        return ret;
15539
0
    }
15540
15541
0
    outIdx = out;
15542
0
    XMEMSET(counter, 0, sizeof(counter));
15543
15544
0
    while (remaining > 0) {
15545
15546
0
        IncrementX963KdfCounter(counter);
15547
15548
0
        ret = wc_HashUpdate(hash, type, secret, secretSz);
15549
0
        if (ret != 0) {
15550
0
            break;
15551
0
        }
15552
15553
0
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
15554
0
        if (ret != 0) {
15555
0
            break;
15556
0
        }
15557
15558
0
        if (sinfo) {
15559
0
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
15560
0
            if (ret != 0) {
15561
0
                break;
15562
0
            }
15563
0
        }
15564
15565
0
        ret = wc_HashFinal(hash, type, tmp);
15566
0
        if (ret != 0) {
15567
0
            break;
15568
0
        }
15569
15570
0
        copySz = min(remaining, digestSz);
15571
0
        XMEMCPY(outIdx, tmp, copySz);
15572
15573
0
        remaining -= copySz;
15574
0
        outIdx += copySz;
15575
0
    }
15576
15577
0
    wc_HashFree(hash, type);
15578
15579
0
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15580
15581
0
    return ret;
15582
0
}
15583
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
15584
15585
#ifdef WOLFSSL_SE050
15586
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
15587
 * keyId is a word32, can be used for key IDs larger than an int.
15588
 *
15589
 * key    initialized ecc_key struct
15590
 * keyId  hardware key ID which stores ECC key
15591
 * flags  optional flags, currently unused
15592
 *
15593
 * Return 0 on success, negative on error */
15594
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
15595
{
15596
    (void)flags;
15597
15598
    if (key == NULL) {
15599
        return BAD_FUNC_ARG;
15600
    }
15601
15602
    return se050_ecc_use_key_id(key, keyId);
15603
}
15604
15605
/* Get hardware key ID associated with this ecc_key structure.
15606
 *
15607
 * key    initialized ecc_key struct
15608
 * keyId  [OUT] output for key ID associated with this structure
15609
 *
15610
 * Returns 0 on success, negative on error.
15611
 */
15612
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
15613
{
15614
    if (key == NULL || keyId == NULL) {
15615
        return BAD_FUNC_ARG;
15616
    }
15617
15618
    return se050_ecc_get_key_id(key, keyId);
15619
}
15620
#endif /* WOLFSSL_SE050 */
15621
15622
15623
#ifdef WC_ECC_NONBLOCK
15624
/* Enable ECC support for non-blocking operations */
15625
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
15626
{
15627
    if (key) {
15628
        if (ctx) {
15629
            XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
15630
        }
15631
        key->nb_ctx = ctx;
15632
    }
15633
    return 0;
15634
}
15635
#endif /* WC_ECC_NONBLOCK */
15636
15637
#endif /* HAVE_ECC */