Coverage Report

Created: 2025-12-31 07:08

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
75.8k
#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
195k
const ecc_set_type *wc_ecc_get_sets(void) {
1410
195k
    return ecc_sets;
1411
195k
}
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
259k
    #define ECC_CURVE_FIELD_PRIME   0x01
1497
259k
    #define ECC_CURVE_FIELD_AF      0x02
1498
#ifdef USE_ECC_B_PARAM
1499
256k
    #define ECC_CURVE_FIELD_BF      0x04
1500
#endif
1501
235k
    #define ECC_CURVE_FIELD_ORDER   0x08
1502
192k
    #define ECC_CURVE_FIELD_GX      0x10
1503
192k
    #define ECC_CURVE_FIELD_GY      0x20
1504
#ifdef USE_ECC_B_PARAM
1505
19.8k
    #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
38.1k
        unsigned char* spec_ints = NULL;                                \
1571
38.1k
        ecc_curve_spec curve_lcl;                                       \
1572
38.1k
        ecc_curve_spec* curve = &curve_lcl;                             \
1573
38.1k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1574
38.1k
        curve->spec_count = intcount
1575
1576
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1577
38.0k
    do {                                                                \
1578
38.0k
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1579
38.0k
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1580
38.0k
            DYNAMIC_TYPE_ECC);                                          \
1581
38.0k
        if (spec_ints == NULL)                                          \
1582
38.0k
            (err) = MEMORY_E;                                           \
1583
38.0k
        else {                                                          \
1584
37.3k
            curve->spec_ints = spec_ints;                               \
1585
37.3k
            (err) = MP_OKAY;                                            \
1586
37.3k
        }                                                               \
1587
38.0k
    } 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
38.0k
        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
280k
{
1636
280k
    if (item) {
1637
    #ifdef HAVE_WOLF_BIGINT
1638
        wc_bigint_free(&item->raw);
1639
    #endif
1640
280k
        mp_clear(item);
1641
280k
    }
1642
280k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1643
280k
}
1644
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1645
67.9k
{
1646
67.9k
    if (curve == NULL) {
1647
0
        return;
1648
0
    }
1649
1650
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1651
55.6k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1652
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1653
55.6k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1654
67.9k
#ifdef USE_ECC_B_PARAM
1655
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1656
54.3k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1657
67.9k
#endif
1658
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1659
47.3k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1660
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1661
29.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1662
67.9k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1663
29.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1664
1665
67.9k
    curve->load_mask = 0;
1666
67.9k
}
1667
1668
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1669
70.4k
{
1670
70.4k
    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
70.4k
        wc_ecc_curve_cache_free_spec(curve);
1681
70.4k
    #endif
1682
70.4k
    }
1683
70.4k
}
1684
1685
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1686
    mp_int** dst, byte mask)
1687
193k
{
1688
193k
    int err;
1689
1690
193k
#ifndef ECC_CACHE_CURVE
1691
    /* get mp_int from temp */
1692
193k
    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
193k
#ifdef WOLFSSL_SP_MATH_ALL
1697
193k
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1698
193k
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1699
#else
1700
    *dst = &curve->spec_ints[curve->spec_use++];
1701
#endif
1702
193k
#endif
1703
1704
193k
#ifdef WOLFSSL_SP_MATH_ALL
1705
193k
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1706
#else
1707
    err = mp_init(*dst);
1708
#endif
1709
193k
    if (err == MP_OKAY) {
1710
193k
        curve->load_mask |= mask;
1711
1712
193k
        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
193k
    }
1719
193k
    return err;
1720
193k
}
1721
1722
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1723
    byte load_mask)
1724
66.4k
{
1725
66.4k
    int ret = 0;
1726
66.4k
    ecc_curve_spec* curve;
1727
66.4k
    byte load_items = 0; /* mask of items to load */
1728
#ifdef ECC_CACHE_CURVE
1729
    int x;
1730
#endif
1731
1732
66.4k
    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
66.4k
    curve = *pCurve;
1782
66.4k
#endif /* ECC_CACHE_CURVE */
1783
1784
    /* make sure the curve is initialized */
1785
66.4k
    if (curve->dp != dp) {
1786
66.4k
        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
66.4k
    }
1799
66.4k
    curve->dp = dp; /* set dp info */
1800
1801
    /* determine items to load */
1802
66.4k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1803
66.4k
    curve->load_mask |= load_items;
1804
1805
    /* load items */
1806
66.4k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1807
55.6k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1808
55.6k
            ECC_CURVE_FIELD_PRIME);
1809
66.4k
    if (load_items & ECC_CURVE_FIELD_AF)
1810
55.6k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1811
55.6k
            ECC_CURVE_FIELD_AF);
1812
66.4k
#ifdef USE_ECC_B_PARAM
1813
66.4k
    if (load_items & ECC_CURVE_FIELD_BF)
1814
54.3k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1815
54.3k
            ECC_CURVE_FIELD_BF);
1816
66.4k
#endif
1817
66.4k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1818
47.3k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1819
47.3k
            ECC_CURVE_FIELD_ORDER);
1820
66.4k
    if (load_items & ECC_CURVE_FIELD_GX)
1821
29.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1822
29.2k
            ECC_CURVE_FIELD_GX);
1823
66.4k
    if (load_items & ECC_CURVE_FIELD_GY)
1824
29.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1825
29.2k
            ECC_CURVE_FIELD_GY);
1826
1827
    /* check for error */
1828
66.4k
    if (ret != 0) {
1829
177
        wc_ecc_curve_free(curve);
1830
177
        ret = MP_READ_E;
1831
177
    }
1832
1833
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1834
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1835
#endif
1836
1837
66.4k
    return ret;
1838
66.4k
}
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
47
        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.1k
{
1892
56.1k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1893
0
        return BAD_FUNC_ARG;
1894
0
    }
1895
1896
56.1k
    if (keysize > ECC_MAXSIZE) {
1897
832
        return ECC_BAD_ARG_E;
1898
832
    }
1899
1900
    /* handle custom case */
1901
55.3k
    if (key->idx != ECC_CUSTOM_IDX) {
1902
55.1k
        int x;
1903
1904
        /* default values */
1905
55.1k
        key->idx = 0;
1906
55.1k
        key->dp = NULL;
1907
1908
        /* find ecc_set based on curve_id or key size */
1909
793k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1910
793k
            if (curve_id > ECC_CURVE_DEF) {
1911
692k
                if (curve_id == ecc_sets[x].id)
1912
49.9k
                  break;
1913
692k
            }
1914
100k
            else if (keysize <= ecc_sets[x].size) {
1915
5.04k
                break;
1916
5.04k
            }
1917
793k
        }
1918
55.1k
        if (ecc_sets[x].size == 0) {
1919
188
            WOLFSSL_MSG("ECC Curve not found");
1920
188
            return ECC_CURVE_OID_E;
1921
188
        }
1922
1923
55.0k
        key->idx = x;
1924
55.0k
        key->dp  = &ecc_sets[x];
1925
55.0k
    }
1926
1927
55.1k
    return 0;
1928
55.3k
}
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.02M
{
1962
6.02M
#if !defined(WOLFSSL_SP_MATH)
1963
6.02M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1964
6.02M
   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.02M
   mp_int  *x, *y, *z;
1971
6.02M
   int     err;
1972
1973
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1974
6.02M
   if (Q == R) {
1975
0
      ecc_point* tPt  = P;
1976
0
      P = Q;
1977
0
      Q = tPt;
1978
0
   }
1979
1980
6.02M
#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.02M
#endif /* WOLFSSL_SMALL_STACK */
1994
6.02M
   {
1995
6.02M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1996
6.02M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1997
6.02M
   #ifdef MP_INT_SIZE_CHECK_NULL
1998
6.02M
      if (t1 == NULL || t2 == NULL) {
1999
151
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2000
151
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2001
151
         return MEMORY_E;
2002
151
      }
2003
6.02M
   #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.02M
   }
2020
2021
6.02M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2022
6.02M
   if (err == MP_OKAY) {
2023
6.02M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2024
6.02M
   }
2025
6.02M
   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.02M
   if (err == MP_OKAY) {
2045
6.02M
#ifdef ECC_TIMING_RESISTANT
2046
6.02M
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2047
#else
2048
      err = mp_sub(modulus, Q->y, t1);
2049
#endif
2050
6.02M
   }
2051
6.02M
   if (err == MP_OKAY) {
2052
6.02M
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2053
9.59k
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2054
274
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2055
216
          mp_clear(t1);
2056
216
          mp_clear(t2);
2057
216
   #ifdef WOLFSSL_SMALL_STACK
2058
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2059
         if (R->key == NULL)
2060
      #endif
2061
216
   #endif
2062
216
         {
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
216
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2069
216
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2070
216
         }
2071
216
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2072
216
      }
2073
6.02M
   }
2074
2075
6.02M
   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.02M
   x = R->x;
2100
6.02M
   y = R->y;
2101
6.02M
   z = R->z;
2102
6.02M
#endif
2103
2104
6.02M
   if (err == MP_OKAY)
2105
6.02M
       err = mp_copy(P->x, x);
2106
6.02M
   if (err == MP_OKAY)
2107
6.02M
       err = mp_copy(P->y, y);
2108
6.02M
   if (err == MP_OKAY)
2109
6.02M
       err = mp_copy(P->z, z);
2110
2111
   /* if Z is one then these are no-operations */
2112
6.02M
   if (err == MP_OKAY) {
2113
6.02M
       if (!mp_iszero(Q->z)) {
2114
           /* T1 = Z' * Z' */
2115
6.02M
           err = mp_sqr(Q->z, t1);
2116
6.02M
           if (err == MP_OKAY)
2117
6.02M
               err = mp_montgomery_reduce(t1, modulus, mp);
2118
2119
           /* X = X * T1 */
2120
6.02M
           if (err == MP_OKAY)
2121
6.02M
               err = mp_mul(t1, x, x);
2122
6.02M
           if (err == MP_OKAY)
2123
6.02M
               err = mp_montgomery_reduce(x, modulus, mp);
2124
2125
           /* T1 = Z' * T1 */
2126
6.02M
           if (err == MP_OKAY)
2127
6.02M
               err = mp_mul(Q->z, t1, t1);
2128
6.02M
           if (err == MP_OKAY)
2129
6.02M
               err = mp_montgomery_reduce(t1, modulus, mp);
2130
2131
           /* Y = Y * T1 */
2132
6.02M
           if (err == MP_OKAY)
2133
6.02M
               err = mp_mul(t1, y, y);
2134
6.02M
           if (err == MP_OKAY)
2135
6.02M
               err = mp_montgomery_reduce(y, modulus, mp);
2136
6.02M
       }
2137
6.02M
   }
2138
2139
   /* T1 = Z*Z */
2140
6.02M
   if (err == MP_OKAY)
2141
6.02M
       err = mp_sqr(z, t1);
2142
6.02M
   if (err == MP_OKAY)
2143
6.02M
       err = mp_montgomery_reduce(t1, modulus, mp);
2144
2145
   /* T2 = X' * T1 */
2146
6.02M
   if (err == MP_OKAY)
2147
6.02M
       err = mp_mul(Q->x, t1, t2);
2148
6.02M
   if (err == MP_OKAY)
2149
6.02M
       err = mp_montgomery_reduce(t2, modulus, mp);
2150
2151
   /* T1 = Z * T1 */
2152
6.02M
   if (err == MP_OKAY)
2153
6.02M
       err = mp_mul(z, t1, t1);
2154
6.02M
   if (err == MP_OKAY)
2155
6.02M
       err = mp_montgomery_reduce(t1, modulus, mp);
2156
2157
   /* T1 = Y' * T1 */
2158
6.02M
   if (err == MP_OKAY)
2159
6.02M
       err = mp_mul(Q->y, t1, t1);
2160
6.02M
   if (err == MP_OKAY)
2161
6.02M
       err = mp_montgomery_reduce(t1, modulus, mp);
2162
2163
   /* Y = Y - T1 */
2164
6.02M
   if (err == MP_OKAY)
2165
6.02M
       err = mp_submod_ct(y, t1, modulus, y);
2166
   /* T1 = 2T1 */
2167
6.02M
   if (err == MP_OKAY)
2168
6.02M
       err = mp_addmod_ct(t1, t1, modulus, t1);
2169
   /* T1 = Y + T1 */
2170
6.02M
   if (err == MP_OKAY)
2171
6.02M
       err = mp_addmod_ct(t1, y, modulus, t1);
2172
   /* X = X - T2 */
2173
6.02M
   if (err == MP_OKAY)
2174
6.02M
       err = mp_submod_ct(x, t2, modulus, x);
2175
   /* T2 = 2T2 */
2176
6.02M
   if (err == MP_OKAY)
2177
6.02M
       err = mp_addmod_ct(t2, t2, modulus, t2);
2178
   /* T2 = X + T2 */
2179
6.02M
   if (err == MP_OKAY)
2180
6.02M
       err = mp_addmod_ct(t2, x, modulus, t2);
2181
2182
6.02M
   if (err == MP_OKAY) {
2183
6.02M
       if (!mp_iszero(Q->z)) {
2184
           /* Z = Z * Z' */
2185
6.02M
           err = mp_mul(z, Q->z, z);
2186
6.02M
           if (err == MP_OKAY)
2187
6.02M
               err = mp_montgomery_reduce(z, modulus, mp);
2188
6.02M
       }
2189
6.02M
   }
2190
2191
   /* Z = Z * X */
2192
6.02M
   if (err == MP_OKAY)
2193
6.02M
       err = mp_mul(z, x, z);
2194
6.02M
   if (err == MP_OKAY)
2195
6.02M
       err = mp_montgomery_reduce(z, modulus, mp);
2196
2197
   /* T1 = T1 * X  */
2198
6.02M
   if (err == MP_OKAY)
2199
6.02M
       err = mp_mul(t1, x, t1);
2200
6.02M
   if (err == MP_OKAY)
2201
6.02M
       err = mp_montgomery_reduce(t1, modulus, mp);
2202
2203
   /* X = X * X */
2204
6.02M
   if (err == MP_OKAY)
2205
6.02M
       err = mp_sqr(x, x);
2206
6.02M
   if (err == MP_OKAY)
2207
6.02M
       err = mp_montgomery_reduce(x, modulus, mp);
2208
2209
   /* T2 = T2 * x */
2210
6.02M
   if (err == MP_OKAY)
2211
6.02M
       err = mp_mul(t2, x, t2);
2212
6.02M
   if (err == MP_OKAY)
2213
6.02M
       err = mp_montgomery_reduce(t2, modulus, mp);
2214
2215
   /* T1 = T1 * X  */
2216
6.02M
   if (err == MP_OKAY)
2217
6.02M
       err = mp_mul(t1, x, t1);
2218
6.02M
   if (err == MP_OKAY)
2219
6.02M
       err = mp_montgomery_reduce(t1, modulus, mp);
2220
2221
   /* X = Y*Y */
2222
6.02M
   if (err == MP_OKAY)
2223
6.02M
       err = mp_sqr(y, x);
2224
6.02M
   if (err == MP_OKAY)
2225
6.02M
       err = mp_montgomery_reduce(x, modulus, mp);
2226
2227
   /* X = X - T2 */
2228
6.02M
   if (err == MP_OKAY)
2229
6.02M
       err = mp_submod_ct(x, t2, modulus, x);
2230
   /* T2 = T2 - X */
2231
6.02M
   if (err == MP_OKAY)
2232
6.02M
       err = mp_submod_ct(t2, x, modulus, t2);
2233
   /* T2 = T2 - X */
2234
6.02M
   if (err == MP_OKAY)
2235
6.02M
       err = mp_submod_ct(t2, x, modulus, t2);
2236
   /* T2 = T2 * Y */
2237
6.02M
   if (err == MP_OKAY)
2238
6.02M
       err = mp_mul(t2, y, t2);
2239
6.02M
   if (err == MP_OKAY)
2240
6.02M
       err = mp_montgomery_reduce(t2, modulus, mp);
2241
2242
   /* Y = T2 - T1 */
2243
6.02M
   if (err == MP_OKAY)
2244
6.02M
       err = mp_submod_ct(t2, t1, modulus, y);
2245
   /* Y = Y/2 */
2246
6.02M
   if (err == MP_OKAY)
2247
6.02M
       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.02M
done:
2259
2260
   /* clean up */
2261
6.02M
   mp_clear(t1);
2262
6.02M
   mp_clear(t2);
2263
6.02M
#ifdef WOLFSSL_SMALL_STACK
2264
#ifdef WOLFSSL_SMALL_STACK_CACHE
2265
   if (R->key == NULL)
2266
#endif
2267
6.02M
#endif
2268
6.02M
   {
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.02M
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2275
6.02M
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2276
6.02M
   }
2277
2278
6.02M
   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.02M
}
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.89k
{
2316
2.89k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2317
0
        return ECC_BAD_ARG_E;
2318
0
    }
2319
2320
2.89k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2321
2.86k
        mp_cmp(P->y, modulus) != MP_LT ||
2322
2.82k
        mp_cmp(P->z, modulus) != MP_LT ||
2323
2.82k
        mp_cmp(Q->x, modulus) != MP_LT ||
2324
2.79k
        mp_cmp(Q->y, modulus) != MP_LT ||
2325
2.76k
        mp_cmp(Q->z, modulus) != MP_LT) {
2326
129
        return ECC_OUT_OF_RANGE_E;
2327
129
    }
2328
2329
2.76k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2330
2.89k
}
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.50M
{
2362
6.50M
#if !defined(WOLFSSL_SP_MATH)
2363
6.50M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2364
6.50M
   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.50M
   mp_int *x, *y, *z;
2371
6.50M
   int    err;
2372
2373
6.50M
#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.50M
#endif
2387
6.50M
   {
2388
6.50M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2389
6.50M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2390
6.50M
   #ifdef MP_INT_SIZE_CHECK_NULL
2391
6.50M
      if (t1 == NULL || t2 == NULL) {
2392
178
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2393
178
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2394
178
         return MEMORY_E;
2395
178
      }
2396
6.50M
   #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.50M
   }
2413
2414
6.50M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2415
6.50M
   if (err == MP_OKAY) {
2416
6.50M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2417
6.50M
   }
2418
6.50M
   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.50M
   x = R->x;
2471
6.50M
   y = R->y;
2472
6.50M
   z = R->z;
2473
6.50M
#endif
2474
2475
6.50M
   if (err == MP_OKAY)
2476
6.50M
       err = mp_copy(P->x, x);
2477
6.50M
   if (err == MP_OKAY)
2478
6.50M
       err = mp_copy(P->y, y);
2479
6.50M
   if (err == MP_OKAY)
2480
6.50M
       err = mp_copy(P->z, z);
2481
2482
   /* T1 = Z * Z */
2483
6.50M
   if (err == MP_OKAY)
2484
6.50M
       err = mp_sqr(z, t1);
2485
6.50M
   if (err == MP_OKAY)
2486
6.50M
       err = mp_montgomery_reduce(t1, modulus, mp);
2487
2488
   /* Z = Y * Z */
2489
6.50M
   if (err == MP_OKAY)
2490
6.50M
       err = mp_mul(z, y, z);
2491
6.50M
   if (err == MP_OKAY)
2492
6.50M
       err = mp_montgomery_reduce(z, modulus, mp);
2493
2494
   /* Z = 2Z */
2495
6.50M
   if (err == MP_OKAY)
2496
6.50M
       err = mp_addmod_ct(z, z, modulus, z);
2497
2498
   /* Determine if curve "a" should be used in calc */
2499
6.50M
#ifdef WOLFSSL_CUSTOM_CURVES
2500
6.50M
   if (err == MP_OKAY) {
2501
      /* Use a and prime to determine if a == 3 */
2502
6.50M
      err = mp_submod(modulus, a, modulus, t2);
2503
6.50M
   }
2504
6.50M
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2505
      /* T2 = X * X */
2506
905k
      err = mp_sqr(x, t2);
2507
905k
      if (err == MP_OKAY)
2508
905k
          err = mp_montgomery_reduce(t2, modulus, mp);
2509
      /* T1 = T2 + T1 */
2510
905k
      if (err == MP_OKAY)
2511
905k
          err = mp_addmod_ct(t2, t2, modulus, t1);
2512
      /* T1 = T2 + T1 */
2513
905k
      if (err == MP_OKAY)
2514
905k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2515
905k
   }
2516
5.60M
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2517
      /* use "a" in calc */
2518
2519
      /* T2 = T1 * T1 */
2520
814k
      err = mp_sqr(t1, t2);
2521
814k
      if (err == MP_OKAY)
2522
814k
          err = mp_montgomery_reduce(t2, modulus, mp);
2523
      /* T1 = T2 * a */
2524
814k
      if (err == MP_OKAY)
2525
814k
          err = mp_mulmod(t2, a, modulus, t1);
2526
      /* T2 = X * X */
2527
814k
      if (err == MP_OKAY)
2528
814k
          err = mp_sqr(x, t2);
2529
814k
      if (err == MP_OKAY)
2530
814k
          err = mp_montgomery_reduce(t2, modulus, mp);
2531
      /* T1 = T2 + T1 */
2532
814k
      if (err == MP_OKAY)
2533
814k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2534
      /* T1 = T2 + T1 */
2535
814k
      if (err == MP_OKAY)
2536
814k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2537
      /* T1 = T2 + T1 */
2538
814k
      if (err == MP_OKAY)
2539
814k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2540
814k
   }
2541
4.78M
   else
2542
4.78M
#endif /* WOLFSSL_CUSTOM_CURVES */
2543
4.78M
   {
2544
      /* assumes "a" == 3 */
2545
4.78M
      (void)a;
2546
2547
      /* T2 = X - T1 */
2548
4.78M
      if (err == MP_OKAY)
2549
4.78M
          err = mp_submod_ct(x, t1, modulus, t2);
2550
      /* T1 = X + T1 */
2551
4.78M
      if (err == MP_OKAY)
2552
4.78M
          err = mp_addmod_ct(t1, x, modulus, t1);
2553
      /* T2 = T1 * T2 */
2554
4.78M
      if (err == MP_OKAY)
2555
4.78M
          err = mp_mul(t1, t2, t2);
2556
4.78M
      if (err == MP_OKAY)
2557
4.78M
          err = mp_montgomery_reduce(t2, modulus, mp);
2558
2559
      /* T1 = 2T2 */
2560
4.78M
      if (err == MP_OKAY)
2561
4.78M
          err = mp_addmod_ct(t2, t2, modulus, t1);
2562
      /* T1 = T1 + T2 */
2563
4.78M
      if (err == MP_OKAY)
2564
4.78M
          err = mp_addmod_ct(t1, t2, modulus, t1);
2565
4.78M
   }
2566
2567
   /* Y = 2Y */
2568
6.50M
   if (err == MP_OKAY)
2569
6.50M
       err = mp_addmod_ct(y, y, modulus, y);
2570
   /* Y = Y * Y */
2571
6.50M
   if (err == MP_OKAY)
2572
6.50M
       err = mp_sqr(y, y);
2573
6.50M
   if (err == MP_OKAY)
2574
6.50M
       err = mp_montgomery_reduce(y, modulus, mp);
2575
2576
   /* T2 = Y * Y */
2577
6.50M
   if (err == MP_OKAY)
2578
6.50M
       err = mp_sqr(y, t2);
2579
6.50M
   if (err == MP_OKAY)
2580
6.50M
       err = mp_montgomery_reduce(t2, modulus, mp);
2581
2582
   /* T2 = T2/2 */
2583
6.50M
   if (err == MP_OKAY)
2584
6.50M
       err = mp_div_2_mod_ct(t2, modulus, t2);
2585
2586
   /* Y = Y * X */
2587
6.50M
   if (err == MP_OKAY)
2588
6.50M
       err = mp_mul(y, x, y);
2589
6.50M
   if (err == MP_OKAY)
2590
6.50M
       err = mp_montgomery_reduce(y, modulus, mp);
2591
2592
   /* X = T1 * T1 */
2593
6.50M
   if (err == MP_OKAY)
2594
6.50M
       err = mp_sqr(t1, x);
2595
6.50M
   if (err == MP_OKAY)
2596
6.50M
       err = mp_montgomery_reduce(x, modulus, mp);
2597
2598
   /* X = X - Y */
2599
6.50M
   if (err == MP_OKAY)
2600
6.50M
       err = mp_submod_ct(x, y, modulus, x);
2601
   /* X = X - Y */
2602
6.50M
   if (err == MP_OKAY)
2603
6.50M
       err = mp_submod_ct(x, y, modulus, x);
2604
2605
   /* Y = Y - X */
2606
6.50M
   if (err == MP_OKAY)
2607
6.50M
       err = mp_submod_ct(y, x, modulus, y);
2608
   /* Y = Y * T1 */
2609
6.50M
   if (err == MP_OKAY)
2610
6.50M
       err = mp_mul(y, t1, y);
2611
6.50M
   if (err == MP_OKAY)
2612
6.50M
       err = mp_montgomery_reduce(y, modulus, mp);
2613
2614
   /* Y = Y - T2 */
2615
6.50M
   if (err == MP_OKAY)
2616
6.50M
       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.50M
   mp_clear(t1);
2629
6.50M
   mp_clear(t2);
2630
2631
6.50M
#ifdef WOLFSSL_SMALL_STACK
2632
#ifdef WOLFSSL_SMALL_STACK_CACHE
2633
   if (R->key == NULL)
2634
#endif
2635
6.50M
#endif
2636
6.50M
   {
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.50M
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2643
6.50M
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2644
6.50M
    }
2645
2646
6.50M
   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.50M
}
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.36k
{
2680
4.36k
    if (P == NULL || R == NULL || modulus == NULL)
2681
0
        return ECC_BAD_ARG_E;
2682
2683
4.36k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2684
4.33k
        mp_cmp(P->y, modulus) != MP_LT ||
2685
4.30k
        mp_cmp(P->z, modulus) != MP_LT) {
2686
58
        return ECC_OUT_OF_RANGE_E;
2687
58
    }
2688
2689
4.30k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2690
4.36k
}
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
27.8k
{
2706
27.8k
   int err = MP_OKAY;
2707
27.8k
#if !defined(WOLFSSL_SP_MATH)
2708
27.8k
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2709
27.8k
   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
27.8k
   mp_int *x, *y, *z;
2716
2717
27.8k
   (void)ct;
2718
2719
27.8k
   if (P == NULL || modulus == NULL)
2720
0
       return ECC_BAD_ARG_E;
2721
2722
   /* special case for point at infinity */
2723
27.8k
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2724
659
       err = mp_set(P->x, 0);
2725
659
       if (err == MP_OKAY)
2726
659
           err = mp_set(P->y, 0);
2727
659
       if (err == MP_OKAY)
2728
659
           err = mp_set(P->z, 1);
2729
659
       return err;
2730
659
   }
2731
2732
27.1k
#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
27.1k
#endif
2746
27.1k
   {
2747
27.1k
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2748
27.1k
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2749
27.1k
   #ifdef MP_INT_SIZE_CHECK_NULL
2750
27.1k
      if (t1 == NULL || t2 == NULL) {
2751
35
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2752
35
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2753
35
         return MEMORY_E;
2754
35
      }
2755
27.1k
   #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
27.1k
   }
2772
2773
27.1k
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2774
27.1k
   if (err == MP_OKAY) {
2775
27.1k
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2776
27.1k
   }
2777
27.1k
   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
27.1k
   x = P->x;
2825
27.1k
   y = P->y;
2826
27.1k
   z = P->z;
2827
27.1k
#endif
2828
2829
   /* get 1/z */
2830
27.1k
   if (err == MP_OKAY) {
2831
27.1k
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2832
27.1k
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2833
27.1k
       if (ct) {
2834
15.5k
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2835
15.5k
           if (err == MP_OKAY)
2836
15.3k
               err = mp_montgomery_reduce(t1, modulus, mp);
2837
15.5k
       }
2838
11.6k
       else
2839
11.6k
#endif
2840
11.6k
       {
2841
           /* first map z back to normal */
2842
11.6k
           err = mp_montgomery_reduce(z, modulus, mp);
2843
11.6k
           if (err == MP_OKAY)
2844
11.6k
               err = mp_invmod(z, modulus, t1);
2845
11.6k
       }
2846
27.1k
   }
2847
2848
   /* get 1/z^2 and 1/z^3 */
2849
27.1k
   if (err == MP_OKAY)
2850
26.9k
       err = mp_sqr(t1, t2);
2851
27.1k
   if (err == MP_OKAY)
2852
26.9k
       err = mp_mod(t2, modulus, t2);
2853
27.1k
   if (err == MP_OKAY)
2854
26.9k
       err = mp_mul(t1, t2, t1);
2855
27.1k
   if (err == MP_OKAY)
2856
26.9k
       err = mp_mod(t1, modulus, t1);
2857
2858
   /* multiply against x/y */
2859
27.1k
   if (err == MP_OKAY)
2860
26.8k
       err = mp_mul(x, t2, x);
2861
27.1k
   if (err == MP_OKAY)
2862
26.8k
       err = mp_montgomery_reduce(x, modulus, mp);
2863
27.1k
   if (err == MP_OKAY)
2864
26.8k
       err = mp_mul(y, t1, y);
2865
27.1k
   if (err == MP_OKAY)
2866
26.8k
       err = mp_montgomery_reduce(y, modulus, mp);
2867
2868
27.1k
   if (err == MP_OKAY)
2869
26.8k
       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
27.1k
   mp_clear(t1);
2885
27.1k
   mp_clear(t2);
2886
2887
27.1k
#ifdef WOLFSSL_SMALL_STACK
2888
#ifdef WOLFSSL_SMALL_STACK_CACHE
2889
   if (P->key == NULL)
2890
#endif
2891
27.1k
#endif
2892
27.1k
   {
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
27.1k
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2899
27.1k
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2900
27.1k
   }
2901
2902
27.1k
   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
27.1k
}
2937
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2938
2939
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2940
20.3k
{
2941
20.3k
    return ecc_map_ex(P, modulus, mp, 0);
2942
20.3k
}
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
31.6k
{
3104
31.6k
    int err = MP_OKAY;
3105
3106
31.6k
    err = mp_montgomery_calc_normalization(mu, modulus);
3107
    /* Generate random value to multiply into p->z. */
3108
31.6k
    if (err == MP_OKAY)
3109
31.6k
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3110
    /* Convert to montogmery form. */
3111
31.6k
    if (err == MP_OKAY)
3112
31.5k
        err = mp_mulmod(ty, mu, modulus, ty);
3113
    /* Multiply random value into p->z. */
3114
31.6k
    if (err == MP_OKAY)
3115
31.4k
        err = mp_mul(p->z, ty, p->z);
3116
31.6k
    if (err == MP_OKAY)
3117
31.4k
        err = mp_montgomery_reduce(p->z, modulus, mp);
3118
    /* Square random value for X (X' = X / Z^2). */
3119
31.6k
    if (err == MP_OKAY)
3120
31.4k
        err = mp_sqr(ty, tx);
3121
31.6k
    if (err == MP_OKAY)
3122
31.4k
        err = mp_montgomery_reduce(tx, modulus, mp);
3123
    /* Multiply square of random by random value for Y. */
3124
31.6k
    if (err == MP_OKAY)
3125
31.4k
        err = mp_mul(ty, tx, ty);
3126
31.6k
    if (err == MP_OKAY)
3127
31.3k
        err = mp_montgomery_reduce(ty, modulus, mp);
3128
    /* Multiply square into X. */
3129
31.6k
    if (err == MP_OKAY)
3130
31.3k
        err = mp_mul(p->x, tx, p->x);
3131
31.6k
    if (err == MP_OKAY)
3132
31.3k
        err = mp_montgomery_reduce(p->x, modulus, mp);
3133
    /* Multiply cube into Y (Y' = Y / Z^3). */
3134
31.6k
    if (err == MP_OKAY)
3135
31.3k
        err = mp_mul(p->y, ty, p->y);
3136
31.6k
    if (err == MP_OKAY)
3137
31.3k
        err = mp_montgomery_reduce(p->y, modulus, mp);
3138
3139
31.6k
    return err;
3140
31.6k
}
3141
3142
#ifndef WC_PROTECT_ENCRYPTED_MEM
3143
161k
#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
29.3k
{
3164
29.3k
    int      err = MP_OKAY;
3165
29.3k
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3166
29.3k
    int      i;
3167
29.3k
    int      j = 1;
3168
29.3k
    int      cnt = DIGIT_BIT;
3169
29.3k
    int      t = 0;
3170
29.3k
    mp_digit b;
3171
29.3k
    mp_digit v = 0;
3172
29.3k
    mp_int*  kt = R[2]->x;
3173
29.3k
#ifndef WC_NO_CACHE_RESISTANT
3174
    /* First bit always 1 (fix at end) and swap equals first bit */
3175
29.3k
    int      swap = 1;
3176
29.3k
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3177
29.3k
#endif
3178
29.3k
    int      infinity;
3179
3180
29.3k
#ifndef WC_NO_CACHE_RESISTANT
3181
29.3k
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3182
29.3k
    if (err == MP_OKAY)
3183
29.2k
        err = mp_init(tmp);
3184
29.3k
#endif
3185
3186
    /* Step 1: R[0] = P; R[1] = P */
3187
    /* R[0] = P */
3188
29.3k
    if (err == MP_OKAY)
3189
29.2k
        err = mp_copy(P->x, R[0]->x);
3190
29.3k
    if (err == MP_OKAY)
3191
29.2k
        err = mp_copy(P->y, R[0]->y);
3192
29.3k
    if (err == MP_OKAY)
3193
29.2k
        err = mp_copy(P->z, R[0]->z);
3194
3195
    /* R[1] = P */
3196
29.3k
    if (err == MP_OKAY)
3197
29.2k
        err = mp_copy(P->x, R[1]->x);
3198
29.3k
    if (err == MP_OKAY)
3199
29.2k
        err = mp_copy(P->y, R[1]->y);
3200
29.3k
    if (err == MP_OKAY)
3201
29.2k
        err = mp_copy(P->z, R[1]->z);
3202
3203
    /* Randomize z ordinates to obfuscate timing. */
3204
29.3k
    if ((err == MP_OKAY) && (rng != NULL))
3205
14.9k
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3206
29.3k
    if ((err == MP_OKAY) && (rng != NULL))
3207
14.6k
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3208
3209
29.3k
    if (err == MP_OKAY) {
3210
        /* Order could be one greater than the size of the modulus. */
3211
28.9k
        t = mp_count_bits(modulus) + 1;
3212
28.9k
        v = k->dp[0] >> 1;
3213
28.9k
        if (cnt > t) {
3214
0
            cnt = t;
3215
0
        }
3216
28.9k
        err = mp_copy(k, kt);
3217
28.9k
    }
3218
29.3k
    if (err == MP_OKAY) {
3219
28.9k
        err = mp_grow(kt, (int)modulus->used + 1);
3220
28.9k
    }
3221
    /* Step 2: for j = 1 to t-1 do */
3222
7.41M
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3223
7.38M
        if (--cnt == 0) {
3224
184k
            v = kt->dp[j++];
3225
184k
            cnt = DIGIT_BIT;
3226
184k
        }
3227
3228
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3229
7.38M
        b = v & 1;
3230
7.38M
        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.38M
        swap ^= (int)b;
3240
7.38M
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3241
7.38M
            tmp);
3242
7.38M
        if (err == MP_OKAY) {
3243
7.38M
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3244
7.38M
                tmp);
3245
7.38M
        }
3246
7.38M
        if (err == MP_OKAY) {
3247
7.38M
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3248
7.38M
                tmp);
3249
7.38M
        }
3250
7.38M
        swap = (int)b;
3251
3252
7.38M
        if (err == MP_OKAY)
3253
7.38M
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3254
7.38M
        if (err == MP_OKAY) {
3255
7.38M
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3256
7.38M
                                                                 mp, &infinity);
3257
7.38M
        }
3258
7.38M
#endif /* WC_NO_CACHE_RESISTANT */
3259
7.38M
    }
3260
    /* Step 4: end for */
3261
29.3k
#ifndef WC_NO_CACHE_RESISTANT
3262
    /* Swap back if last bit is 0. */
3263
29.3k
    swap ^= 1;
3264
29.3k
    if (err == MP_OKAY) {
3265
27.5k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3266
27.5k
            tmp);
3267
27.5k
    }
3268
29.3k
    if (err == MP_OKAY) {
3269
27.5k
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3270
27.5k
            tmp);
3271
27.5k
    }
3272
29.3k
    if (err == MP_OKAY) {
3273
27.5k
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3274
27.5k
            tmp);
3275
27.5k
    }
3276
29.3k
#endif
3277
3278
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3279
    /* R[2] = -P */
3280
29.3k
    if (err == MP_OKAY)
3281
27.5k
        err = mp_copy(P->x, R[2]->x);
3282
29.3k
    if (err == MP_OKAY)
3283
27.5k
        err = mp_sub(modulus, P->y, R[2]->y);
3284
29.3k
    if (err == MP_OKAY)
3285
27.5k
        err = mp_copy(P->z, R[2]->z);
3286
    /* Subtract point by adding negative. */
3287
29.3k
    if (err == MP_OKAY) {
3288
27.5k
        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
27.5k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3295
27.5k
            tmp);
3296
27.5k
        if (err == MP_OKAY) {
3297
27.5k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3298
27.5k
                (int)b, tmp);
3299
27.5k
        }
3300
27.5k
        if (err == MP_OKAY) {
3301
27.5k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3302
27.5k
                (int)b, tmp);
3303
27.5k
        }
3304
27.5k
        if (err == MP_OKAY)
3305
27.5k
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3306
27.5k
                                                                 mp, &infinity);
3307
        /* Swap back if necessary. */
3308
27.5k
        if (err == MP_OKAY) {
3309
27.4k
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3310
27.4k
                (int)b, tmp);
3311
27.4k
        }
3312
27.5k
        if (err == MP_OKAY) {
3313
27.4k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3314
27.4k
                (int)b, tmp);
3315
27.4k
        }
3316
27.5k
        if (err == MP_OKAY) {
3317
27.4k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3318
27.4k
                (int)b, tmp);
3319
27.4k
        }
3320
27.5k
#endif
3321
27.5k
    }
3322
3323
    /* Step 6: return R[0] */
3324
29.3k
    if (err == MP_OKAY)
3325
27.4k
        err = mp_copy(R[0]->x, Q->x);
3326
29.3k
    if (err == MP_OKAY)
3327
27.4k
        err = mp_copy(R[0]->y, Q->y);
3328
29.3k
    if (err == MP_OKAY)
3329
27.4k
        err = mp_copy(R[0]->z, Q->z);
3330
3331
29.3k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3332
29.3k
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3333
29.3k
#endif
3334
3335
29.3k
    return err;
3336
29.3k
}
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
23.6k
{
3537
23.6k
   int err = MP_OKAY;
3538
23.6k
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3539
3540
23.6k
   (void)heap;
3541
3542
23.6k
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3543
23.6k
#ifdef MP_INT_SIZE_CHECK_NULL
3544
23.6k
   if (mu == NULL)
3545
27
       err = MEMORY_E;
3546
23.6k
#endif
3547
23.6k
   if (err == MP_OKAY)
3548
23.5k
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3549
23.6k
   if (err == MP_OKAY) {
3550
23.5k
       err = mp_montgomery_calc_normalization(mu, modulus);
3551
3552
23.5k
       if (err == MP_OKAY) {
3553
23.5k
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3554
2.00k
               err = mp_copy(p->x, r->x);
3555
2.00k
               if (err == MP_OKAY)
3556
2.00k
                   err = mp_copy(p->y, r->y);
3557
2.00k
               if (err == MP_OKAY)
3558
2.00k
                   err = mp_copy(p->z, r->z);
3559
2.00k
           }
3560
21.5k
           else {
3561
21.5k
               err = mp_mulmod(p->x, mu, modulus, r->x);
3562
21.5k
               if (err == MP_OKAY)
3563
21.5k
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3564
21.5k
               if (err == MP_OKAY)
3565
21.5k
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3566
21.5k
           }
3567
23.5k
       }
3568
3569
23.5k
       mp_clear(mu);
3570
23.5k
   }
3571
3572
23.6k
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3573
23.6k
   return err;
3574
23.6k
}
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
9.74k
{
3688
9.74k
   ecc_point     *tG, *M[M_POINTS];
3689
#ifdef WOLFSSL_NO_MALLOC
3690
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3691
#endif
3692
9.74k
   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
9.74k
   mp_digit      mp;
3697
3698
   /* init variables */
3699
9.74k
   tG = NULL;
3700
9.74k
   XMEMSET(M, 0, sizeof(M));
3701
3702
9.74k
   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
9.74k
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3709
284
       err = ECC_OUT_OF_RANGE_E;
3710
284
       goto exit;
3711
284
   }
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
37.6k
  for (i = 0; i < M_POINTS; i++) {
3726
  #ifdef WOLFSSL_NO_MALLOC
3727
      M[i] = &lcl_M[i];
3728
  #endif
3729
28.2k
      err = wc_ecc_new_point_ex(&M[i], heap);
3730
28.2k
      if (err != MP_OKAY) {
3731
82
         goto exit;
3732
82
      }
3733
#ifdef WOLFSSL_SMALL_STACK_CACHE
3734
      M[i]->key = key;
3735
#endif
3736
28.2k
  }
3737
3738
   /* make a copy of G in case R==G */
3739
#ifdef WOLFSSL_NO_MALLOC
3740
   tG = &lcl_tG;
3741
#endif
3742
9.38k
   err = wc_ecc_new_point_ex(&tG, heap);
3743
9.38k
   if (err != MP_OKAY) {
3744
23
       goto exit;
3745
23
   }
3746
9.35k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3747
24
       goto exit;
3748
24
   }
3749
3750
   /* init montgomery reduction */
3751
9.33k
   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.33k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3759
9.33k
#endif
3760
   /* map R back from projective space */
3761
9.33k
   if (err == MP_OKAY && map)
3762
8.98k
       err = ecc_map(R, modulus, mp);
3763
3764
9.74k
exit:
3765
3766
   /* done */
3767
9.74k
   wc_ecc_del_point_ex(tG, heap);
3768
38.9k
   for (i = 0; i < M_POINTS; i++) {
3769
29.2k
       wc_ecc_del_point_ex(M[i], heap);
3770
29.2k
   }
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
9.74k
   return err;
3783
9.33k
}
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
15.6k
{
3841
15.6k
    int err;
3842
15.6k
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3843
3844
15.6k
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3845
15.6k
#ifdef MP_INT_SIZE_CHECK_NULL
3846
15.6k
    if (t == NULL) {
3847
8
        err = MEMORY_E;
3848
8
    }
3849
15.5k
    else
3850
15.5k
#endif
3851
15.5k
    {
3852
15.5k
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3853
15.5k
    }
3854
15.6k
    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
15.5k
        err = mp_sub_d(order, 1, t);
3860
15.5k
        if (err == MP_OKAY) {
3861
15.5k
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3862
15.5k
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3863
15.5k
            if (err == MP_OKAY) {
3864
15.5k
                err = mp_sub(modulus, tG->y, t);
3865
15.5k
            }
3866
15.5k
            if (err == MP_OKAY) {
3867
15.5k
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3868
15.5k
            }
3869
15.5k
            if (err == MP_OKAY) {
3870
15.5k
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3871
15.5k
            }
3872
15.5k
        }
3873
3874
15.5k
        mp_free(t);
3875
15.5k
    }
3876
3877
15.6k
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3878
15.6k
    return err;
3879
15.6k
}
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
10.6k
{
3899
10.6k
   ecc_point     *tG, *M[M_POINTS];
3900
#ifdef WOLFSSL_NO_MALLOC
3901
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3902
#endif
3903
10.6k
   int           i, err;
3904
#ifdef WOLFSSL_SMALL_STACK_CACHE
3905
   ecc_key       *key = NULL;
3906
#endif
3907
10.6k
   mp_digit      mp;
3908
3909
10.6k
   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
10.6k
   if (mp_count_bits(k) > mp_count_bits(order)) {
3923
20
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3924
20
      return ECC_OUT_OF_RANGE_E;
3925
20
   }
3926
3927
   /* init variables */
3928
10.6k
   tG = NULL;
3929
10.6k
   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
42.3k
   for (i = 0; i < M_POINTS; i++) {
3943
   #ifdef WOLFSSL_NO_MALLOC
3944
      M[i] = &lcl_M[i];
3945
   #endif
3946
31.8k
      err = wc_ecc_new_point_ex(&M[i], heap);
3947
31.8k
      if (err != MP_OKAY) {
3948
97
         goto exit;
3949
97
      }
3950
#ifdef WOLFSSL_SMALL_STACK_CACHE
3951
      M[i]->key = key;
3952
#endif
3953
31.8k
  }
3954
3955
   /* make a copy of G in case R==G */
3956
#ifdef WOLFSSL_NO_MALLOC
3957
   tG = &lcl_tG;
3958
#endif
3959
10.5k
   err = wc_ecc_new_point_ex(&tG, heap);
3960
10.5k
   if (err != MP_OKAY) {
3961
26
       goto exit;
3962
26
   }
3963
10.5k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3964
63
       goto exit;
3965
63
   }
3966
3967
   /* init montgomery reduction */
3968
10.4k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3969
0
      goto exit;
3970
0
   }
3971
3972
10.4k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3973
10.4k
#ifdef ECC_TIMING_RESISTANT
3974
10.4k
   if (err == MP_OKAY) {
3975
10.2k
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3976
10.2k
   }
3977
#else
3978
   (void)order;
3979
#endif
3980
   /* map R back from projective space */
3981
10.4k
   if (err == MP_OKAY && map)
3982
0
      err = ecc_map(R, modulus, mp);
3983
3984
10.6k
exit:
3985
3986
   /* done */
3987
10.6k
   wc_ecc_del_point_ex(tG, heap);
3988
42.6k
   for (i = 0; i < M_POINTS; i++) {
3989
31.9k
      wc_ecc_del_point_ex(M[i], heap);
3990
31.9k
   }
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
10.6k
   return err;
3998
10.4k
}
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.48k
{
4059
1.48k
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4060
13
        mp_zero(R->x);
4061
13
        mp_zero(R->y);
4062
13
        mp_set(R->z, 1);
4063
13
        return MP_OKAY;
4064
13
    }
4065
1.47k
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4066
1.48k
}
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
288k
{
4079
288k
   int err = MP_OKAY;
4080
288k
   ecc_point* p;
4081
4082
288k
   if (point == NULL) {
4083
0
       return BAD_FUNC_ARG;
4084
0
   }
4085
4086
288k
   p = *point;
4087
288k
   if (p == NULL) {
4088
288k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4089
288k
   }
4090
288k
   if (p == NULL) {
4091
1.66k
      return MEMORY_E;
4092
1.66k
   }
4093
287k
   XMEMSET(p, 0, sizeof(ecc_point));
4094
4095
287k
   if (*point == NULL)
4096
287k
       p->isAllocated = 1;
4097
4098
287k
#ifndef ALT_ECC_SIZE
4099
287k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4100
287k
   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
287k
   *point = p;
4116
287k
   (void)heap;
4117
287k
   return err;
4118
288k
} /* wc_ecc_new_point_ex */
4119
4120
ecc_point* wc_ecc_new_point_h(void* heap)
4121
43.5k
{
4122
43.5k
    ecc_point* p = NULL;
4123
43.5k
    (void)wc_ecc_new_point_ex(&p, heap);
4124
43.5k
    return p;
4125
43.5k
}
4126
4127
ecc_point* wc_ecc_new_point(void)
4128
12.6k
{
4129
12.6k
   ecc_point* p = NULL;
4130
12.6k
   (void)wc_ecc_new_point_ex(&p, NULL);
4131
12.6k
   return p;
4132
12.6k
}
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
345k
{
4139
345k
   if (p != NULL) {
4140
287k
      mp_clear(p->x);
4141
287k
      mp_clear(p->y);
4142
287k
      mp_clear(p->z);
4143
287k
      if (p->isAllocated)
4144
287k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4145
287k
   }
4146
345k
   (void)heap;
4147
345k
}
4148
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4149
380
{
4150
380
   wc_ecc_del_point_ex(p, heap);
4151
380
}
4152
void wc_ecc_del_point(ecc_point* p)
4153
110k
{
4154
110k
    wc_ecc_del_point_ex(p, NULL);
4155
110k
}
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
887k
{
4173
887k
    int ret;
4174
4175
    /* prevents null arguments */
4176
887k
    if (p == NULL || r == NULL)
4177
0
        return ECC_BAD_ARG_E;
4178
4179
887k
    ret = mp_copy(p->x, r->x);
4180
887k
    if (ret != MP_OKAY)
4181
2
        return ret;
4182
887k
    ret = mp_copy(p->y, r->y);
4183
887k
    if (ret != MP_OKAY)
4184
2
        return ret;
4185
887k
    ret = mp_copy(p->z, r->z);
4186
887k
    if (ret != MP_OKAY)
4187
2
        return ret;
4188
4189
886k
    return MP_OKAY;
4190
887k
}
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.91k
{
4200
2.91k
    int ret;
4201
4202
    /* prevents null arguments */
4203
2.91k
    if (a == NULL || b == NULL)
4204
0
        return BAD_FUNC_ARG;
4205
4206
2.91k
    ret = mp_cmp(a->x, b->x);
4207
2.91k
    if (ret != MP_EQ)
4208
2.17k
        return ret;
4209
743
    ret = mp_cmp(a->y, b->y);
4210
743
    if (ret != MP_EQ)
4211
396
        return ret;
4212
347
    ret = mp_cmp(a->z, b->z);
4213
347
    if (ret != MP_EQ)
4214
24
        return ret;
4215
4216
323
    return MP_EQ;
4217
347
}
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
48.4k
{
4226
48.4k
   int x;
4227
4228
48.4k
   if (n >= (int)ECC_SET_COUNT)
4229
0
       return 0;
4230
4231
1.11M
   for (x = 0; ecc_sets[x].size != 0; x++)
4232
1.06M
       ;
4233
   /* -1 is a valid index --- indicating that the domain params
4234
      were supplied by the user */
4235
48.4k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4236
48.4k
      return 1;
4237
48.4k
   }
4238
4239
0
   return 0;
4240
48.4k
}
4241
4242
int wc_ecc_get_curve_idx(int curve_id)
4243
39.5k
{
4244
39.5k
    int curve_idx;
4245
504k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4246
504k
        if (curve_id == ecc_sets[curve_idx].id)
4247
39.4k
            break;
4248
504k
    }
4249
39.5k
    if (ecc_sets[curve_idx].size == 0) {
4250
111
        return ECC_CURVE_INVALID;
4251
111
    }
4252
39.4k
    return curve_idx;
4253
39.5k
}
4254
4255
int wc_ecc_get_curve_id(int curve_idx)
4256
1.76k
{
4257
1.76k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4258
1.76k
        return ecc_sets[curve_idx].id;
4259
1.76k
    }
4260
0
    return ECC_CURVE_INVALID;
4261
1.76k
}
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.14k
{
4270
1.14k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4271
1.14k
    if (curve_idx == ECC_CURVE_INVALID)
4272
0
        return ECC_BAD_ARG_E;
4273
1.14k
    return ecc_sets[curve_idx].size;
4274
1.14k
}
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
27.4k
{
4591
27.4k
    const ecc_set_type* ecc_set = NULL;
4592
4593
27.4k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4594
27.4k
        ecc_set = &ecc_sets[curve_idx];
4595
27.4k
    }
4596
27.4k
    return ecc_set;
4597
27.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.40k
{
4657
1.40k
   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.40k
   (void)err;
4665
4666
1.40k
   if (private_key == NULL || public_key == NULL || out == NULL ||
4667
1.40k
                                                            outlen == NULL) {
4668
0
       return BAD_FUNC_ARG;
4669
0
   }
4670
4671
1.40k
#ifdef WOLF_CRYPTO_CB
4672
1.40k
    #ifndef WOLF_CRYPTO_CB_FIND
4673
1.40k
    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.40k
#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.40k
   if (private_key->type != ECC_PRIVATEKEY &&
4688
326
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4689
0
      return ECC_BAD_ARG_E;
4690
0
   }
4691
4692
   /* Verify domain params supplied */
4693
1.40k
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4694
1.40k
       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.40k
   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.40k
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4733
1.40k
#endif /* WOLFSSL_ATECC508A */
4734
1.40k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4735
4736
1.40k
   return err;
4737
1.40k
}
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
241
{
4747
241
    int err = MP_OKAY;
4748
241
    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
241
    (void)point;
4871
241
    (void)out;
4872
241
    (void)outlen;
4873
241
    (void)k;
4874
241
#endif
4875
#if defined(WOLFSSL_SP_MATH)
4876
    {
4877
        err = WC_KEY_SIZE_E;
4878
        goto errout;
4879
    }
4880
#else
4881
241
    {
4882
241
        ecc_point* result = NULL;
4883
        #ifdef WOLFSSL_NO_MALLOC
4884
        ecc_point  lcl_result;
4885
        #endif
4886
241
        int x = 0;
4887
241
        mp_digit mp = 0;
4888
241
        DECLARE_CURVE_SPECS(3);
4889
4890
        /* load curve info */
4891
241
        ALLOC_CURVE_SPECS(3, err);
4892
241
        if (err == MP_OKAY) {
4893
240
            err = wc_ecc_curve_load(private_key->dp, &curve,
4894
240
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4895
240
                 ECC_CURVE_FIELD_ORDER));
4896
240
        }
4897
4898
241
        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
240
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4908
240
        if (err != MP_OKAY) {
4909
1
            wc_ecc_curve_free(curve);
4910
1
            FREE_CURVE_SPECS();
4911
1
            goto errout;
4912
1
        }
4913
4914
239
#ifdef ECC_TIMING_RESISTANT
4915
239
        if (private_key->rng == NULL) {
4916
0
            err = MISSING_RNG_E;
4917
0
        }
4918
239
#endif
4919
4920
239
        if (err == MP_OKAY) {
4921
            /* Map in a separate call as this should be constant time */
4922
239
#ifdef ECC_TIMING_RESISTANT
4923
239
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4924
239
                                              curve->order, private_key->rng, 0,
4925
239
                                              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
239
        }
4931
239
        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
217
            err = mp_montgomery_setup(curve->prime, &mp);
4939
217
        }
4940
239
        if (err == MP_OKAY) {
4941
            /* Use constant time map if compiled in */
4942
217
            err = ecc_map_ex(result, curve->prime, mp, 1);
4943
217
        }
4944
239
        if (err == MP_OKAY) {
4945
217
            x = mp_unsigned_bin_size(curve->prime);
4946
217
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4947
0
                err = BUFFER_E;
4948
0
            }
4949
217
        }
4950
4951
239
        if (err == MP_OKAY) {
4952
217
            XMEMSET(out, 0, (size_t)x);
4953
217
            err = mp_to_unsigned_bin(result->x, out +
4954
217
                                     (x - mp_unsigned_bin_size(result->x)));
4955
217
        }
4956
239
        *outlen = (word32)x;
4957
4958
239
        mp_forcezero(result->x);
4959
239
        mp_forcezero(result->y);
4960
239
        wc_ecc_del_point_ex(result, private_key->heap);
4961
4962
239
        wc_ecc_curve_free(curve);
4963
239
        FREE_CURVE_SPECS();
4964
239
    }
4965
0
#endif
4966
4967
241
  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
241
    return err;
4976
239
}
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.40k
{
5084
1.40k
    int err;
5085
5086
1.40k
    if (private_key == NULL || point == NULL || out == NULL ||
5087
1.40k
                                                            outlen == NULL) {
5088
0
        return BAD_FUNC_ARG;
5089
0
    }
5090
5091
    /* type valid? */
5092
1.40k
    if (private_key->type != ECC_PRIVATEKEY &&
5093
326
            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.40k
    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.40k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5105
5106
1.40k
    switch (private_key->state) {
5107
1.40k
        case ECC_STATE_NONE:
5108
1.40k
        case ECC_STATE_SHARED_SEC_GEN:
5109
1.40k
            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.40k
            {
5119
1.40k
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5120
1.40k
                    out, outlen);
5121
1.40k
            }
5122
1.40k
            if (err < 0) {
5123
82
                break;
5124
82
            }
5125
1.32k
            FALL_THROUGH;
5126
5127
1.32k
        case ECC_STATE_SHARED_SEC_RES:
5128
1.32k
            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.32k
            err = 0;
5142
1.32k
            break;
5143
5144
0
        default:
5145
0
            err = BAD_STATE_E;
5146
1.40k
    } /* switch */
5147
5148
1.40k
    RESTORE_VECTOR_REGISTERS();
5149
5150
    /* if async pending then return and skip done cleanup below */
5151
1.40k
    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.40k
    private_key->state = ECC_STATE_NONE;
5160
5161
1.40k
    return err;
5162
1.40k
}
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.35k
{
5219
7.35k
    int err = MP_OKAY;
5220
7.35k
    DECLARE_CURVE_SPECS(3);
5221
5222
7.35k
    if (p == NULL)
5223
0
        return BAD_FUNC_ARG;
5224
5225
    /* is the IDX valid ?  */
5226
7.35k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5227
0
       return ECC_BAD_ARG_E;
5228
0
    }
5229
5230
7.35k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5231
5232
7.35k
    ALLOC_CURVE_SPECS(3, err);
5233
7.35k
    if (err == MP_OKAY) {
5234
7.02k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5235
7.02k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5236
7.02k
                                ECC_CURVE_FIELD_BF);
5237
7.02k
    }
5238
5239
7.35k
    if (err == MP_OKAY) {
5240
7.02k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5241
7.02k
    }
5242
5243
7.35k
    wc_ecc_curve_free(curve);
5244
7.35k
    FREE_CURVE_SPECS();
5245
5246
7.35k
    RESTORE_VECTOR_REGISTERS();
5247
5248
7.35k
    return err;
5249
7.35k
}
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.0k
{
5259
11.0k
    if (p == NULL)
5260
0
        return BAD_FUNC_ARG;
5261
11.0k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5262
3.59k
        return 1;
5263
5264
7.47k
    return 0;
5265
11.0k
}
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
44.6k
{
5271
44.6k
#ifndef WC_NO_RNG
5272
44.6k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5273
44.6k
    int err;
5274
44.6k
    byte buf[ECC_MAXSIZE_GEN];
5275
5276
44.6k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5277
44.6k
                                                                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
44.6k
    size += 8;
5284
5285
    /* make up random string */
5286
44.6k
    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
44.6k
    if (err == 0)
5293
44.3k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5294
5295
    /* the key should be smaller than the order of base point */
5296
44.6k
    if (err == MP_OKAY) {
5297
44.3k
        if (mp_cmp(k, order) != MP_LT) {
5298
44.0k
            err = mp_mod(k, order, k);
5299
44.0k
        }
5300
44.3k
    }
5301
5302
    /* quick sanity check to make sure we're not dealing with a 0 key */
5303
44.6k
    if (err == MP_OKAY) {
5304
44.3k
        if (mp_iszero(k) == MP_YES)
5305
256
          err = MP_ZERO_E;
5306
44.3k
    }
5307
5308
44.6k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5309
#ifdef WOLFSSL_CHECK_MEM_ZERO
5310
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5311
#endif
5312
5313
44.6k
    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
44.6k
}
5370
5371
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5372
51.6k
{
5373
    /* make sure required key variables are reset */
5374
51.6k
    key->state = ECC_STATE_NONE;
5375
51.6k
}
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.35k
{
5396
3.35k
    int err = MP_OKAY;
5397
3.35k
#ifdef HAVE_ECC_MAKE_PUB
5398
3.35k
    ecc_point* pub;
5399
3.35k
#endif /* HAVE_ECC_MAKE_PUB */
5400
5401
3.35k
    (void)rng;
5402
5403
3.35k
    if (key == NULL) {
5404
0
        return BAD_FUNC_ARG;
5405
0
    }
5406
5407
3.35k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5408
5409
3.35k
#ifdef HAVE_ECC_MAKE_PUB
5410
    /* if ecc_point passed in then use it as output for public key point */
5411
3.35k
    if (pubOut != NULL) {
5412
838
        pub = pubOut;
5413
838
    }
5414
2.51k
    else {
5415
        /* caching public key making it a ECC_PRIVATEKEY instead of
5416
           ECC_PRIVATEKEY_ONLY */
5417
2.51k
        pub = &key->pubkey;
5418
2.51k
        key->type = ECC_PRIVATEKEY_ONLY;
5419
2.51k
    }
5420
5421
3.35k
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5422
3.34k
            mp_isneg(ecc_get_k(key)) ||
5423
3.34k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5424
41
        err = ECC_PRIV_KEY_E;
5425
41
    }
5426
5427
3.35k
    if (err == MP_OKAY) {
5428
3.30k
    #ifndef ALT_ECC_SIZE
5429
3.30k
        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.30k
    }
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.35k
    { /* 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.35k
    if (err == MP_OKAY) {
5492
        /* Multi-Precision Math: compute public curve */
5493
3.30k
        mp_digit mp = 0;
5494
3.30k
        ecc_point* base = NULL;
5495
    #ifdef WOLFSSL_NO_MALLOC
5496
        ecc_point  lcl_base;
5497
        base = &lcl_base;
5498
    #endif
5499
3.30k
        err = wc_ecc_new_point_ex(&base, key->heap);
5500
5501
        /* read in the x/y for this key */
5502
3.30k
        if (err == MP_OKAY)
5503
3.23k
            err = mp_copy(curve->Gx, base->x);
5504
3.30k
        if (err == MP_OKAY)
5505
3.23k
            err = mp_copy(curve->Gy, base->y);
5506
3.30k
        if (err == MP_OKAY)
5507
3.23k
            err = mp_montgomery_setup(curve->prime, &mp);
5508
3.30k
        if (err == MP_OKAY)
5509
3.23k
            err = mp_set(base->z, 1);
5510
5511
        /* make the public key */
5512
3.30k
        if (err == MP_OKAY) {
5513
            /* Map in a separate call as this should be constant time */
5514
3.23k
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5515
3.23k
                                 curve->prime, curve->order, rng, 0, key->heap);
5516
3.23k
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5517
21
               err = MEMORY_E;
5518
21
            }
5519
3.23k
        }
5520
3.30k
        if (err == MP_OKAY) {
5521
            /* Use constant time map if compiled in */
5522
3.11k
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5523
3.11k
        }
5524
5525
3.30k
        wc_ecc_del_point_ex(base, key->heap);
5526
3.30k
    }
5527
3.35k
#endif /* WOLFSSL_SP_MATH */
5528
3.35k
    } /* END: Software Crypto */
5529
5530
3.35k
    if (err != MP_OKAY
5531
    #ifdef WOLFSSL_ASYNC_CRYPT
5532
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5533
    #endif
5534
3.35k
    ) {
5535
        /* clean up if failed */
5536
271
    #ifndef ALT_ECC_SIZE
5537
271
        mp_clear(pub->x);
5538
271
        mp_clear(pub->y);
5539
271
        mp_clear(pub->z);
5540
271
    #endif
5541
271
    }
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.35k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5551
2.51k
        key->type = ECC_PRIVATEKEY;
5552
2.51k
    }
5553
5554
3.35k
    RESTORE_VECTOR_REGISTERS();
5555
5556
3.35k
    return err;
5557
3.35k
}
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.95k
{
5571
5.95k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5572
5573
5.95k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5574
5.95k
}
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.43k
{
5587
2.43k
    int err = MP_OKAY;
5588
2.43k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5589
5590
2.43k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5591
5592
2.43k
    if (key == NULL) {
5593
0
        return BAD_FUNC_ARG;
5594
0
    }
5595
5596
    /* load curve info */
5597
2.43k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5598
2.43k
    if (err == MP_OKAY) {
5599
2.40k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5600
2.40k
    }
5601
2.43k
    if (err == MP_OKAY) {
5602
2.40k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5603
2.40k
    }
5604
5605
2.43k
    wc_ecc_curve_free(curve);
5606
2.43k
    FREE_CURVE_SPECS();
5607
5608
2.43k
    return err;
5609
2.43k
}
5610
5611
5612
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5613
        int curve_id, int flags)
5614
12.3k
{
5615
12.3k
    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
12.3k
    if (key == NULL || rng == NULL) {
5631
0
        return BAD_FUNC_ARG;
5632
0
    }
5633
5634
    /* make sure required variables are reset */
5635
12.3k
    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
12.3k
    err = wc_ecc_set_curve(key, keysize, curve_id);
5655
12.3k
    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
12.3k
    key->flags = (byte)flags;
5662
5663
12.3k
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5664
12.3k
    #ifndef WOLF_CRYPTO_CB_FIND
5665
12.3k
    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
12.3k
#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
12.3k
   { /* software key gen */
5939
#if defined(WOLFSSL_SP_MATH)
5940
        err = WC_KEY_SIZE_E;
5941
#else
5942
12.3k
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5943
5944
        /* setup the key variables */
5945
12.3k
#ifndef ALT_ECC_SIZE
5946
12.3k
        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
12.3k
        if (err == MP_OKAY) {
5955
12.3k
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5956
12.3k
            if (err != MP_OKAY) {
5957
51
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5958
51
            }
5959
12.3k
        }
5960
5961
12.3k
        if (err == MP_OKAY) {
5962
12.3k
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5963
12.3k
            if (err != MP_OKAY) {
5964
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5965
0
            }
5966
12.3k
        }
5967
5968
        /* generate k */
5969
12.3k
        if (err == MP_OKAY) {
5970
12.3k
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5971
12.3k
            if (err != MP_OKAY) {
5972
197
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5973
197
            }
5974
12.3k
        }
5975
5976
        /* generate public key from k */
5977
12.3k
        if (err == MP_OKAY) {
5978
12.1k
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5979
12.1k
            if (err != MP_OKAY) {
5980
1.78k
                WOLFSSL_MSG("ecc_make_pub_ex failed");
5981
1.78k
            }
5982
12.1k
        }
5983
5984
12.3k
        if (err == MP_OKAY
5985
        #ifdef WOLFSSL_ASYNC_CRYPT
5986
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
5987
        #endif
5988
12.3k
        ) {
5989
10.3k
            key->type = ECC_PRIVATEKEY;
5990
10.3k
        }
5991
2.03k
        else {
5992
            /* cleanup these on failure case only */
5993
2.03k
            mp_forcezero(key->k);
5994
2.03k
        }
5995
5996
        /* cleanup allocations */
5997
12.3k
        wc_ecc_curve_free(curve);
5998
12.3k
        FREE_CURVE_SPECS();
5999
12.3k
#endif /* WOLFSSL_SP_MATH */
6000
12.3k
    }
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
12.3k
#endif /* HAVE_ECC_MAKE_PUB */
6019
6020
12.3k
    return err;
6021
12.3k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6022
12.3k
}
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.0k
{
6028
14.0k
    int err;
6029
6030
14.0k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6031
6032
14.0k
    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.0k
    RESTORE_VECTOR_REGISTERS();
6050
6051
14.0k
    return err;
6052
14.0k
}
6053
6054
WOLFSSL_ABI
6055
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6056
14.0k
{
6057
14.0k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6058
14.0k
}
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.5k
{
6121
37.5k
    int devId = INVALID_DEVID;
6122
37.5k
    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.5k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6129
37.5k
    if (key) {
6130
33.5k
        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.5k
    }
6135
6136
37.5k
    return key;
6137
37.5k
}
6138
6139
6140
WOLFSSL_ABI
6141
void wc_ecc_key_free(ecc_key* key)
6142
103k
{
6143
103k
    if (key) {
6144
33.5k
        void* heap = key->heap;
6145
6146
33.5k
        wc_ecc_free(key);
6147
33.5k
        ForceZero(key, sizeof(ecc_key));
6148
33.5k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6149
33.5k
        (void)heap;
6150
33.5k
    }
6151
103k
}
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
57.7k
{
6172
57.7k
    int ret      = 0;
6173
6174
57.7k
    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
57.7k
    XMEMSET(key, 0, sizeof(ecc_key));
6183
57.7k
    key->state = ECC_STATE_NONE;
6184
6185
57.7k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6186
57.7k
    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
57.7k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6214
57.7k
#ifndef WOLFSSL_ECC_BLIND_K
6215
57.7k
                                                                      NULL, NULL
6216
#else
6217
                                                                key->kb, key->ku
6218
#endif
6219
57.7k
                        );
6220
57.7k
    if (ret != MP_OKAY) {
6221
0
        return MEMORY_E;
6222
0
    }
6223
57.7k
#endif /* ALT_ECC_SIZE */
6224
#ifdef WOLFSSL_ECC_BLIND_K
6225
    mp_forcezero(key->kb);
6226
#endif
6227
57.7k
#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
57.7k
    key->heap = heap;
6243
57.7k
#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
57.7k
    return ret;
6286
57.7k
}
6287
6288
WOLFSSL_ABI
6289
int wc_ecc_init(ecc_key* key)
6290
2.06k
{
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.06k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6295
2.06k
#endif
6296
2.06k
}
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
592
{
6354
592
    if (key == NULL) {
6355
0
        return BAD_FUNC_ARG;
6356
0
    }
6357
592
    key->flags |= flags;
6358
592
    return 0;
6359
592
}
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
4.01k
{
6707
4.01k
    int err;
6708
4.01k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6709
4.01k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6710
4.01k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6711
4.01k
#endif
6712
#ifdef NO_ASN
6713
    word32 keySz;
6714
#endif
6715
6716
4.01k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6717
178
        return ECC_BAD_ARG_E;
6718
178
    }
6719
3.83k
    if (inlen > WC_MAX_DIGEST_SIZE) {
6720
128
        return BAD_LENGTH_E;
6721
128
    }
6722
6723
3.70k
#ifdef WOLF_CRYPTO_CB
6724
3.70k
    #ifndef WOLF_CRYPTO_CB_FIND
6725
3.70k
    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.70k
#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.70k
    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.70k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6754
3.70k
    #ifdef MP_INT_SIZE_CHECK_NULL
6755
3.70k
    if (r == NULL)
6756
5
        return MEMORY_E;
6757
3.69k
    #endif
6758
3.69k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6759
3.69k
    #ifdef MP_INT_SIZE_CHECK_NULL
6760
3.69k
    if (s == NULL) {
6761
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6762
5
        return MEMORY_E;
6763
5
    }
6764
3.69k
    #endif
6765
6766
3.69k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6767
3.69k
    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.69k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6773
3.69k
    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.69k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6787
3.69k
#endif
6788
3.69k
    if (err < 0) {
6789
172
        mp_clear(r);
6790
172
        mp_clear(s);
6791
172
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6792
172
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6793
172
        return err;
6794
172
    }
6795
6796
3.52k
#ifndef NO_ASN
6797
    /* encoded with DSA header */
6798
3.52k
    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.52k
    mp_clear(r);
6819
3.52k
    mp_clear(s);
6820
6821
3.52k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6822
3.52k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6823
3.52k
#endif /* WOLFSSL_ASYNC_CRYPT */
6824
3.52k
    return err;
6825
3.69k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6826
3.69k
}
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.82k
{
6908
1.82k
    int err = MP_OKAY;
6909
1.82k
    int loop_check = 0;
6910
1.82k
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6911
6912
1.82k
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6913
1.82k
#ifdef MP_INT_SIZE_CHECK_NULL
6914
1.82k
    if (b == NULL)
6915
2
        err = MEMORY_E;
6916
1.82k
#endif
6917
6918
1.82k
    if (err == MP_OKAY) {
6919
1.82k
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6920
1.82k
    }
6921
6922
1.82k
#ifdef WOLFSSL_CUSTOM_CURVES
6923
    /* if custom curve, apply params to pubkey */
6924
1.82k
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6925
0
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6926
0
    }
6927
1.82k
#endif
6928
6929
1.82k
    if (err == MP_OKAY) {
6930
        /* Generate blinding value - non-zero value. */
6931
2.04k
        do {
6932
2.04k
            if (++loop_check > 64) {
6933
2
                 err = RNG_FAILURE_E;
6934
2
                 break;
6935
2
            }
6936
6937
2.04k
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6938
2.04k
        }
6939
2.04k
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6940
1.82k
        loop_check = 0;
6941
1.82k
    }
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.84k
    for (; err == MP_OKAY;) {
6949
1.83k
        if (++loop_check > 64) {
6950
16
             err = RNG_FAILURE_E;
6951
16
             break;
6952
16
        }
6953
1.82k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6954
1.82k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6955
1.82k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6956
1.82k
#ifndef WOLFSSL_NO_MALLOC
6957
1.82k
        if (key->sign_k != NULL)
6958
#else
6959
        if (key->sign_k_set)
6960
#endif
6961
570
        {
6962
570
            if (loop_check > 1) {
6963
0
               err = RNG_FAILURE_E;
6964
0
               break;
6965
0
            }
6966
6967
            /* use provided sign_k */
6968
570
            err = mp_copy(key->sign_k, pubkey->k);
6969
570
            if (err != MP_OKAY) break;
6970
6971
            /* free sign_k, so only used once */
6972
570
            mp_forcezero(key->sign_k);
6973
570
#ifndef WOLFSSL_NO_MALLOC
6974
570
            mp_free(key->sign_k);
6975
570
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6976
570
            key->sign_k = NULL;
6977
#else
6978
            key->sign_k_set = 0;
6979
#endif
6980
570
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6981
570
            loop_check = 64;
6982
570
    #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
570
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6994
570
        }
6995
1.25k
        else
6996
1.25k
#endif
6997
1.25k
        {
6998
1.25k
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6999
1.25k
                    WC_ECC_FLAG_NONE);
7000
1.25k
        }
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.82k
        if (err != MP_OKAY) break;
7011
7012
        /* find r = x1 mod n */
7013
1.80k
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7014
1.80k
        if (err != MP_OKAY) break;
7015
7016
1.80k
        if (mp_iszero(r) == MP_NO) {
7017
1.80k
            mp_int* kp = ecc_get_k(pubkey);
7018
1.80k
            mp_int* ep = kp;
7019
1.80k
            mp_int* x  = ecc_get_k(key);
7020
7021
            /* Blind after getting. */
7022
1.80k
            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.80k
            err = mp_mulmod(kp, b, curve->order, kp);
7029
1.80k
            if (err != MP_OKAY) break;
7030
7031
            /* k' = 1/k.b
7032
                  = 1/k' */
7033
1.80k
            err = mp_invmod(kp, curve->order, kp);
7034
1.80k
            if (err != MP_OKAY) break;
7035
7036
            /* s = x.r */
7037
1.80k
            err = mp_mulmod(x, r, curve->order, s);
7038
1.80k
            if (err != MP_OKAY) break;
7039
7040
            /* s = x.r/k.b
7041
                 = k'.s */
7042
1.80k
            err = mp_mulmod(kp, s, curve->order, s);
7043
1.80k
            if (err != MP_OKAY) break;
7044
7045
            /* e' = e/k.b
7046
                  = e.k' */
7047
1.80k
            err = mp_mulmod(kp, e, curve->order, ep);
7048
1.80k
            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.79k
            err = mp_addmod_ct(ep, s, curve->order, s);
7053
1.79k
            if (err != MP_OKAY) break;
7054
7055
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7056
                 = b.s */
7057
1.79k
            err = mp_mulmod(s, b, curve->order, s);
7058
1.79k
            if (err != MP_OKAY) break;
7059
7060
1.79k
            if (mp_iszero(s) == MP_NO) {
7061
                /* sign successful */
7062
1.78k
                break;
7063
1.78k
            }
7064
1.79k
         }
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.82k
    mp_forcezero(b);
7073
1.82k
    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.82k
    return err;
7079
1.82k
}
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.83k
{
7219
1.83k
   int    err = 0;
7220
1.83k
#if !defined(WOLFSSL_SP_MATH)
7221
1.83k
   mp_int* e;
7222
1.83k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7223
1.83k
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7224
1.83k
#endif
7225
7226
1.83k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7227
1.83k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7228
1.83k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7229
1.83k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7230
1.83k
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7231
1.83k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7232
#else
7233
   DECLARE_CURVE_SPECS(1);
7234
#endif
7235
1.83k
#endif /* !WOLFSSL_SP_MATH */
7236
7237
1.83k
   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.83k
   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.83k
   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.83k
   (void)inlen;
7305
1.83k
#endif
7306
7307
1.83k
#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.83k
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7317
1.83k
#ifdef MP_INT_SIZE_CHECK_NULL
7318
1.83k
   if (e_lcl == NULL) {
7319
2
      return MEMORY_E;
7320
2
   }
7321
1.82k
#endif
7322
1.82k
   e = e_lcl;
7323
1.82k
#endif
7324
7325
   /* get the hash and load it as a bignum into 'e' */
7326
   /* init the bignums */
7327
1.82k
   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.82k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7334
1.82k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7335
1.82k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7336
1.82k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7337
1.82k
    if (err == MP_OKAY)
7338
1.82k
        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.82k
   if (err == MP_OKAY) {
7358
       /* we may need to truncate if hash is longer than key size */
7359
1.82k
       word32 orderBits = (word32)mp_count_bits(curve->order);
7360
7361
       /* truncate down to byte size, may be all that's needed */
7362
1.82k
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7363
194
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7364
1.82k
       err = mp_read_unsigned_bin(e, in, inlen);
7365
7366
       /* may still need bit truncation too */
7367
1.82k
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7368
152
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7369
1.82k
   }
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.82k
   if (err == MP_OKAY) {
7449
1.82k
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7450
7451
1.82k
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7452
1.82k
           err=MEMORY_E);
7453
1.82k
       if (WC_VAR_OK(pubkey))
7454
1.82k
       {
7455
       /* don't use async for key, since we don't support async return here */
7456
1.82k
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7457
1.82k
           if (err == MP_OKAY) {
7458
1.82k
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7459
1.82k
              wc_ecc_free(pubkey);
7460
1.82k
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7461
1.82k
           }
7462
1.82k
       }
7463
1.82k
   }
7464
7465
1.82k
   mp_clear(e);
7466
1.82k
   wc_ecc_curve_free(curve);
7467
1.82k
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7468
1.82k
   FREE_CURVE_SPECS();
7469
1.82k
#endif /* !WOLFSSL_SP_MATH */
7470
7471
1.82k
   return err;
7472
1.82k
}
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
708
{
7805
708
    int ret = MP_OKAY;
7806
708
    DECLARE_CURVE_SPECS(1);
7807
7808
708
    if (k == NULL || klen == 0 || key == NULL) {
7809
0
        return BAD_FUNC_ARG;
7810
0
    }
7811
7812
708
    ALLOC_CURVE_SPECS(1, ret);
7813
708
    if (ret == MP_OKAY) {
7814
699
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7815
699
    }
7816
7817
708
    if (ret != 0) {
7818
9
        FREE_CURVE_SPECS();
7819
9
        return ret;
7820
9
    }
7821
7822
699
#ifndef WOLFSSL_NO_MALLOC
7823
699
    if (key->sign_k == NULL) {
7824
699
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7825
699
                                                            DYNAMIC_TYPE_ECC);
7826
699
        if (key->sign_k) {
7827
692
            ret = mp_init(key->sign_k);
7828
692
        }
7829
7
        else {
7830
7
            ret = MEMORY_E;
7831
7
        }
7832
699
    }
7833
699
#endif
7834
7835
699
    if (ret == 0) {
7836
692
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7837
692
    }
7838
699
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7839
42
        ret = MP_VAL;
7840
42
    }
7841
#ifdef WOLFSSL_NO_MALLOC
7842
    if (ret == 0) {
7843
        key->sign_k_set = 1;
7844
    }
7845
#endif
7846
7847
699
    wc_ecc_curve_free(curve);
7848
699
    FREE_CURVE_SPECS();
7849
699
    return ret;
7850
708
}
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
550
{
7859
550
#ifndef WOLFSSL_ECC_CURVE_STATIC
7860
550
    if (curve->prime != NULL)
7861
194
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7862
550
    if (curve->Af != NULL)
7863
172
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7864
550
    if (curve->Bf != NULL)
7865
165
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7866
550
    if (curve->order != NULL)
7867
150
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7868
550
    if (curve->Gx != NULL)
7869
153
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7870
550
    if (curve->Gy != NULL)
7871
153
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7872
550
#endif
7873
7874
550
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7875
7876
550
    (void)heap;
7877
550
}
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
29.2k
{
7887
29.2k
    if (key == NULL) {
7888
1
        return 0;
7889
1
    }
7890
7891
29.2k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7892
29.2k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7893
29.2k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7894
29.2k
#ifndef WOLFSSL_NO_MALLOC
7895
29.2k
    if (key->sign_k != NULL)
7896
197
#endif
7897
197
    {
7898
197
        mp_forcezero(key->sign_k);
7899
197
        mp_free(key->sign_k);
7900
197
#ifndef WOLFSSL_NO_MALLOC
7901
197
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7902
197
#endif
7903
197
    }
7904
29.2k
#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
29.2k
    mp_clear(key->pubkey.x);
7948
29.2k
    mp_clear(key->pubkey.y);
7949
29.2k
    mp_clear(key->pubkey.z);
7950
7951
#ifdef ALT_ECC_SIZE
7952
    if (key->k)
7953
#endif
7954
29.2k
        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
29.2k
#ifdef WOLFSSL_CUSTOM_CURVES
7967
29.2k
    if (key->deallocSet && key->dp != NULL)
7968
0
        wc_ecc_free_curve(key->dp, key->heap);
7969
29.2k
#endif
7970
7971
#ifdef WOLFSSL_CHECK_MEM_ZERO
7972
    wc_MemZero_Check(key, sizeof(ecc_key));
7973
#endif
7974
7975
29.2k
    return 0;
7976
29.2k
}
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
6.84M
{
8008
6.84M
    int err;
8009
8010
6.84M
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8011
        /* A is infinity. */
8012
320k
        err = wc_ecc_copy_point(B, R);
8013
320k
    }
8014
6.52M
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8015
        /* B is infinity. */
8016
34.5k
        err = wc_ecc_copy_point(A, R);
8017
34.5k
    }
8018
6.48M
    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.36k
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8021
            /* A = B */
8022
604
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8023
604
        }
8024
759
        else {
8025
            /* A = -B */
8026
759
            err = mp_set(R->x, 0);
8027
759
            if (err == MP_OKAY)
8028
759
                err = mp_set(R->y, 0);
8029
759
            if (err == MP_OKAY)
8030
759
                err = mp_set(R->z, 1);
8031
759
            if ((err == MP_OKAY) && (infinity != NULL))
8032
300
                *infinity = 1;
8033
759
        }
8034
1.36k
    }
8035
6.48M
    else {
8036
6.48M
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8037
6.48M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8038
            /* When all zero then should have done a double */
8039
26.9k
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8040
660
                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
660
                else {
8050
660
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8051
660
                }
8052
660
            }
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.3k
                    *infinity = 1;
8062
26.3k
            }
8063
26.9k
        }
8064
6.48M
    }
8065
8066
6.84M
    return err;
8067
6.84M
}
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.29M
{
8077
7.29M
    int err;
8078
8079
7.29M
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8080
        /* P is infinity. */
8081
255k
        err = wc_ecc_copy_point(P, R);
8082
255k
    }
8083
7.03M
    else {
8084
7.03M
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8085
7.03M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8086
117k
           err = mp_set(R->x, 0);
8087
117k
           if (err == MP_OKAY)
8088
117k
               err = mp_set(R->y, 0);
8089
117k
           if (err == MP_OKAY)
8090
117k
               err = mp_set(R->z, 1);
8091
117k
        }
8092
7.03M
    }
8093
8094
7.29M
    return err;
8095
7.29M
}
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.18k
{
8110
3.18k
    int err = MP_OKAY;
8111
3.18k
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8112
8113
3.18k
    (void)heap;
8114
8115
3.18k
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8116
3.18k
#ifdef MP_INT_SIZE_CHECK_NULL
8117
3.18k
    if (mu == NULL)
8118
2
       err = MEMORY_E;
8119
3.18k
#endif
8120
3.18k
    if (err == MP_OKAY) {
8121
3.18k
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8122
3.18k
    }
8123
3.18k
    if (err == MP_OKAY) {
8124
3.18k
        err = mp_montgomery_calc_normalization(mu, modulus);
8125
8126
3.18k
        if (err == MP_OKAY) {
8127
            /* copy ones ... */
8128
3.18k
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8129
3.18k
        }
8130
8131
3.18k
        if (err == MP_OKAY)
8132
3.18k
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8133
3.18k
        if (err == MP_OKAY)
8134
3.18k
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8135
8136
3.18k
        if (err == MP_OKAY)
8137
3.18k
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8138
3.18k
        if (err == MP_OKAY)
8139
3.18k
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8140
3.18k
        if (err == MP_OKAY)
8141
3.18k
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8142
8143
        /* done with mu */
8144
3.18k
        mp_clear(mu);
8145
3.18k
    }
8146
8147
3.18k
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8148
8149
3.18k
    return err;
8150
3.18k
}
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.26k
{
8174
#ifdef WOLFSSL_SMALL_STACK_CACHE
8175
  ecc_key        *key = NULL;
8176
#endif
8177
4.26k
#ifdef WOLFSSL_SMALL_STACK
8178
4.26k
  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.26k
  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.26k
  unsigned char* tA = NULL;
8191
4.26k
  unsigned char* tB = NULL;
8192
4.26k
#endif
8193
4.26k
  int            err = MP_OKAY, first, x, y;
8194
4.26k
  mp_digit       mp = 0;
8195
8196
  /* argchks */
8197
4.26k
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8198
4.26k
                                                         modulus == NULL) {
8199
0
     return ECC_BAD_ARG_E;
8200
0
  }
8201
8202
4.26k
#ifndef WOLFSSL_NO_MALLOC
8203
  /* allocate memory */
8204
4.26k
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8205
4.26k
  if (tA == NULL) {
8206
3
     return MP_MEM;
8207
3
  }
8208
4.26k
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8209
4.26k
  if (tB == NULL) {
8210
3
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8211
3
     return MP_MEM;
8212
3
  }
8213
4.26k
#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.26k
#ifdef WOLFSSL_SMALL_STACK
8224
4.26k
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8225
4.26k
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8226
4.26k
  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.25k
#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.25k
  XMEMSET(tA, 0, ECC_BUFSIZE);
8267
4.25k
  XMEMSET(tB, 0, ECC_BUFSIZE);
8268
#ifndef WOLFSSL_SMALL_STACK
8269
  XMEMSET(precomp, 0, sizeof(precomp));
8270
#else
8271
4.25k
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8272
4.25k
#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.25k
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8280
4.25k
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8281
4.25k
  len  = MAX(lenA, lenB);
8282
8283
  /* sanity check */
8284
4.25k
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8285
0
    err = BAD_FUNC_ARG;
8286
0
  }
8287
8288
4.25k
  if (err == MP_OKAY) {
8289
    /* extract and justify kA */
8290
4.25k
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8291
8292
    /* extract and justify kB */
8293
4.25k
    if (err == MP_OKAY)
8294
4.25k
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8295
8296
    /* allocate the table */
8297
4.25k
    if (err == MP_OKAY) {
8298
72.0k
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8299
        #ifdef WOLFSSL_NO_MALLOC
8300
            precomp[x] = &lcl_precomp[x];
8301
        #endif
8302
67.8k
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8303
67.8k
            if (err != MP_OKAY)
8304
31
                break;
8305
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8306
            precomp[x]->key = key;
8307
        #endif
8308
67.8k
        }
8309
4.25k
    }
8310
4.25k
  }
8311
8312
4.25k
  if (err == MP_OKAY)
8313
    /* init montgomery reduction */
8314
4.22k
    err = mp_montgomery_setup(modulus, &mp);
8315
8316
4.25k
  if (err == MP_OKAY) {
8317
4.22k
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8318
4.22k
  }
8319
8320
4.25k
  if (err == MP_OKAY) {
8321
    /* precomp [i,0](A + B) table */
8322
4.22k
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8323
4.22k
  }
8324
4.25k
  if (err == MP_OKAY) {
8325
4.21k
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8326
4.21k
                                                          a, modulus, mp, NULL);
8327
4.21k
  }
8328
8329
4.25k
  if (err == MP_OKAY) {
8330
    /* precomp [0,i](A + B) table */
8331
4.21k
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8332
4.21k
  }
8333
4.25k
  if (err == MP_OKAY) {
8334
4.21k
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8335
4.21k
                                                             modulus, mp, NULL);
8336
4.21k
  }
8337
8338
4.25k
  if (err == MP_OKAY) {
8339
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8340
16.8k
    for (x = 1; x < 4; x++) {
8341
50.6k
      for (y = 1; y < 4; y++) {
8342
37.9k
        if (err == MP_OKAY) {
8343
37.8k
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8344
37.8k
                                                  precomp[x+(y<<2)], a, modulus,
8345
37.8k
                                                  mp, NULL);
8346
37.8k
        }
8347
37.9k
      }
8348
12.6k
    }
8349
4.21k
  }
8350
8351
4.25k
  if (err == MP_OKAY) {
8352
4.19k
    nibble  = 3;
8353
4.19k
    first   = 1;
8354
4.19k
    bitbufA = tA[0];
8355
4.19k
    bitbufB = tB[0];
8356
8357
    /* for every byte of the multiplicands */
8358
518k
    for (x = 0; x < (int)len || nibble != 3; ) {
8359
        /* grab a nibble */
8360
514k
        if (++nibble == 4) {
8361
128k
            if (x == (int)len) break;
8362
128k
            bitbufA = tA[x];
8363
128k
            bitbufB = tB[x];
8364
128k
            nibble  = 0;
8365
128k
            x++;
8366
128k
        }
8367
8368
        /* extract two bits from both, shift/update */
8369
514k
        nA = (bitbufA >> 6) & 0x03;
8370
514k
        nB = (bitbufB >> 6) & 0x03;
8371
514k
        bitbufA = (bitbufA << 2) & 0xFF;
8372
514k
        bitbufB = (bitbufB << 2) & 0xFF;
8373
8374
        /* if both zero, if first, continue */
8375
514k
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8376
2.03k
            continue;
8377
2.03k
        }
8378
8379
        /* double twice, only if this isn't the first */
8380
512k
        if (first == 0) {
8381
            /* double twice */
8382
506k
            if (err == MP_OKAY)
8383
506k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8384
506k
            if (err == MP_OKAY)
8385
506k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8386
9
            else
8387
9
                break;
8388
506k
        }
8389
8390
        /* if not both zero */
8391
512k
        if ((nA != 0) || (nB != 0)) {
8392
460k
            unsigned int i = nA + (nB<<2);
8393
460k
            if (first == 1) {
8394
                /* if first, copy from table */
8395
5.41k
                first = 0;
8396
5.41k
                if (err == MP_OKAY)
8397
5.41k
                    err = mp_copy(precomp[i]->x, C->x);
8398
8399
5.41k
                if (err == MP_OKAY)
8400
5.41k
                    err = mp_copy(precomp[i]->y, C->y);
8401
8402
5.41k
                if (err == MP_OKAY)
8403
5.41k
                    err = mp_copy(precomp[i]->z, C->z);
8404
0
                else
8405
0
                    break;
8406
454k
            } else {
8407
                /* if not first, add from table */
8408
454k
                if (err == MP_OKAY)
8409
454k
                    err = ecc_projective_add_point_safe(C, precomp[i],
8410
454k
                                                        C, a, modulus, mp,
8411
454k
                                                        &first);
8412
454k
                if (err != MP_OKAY)
8413
16
                    break;
8414
454k
            }
8415
460k
        }
8416
512k
    }
8417
4.19k
  }
8418
8419
  /* reduce to affine */
8420
4.25k
  if (err == MP_OKAY)
8421
4.17k
    err = ecc_map(C, modulus, mp);
8422
8423
  /* clean up */
8424
72.3k
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8425
68.1k
     wc_ecc_del_point_ex(precomp[x], heap);
8426
68.1k
  }
8427
8428
4.25k
  ForceZero(tA, ECC_BUFSIZE);
8429
4.25k
  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.25k
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8442
4.25k
#ifndef WOLFSSL_NO_MALLOC
8443
4.25k
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8444
4.25k
  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.25k
  return err;
8450
4.26k
}
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
6.32k
{
8484
6.32k
    int err;
8485
8486
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8487
    mp_int *r = NULL, *s = NULL;
8488
#else
8489
6.32k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8490
6.32k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8491
6.32k
#endif
8492
#ifdef WOLFSSL_ASYNC_CRYPT
8493
    int isPrivateKeyOnly = 0;
8494
#endif
8495
#ifdef NO_ASN
8496
    word32 keySz;
8497
#endif
8498
8499
6.32k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8500
51
        return ECC_BAD_ARG_E;
8501
51
    }
8502
6.27k
    if (hashlen > WC_MAX_DIGEST_SIZE) {
8503
68
        return BAD_LENGTH_E;
8504
68
    }
8505
8506
6.20k
#ifdef WOLF_CRYPTO_CB
8507
6.20k
    #ifndef WOLF_CRYPTO_CB_FIND
8508
6.20k
    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
6.20k
#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
6.20k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8534
6.20k
        DYNAMIC_TYPE_ECC);
8535
6.20k
    #ifdef MP_INT_SIZE_CHECK_NULL
8536
6.20k
    if (r == NULL)
8537
14
        return MEMORY_E;
8538
6.18k
    #endif
8539
6.18k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8540
6.18k
        DYNAMIC_TYPE_ECC);
8541
6.18k
    #ifdef MP_INT_SIZE_CHECK_NULL
8542
6.18k
    if (s == NULL) {
8543
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8544
5
        return MEMORY_E;
8545
5
    }
8546
6.18k
    #endif
8547
6.18k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8548
6.18k
    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
6.18k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8554
6.18k
    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
6.18k
#endif /* WOLFSSL_ASYNC_CRYPT */
8560
8561
6.18k
    switch (key->state) {
8562
6.18k
        case ECC_STATE_NONE:
8563
6.18k
        case ECC_STATE_VERIFY_DECODE:
8564
6.18k
            key->state = ECC_STATE_VERIFY_DECODE;
8565
8566
            /* default to invalid signature */
8567
6.18k
            *res = 0;
8568
8569
6.18k
    #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
6.18k
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8580
6.18k
        #endif
8581
6.18k
            if (err < 0) {
8582
52
                break;
8583
52
            }
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
6.13k
            FALL_THROUGH;
8603
8604
6.13k
        case ECC_STATE_VERIFY_DO:
8605
6.13k
            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
6.13k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8612
8613
6.13k
        #ifndef WOLFSSL_ASYNC_CRYPT
8614
            /* done with R/S */
8615
6.13k
            mp_clear(r);
8616
6.13k
            mp_clear(s);
8617
6.13k
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8618
6.13k
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8619
6.13k
        #ifdef MP_INT_SIZE_CHECK_NULL
8620
6.13k
            r = NULL;
8621
6.13k
            s = NULL;
8622
6.13k
        #endif
8623
6.13k
        #endif
8624
8625
6.13k
            if (err < 0) {
8626
205
                break;
8627
205
            }
8628
5.92k
            FALL_THROUGH;
8629
8630
5.92k
        case ECC_STATE_VERIFY_RES:
8631
5.92k
            key->state = ECC_STATE_VERIFY_RES;
8632
5.92k
            err = 0;
8633
5.92k
            break;
8634
8635
0
        default:
8636
0
            err = BAD_STATE_E;
8637
6.18k
    }
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
6.18k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8653
6.18k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8654
6.18k
#endif
8655
8656
    /* make sure required variables are reset */
8657
6.18k
    wc_ecc_reset(key);
8658
6.18k
    return err;
8659
6.18k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8660
6.18k
}
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.34k
{
8668
3.34k
    int err = MP_OKAY;
8669
3.34k
    DECLARE_CURVE_SPECS(1);
8670
8671
3.34k
    ALLOC_CURVE_SPECS(1, err);
8672
3.34k
    if (err == MP_OKAY) {
8673
3.34k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8674
3.34k
    }
8675
3.34k
    if (err != 0) {
8676
2
        FREE_CURVE_SPECS();
8677
2
        return err;
8678
2
    }
8679
8680
3.34k
    if (mp_iszero(r) || mp_iszero(s)) {
8681
23
        err = MP_ZERO_E;
8682
23
    }
8683
3.34k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8684
27
        err = MP_VAL;
8685
27
    }
8686
3.34k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8687
46
        err = MP_VAL;
8688
46
    }
8689
8690
3.34k
    wc_ecc_curve_free(curve);
8691
3.34k
    FREE_CURVE_SPECS();
8692
3.34k
    return err;
8693
3.34k
}
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.64k
{
8700
4.64k
    (void)r;
8701
4.64k
    (void)s;
8702
4.64k
    (void)hash;
8703
4.64k
    (void)hashlen;
8704
4.64k
    (void)res;
8705
4.64k
    (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.64k
    return NOT_COMPILED_IN;
8852
4.64k
}
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.24k
{
8858
3.24k
   int        err;
8859
3.24k
   ecc_point* mG = NULL;
8860
3.24k
   ecc_point* mQ = NULL;
8861
#ifdef WOLFSSL_NO_MALLOC
8862
   ecc_point  lcl_mG;
8863
   ecc_point  lcl_mQ;
8864
#endif
8865
3.24k
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8866
3.24k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8867
3.24k
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8868
3.24k
#endif
8869
3.24k
   mp_int*    e;
8870
3.24k
   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.24k
   mp_int*    u1 = NULL;     /* Will be e. */
8876
3.24k
   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.24k
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8887
3.24k
#ifdef MP_INT_SIZE_CHECK_NULL
8888
3.24k
   if (e_lcl == NULL) {
8889
2
       return MEMORY_E;
8890
2
   }
8891
3.23k
#endif
8892
3.23k
   e = e_lcl;
8893
8894
3.23k
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8895
3.23k
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8896
3.23k
   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.23k
   if (err == MP_OKAY) {
8907
       /* we may need to truncate if hash is longer than key size */
8908
3.23k
       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.23k
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8912
375
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8913
3.23k
       err = mp_read_unsigned_bin(e, hash, hashlen);
8914
8915
       /* may still need bit truncation too */
8916
3.23k
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8917
277
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8918
3.23k
   }
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.23k
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8957
3.23k
#ifdef MP_INT_SIZE_CHECK_NULL
8958
3.23k
   if (w == NULL) {
8959
2
       err = MEMORY_E;
8960
2
   }
8961
3.23k
#endif
8962
8963
3.23k
   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.23k
       u1 = e;
8976
3.23k
       u2 = w;
8977
3.23k
#endif
8978
3.23k
       v = w;
8979
3.23k
   }
8980
3.23k
   if (err == MP_OKAY) {
8981
3.23k
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8982
3.23k
   }
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.23k
   if (err == MP_OKAY) {
8994
   #ifdef WOLFSSL_NO_MALLOC
8995
       mG = &lcl_mG;
8996
   #endif
8997
3.23k
       err = wc_ecc_new_point_ex(&mG, key->heap);
8998
3.23k
   }
8999
3.23k
   if (err == MP_OKAY) {
9000
   #ifdef WOLFSSL_NO_MALLOC
9001
       mQ = &lcl_mQ;
9002
   #endif
9003
3.23k
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9004
3.23k
   }
9005
9006
   /*  w  = s^-1 mod n */
9007
3.23k
   if (err == MP_OKAY)
9008
3.23k
       err = mp_invmod(s, curve->order, w);
9009
9010
   /* u1 = ew */
9011
3.23k
   if (err == MP_OKAY)
9012
3.22k
       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.23k
   if (err == MP_OKAY)
9022
3.22k
       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.23k
   if (err == MP_OKAY)
9032
3.21k
       err = mp_copy(curve->Gx, mG->x);
9033
3.23k
   if (err == MP_OKAY)
9034
3.21k
       err = mp_copy(curve->Gy, mG->y);
9035
3.23k
   if (err == MP_OKAY)
9036
3.21k
       err = mp_set(mG->z, 1);
9037
9038
3.23k
   if (err == MP_OKAY)
9039
3.21k
       err = mp_copy(key->pubkey.x, mQ->x);
9040
3.23k
   if (err == MP_OKAY)
9041
3.21k
       err = mp_copy(key->pubkey.y, mQ->y);
9042
3.23k
   if (err == MP_OKAY)
9043
3.21k
       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.23k
    if (err == MP_OKAY) {
9120
3.21k
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9121
3.21k
                                                                     key->heap);
9122
3.21k
    }
9123
3.23k
#endif /* ECC_SHAMIR */
9124
3.23k
#endif /* FREESCALE_LTC_ECC */
9125
9126
   /* v = X_x1 mod n */
9127
3.23k
   if (err == MP_OKAY)
9128
3.15k
       err = mp_mod(mG->x, curve->order, v);
9129
9130
   /* does v == r */
9131
3.23k
   if (err == MP_OKAY) {
9132
3.15k
       if (mp_cmp(v, r) == MP_EQ)
9133
2.92k
           *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.15k
   }
9140
9141
   /* cleanup */
9142
3.23k
   wc_ecc_del_point_ex(mG, key->heap);
9143
3.23k
   wc_ecc_del_point_ex(mQ, key->heap);
9144
9145
3.23k
   mp_clear(e);
9146
3.23k
   mp_clear(w);
9147
3.23k
   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.23k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9157
3.23k
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9158
3.23k
#endif
9159
9160
3.23k
   return err;
9161
3.23k
}
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.34k
{
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.34k
   int           err;
9186
3.34k
   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.34k
   int curveLoaded = 0;
9204
3.34k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9205
3.34k
#endif
9206
9207
3.34k
   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.34k
   *res = 0;
9212
9213
   /* is the IDX valid ?  */
9214
3.34k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9215
0
      return ECC_BAD_ARG_E;
9216
0
   }
9217
9218
3.34k
   err = wc_ecc_check_r_s_range(key, r, s);
9219
3.34k
   if (err != MP_OKAY) {
9220
98
      return err;
9221
98
   }
9222
9223
3.24k
   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.24k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9338
1.19k
      WOLFSSL_MSG("Verify called with private key, generating public part");
9339
1.19k
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9340
1.19k
      if (err != MP_OKAY) {
9341
2
          return err;
9342
2
      }
9343
1.18k
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9344
1.18k
      if (err != MP_OKAY) {
9345
0
          FREE_CURVE_SPECS();
9346
0
          return err;
9347
0
      }
9348
1.18k
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9349
1.18k
      if (err != MP_OKAY) {
9350
3
           WOLFSSL_MSG("Unable to extract public key");
9351
3
           wc_ecc_curve_free(curve);
9352
3
           FREE_CURVE_SPECS();
9353
3
           return err;
9354
3
      }
9355
1.18k
      curveLoaded = 1;
9356
1.18k
  }
9357
9358
3.24k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9359
3.24k
  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.24k
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9368
3.24k
   if (!curveLoaded) {
9369
2.05k
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9370
2.05k
       if (err != 0) {
9371
2
          return err;
9372
2
       }
9373
       /* read in the specs for this curve */
9374
2.05k
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9375
2.05k
       if (err != 0) {
9376
0
          FREE_CURVE_SPECS();
9377
0
          return err;
9378
0
       }
9379
2.05k
   }
9380
9381
3.24k
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9382
3.24k
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9383
9384
3.24k
   (void)curveLoaded;
9385
3.24k
   wc_ecc_curve_free(curve);
9386
3.24k
   FREE_CURVE_SPECS();
9387
3.24k
#endif /* HAVE_ECC_VERIFY_HELPER */
9388
9389
3.24k
   (void)keySz;
9390
3.24k
   (void)hashlen;
9391
9392
3.24k
   return err;
9393
3.24k
#endif /* WOLFSSL_STM32_PKA */
9394
3.24k
}
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
85
{
9405
85
    int err = 0;
9406
85
#ifdef HAVE_COMP_KEY
9407
85
    int compressed = 0;
9408
85
#endif
9409
85
    int keysize;
9410
85
    byte pointType;
9411
9412
#ifndef HAVE_COMP_KEY
9413
    (void)shortKeySize;
9414
#endif
9415
9416
85
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9417
85
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9418
0
        return ECC_BAD_ARG_E;
9419
9420
    /* must be odd */
9421
85
    if ((inLen & 1) == 0) {
9422
0
        return ECC_BAD_ARG_E;
9423
0
    }
9424
9425
    /* clear if previously allocated */
9426
85
    mp_clear(point->x);
9427
85
    mp_clear(point->y);
9428
85
    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
85
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9440
85
#endif
9441
85
    if (err != MP_OKAY)
9442
0
        return MEMORY_E;
9443
9444
85
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9445
9446
    /* check for point type (4, 2, or 3) */
9447
85
    pointType = in[0];
9448
85
    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
85
    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
85
    inLen -= 1;
9463
85
    in += 1;
9464
9465
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9466
     * is true */
9467
85
#ifdef HAVE_COMP_KEY
9468
85
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9469
#else
9470
    keysize = (int)(inLen>>1);
9471
#endif
9472
9473
    /* read data */
9474
85
    if (err == MP_OKAY)
9475
85
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9476
9477
85
#ifdef HAVE_COMP_KEY
9478
85
    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
85
#endif
9614
9615
85
    if (err == MP_OKAY) {
9616
85
#ifdef HAVE_COMP_KEY
9617
85
        if (compressed == 0)
9618
85
#endif
9619
85
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9620
85
    }
9621
85
    if (err == MP_OKAY)
9622
85
        err = mp_set(point->z, 1);
9623
9624
85
    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
85
    RESTORE_VECTOR_REGISTERS();
9631
9632
85
    return err;
9633
85
}
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
131
{
9639
131
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9640
131
}
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
337
{
9662
337
    int    ret = MP_OKAY;
9663
337
    word32 numlen;
9664
337
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9665
9666
337
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9667
0
        return ECC_BAD_ARG_E;
9668
9669
337
    numlen = (word32)ecc_sets[curve_idx].size;
9670
9671
    /* return length needed only */
9672
337
    if (point != NULL && out == NULL && outLen != NULL) {
9673
19
        *outLen = 1 + 2*numlen;
9674
19
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9675
19
    }
9676
9677
318
    if (point == NULL || out == NULL || outLen == NULL)
9678
0
        return ECC_BAD_ARG_E;
9679
9680
318
    if (*outLen < (1 + 2*numlen)) {
9681
16
        *outLen = 1 + 2*numlen;
9682
16
        return BUFFER_E;
9683
16
    }
9684
9685
    /* Sanity check the ordinates' sizes. */
9686
302
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9687
274
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9688
77
        return ECC_BAD_ARG_E;
9689
77
    }
9690
9691
    /* store byte point type */
9692
225
    out[0] = ECC_POINT_UNCOMP;
9693
9694
225
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9695
225
        return MEMORY_E);
9696
9697
    /* pad and store x */
9698
148
    XMEMSET(buf, 0, ECC_BUFSIZE);
9699
148
    ret = mp_to_unsigned_bin(point->x, buf +
9700
148
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9701
148
    if (ret != MP_OKAY)
9702
8
        goto done;
9703
140
    XMEMCPY(out+1, buf, numlen);
9704
9705
    /* pad and store y */
9706
140
    XMEMSET(buf, 0, ECC_BUFSIZE);
9707
140
    ret = mp_to_unsigned_bin(point->y, buf +
9708
140
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9709
140
    if (ret != MP_OKAY)
9710
9
        goto done;
9711
131
    XMEMCPY(out+1+numlen, buf, numlen);
9712
9713
131
    *outLen = 1 + 2*numlen;
9714
9715
148
done:
9716
148
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9717
9718
148
    return ret;
9719
131
}
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.2k
{
9786
12.2k
   int    ret = MP_OKAY;
9787
12.2k
   word32 numlen;
9788
12.2k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9789
12.2k
   word32 pubxlen, pubylen;
9790
9791
   /* return length needed only */
9792
12.2k
   if (key != NULL && out == NULL && outLen != NULL) {
9793
      /* if key hasn't been setup assume max bytes for size estimation */
9794
1.86k
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9795
1.86k
      *outLen = 1 + 2 * numlen;
9796
1.86k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9797
1.86k
   }
9798
9799
10.3k
   if (key == NULL || out == NULL || outLen == NULL)
9800
0
      return ECC_BAD_ARG_E;
9801
9802
10.3k
   if (key->type == ECC_PRIVATEKEY_ONLY)
9803
155
       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.1k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9822
1.26k
       return ECC_BAD_ARG_E;
9823
1.26k
   }
9824
9825
8.91k
   numlen = (word32)key->dp->size;
9826
9827
    /* verify room in out buffer */
9828
8.91k
   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
8.91k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9835
8.91k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9836
8.91k
   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
8.91k
   out[0] = ECC_POINT_UNCOMP;
9843
9844
8.91k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9845
8.91k
       return MEMORY_E);
9846
9847
   /* pad and store x */
9848
8.85k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9849
8.85k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9850
8.85k
   if (ret != MP_OKAY)
9851
8
      goto done;
9852
8.85k
   XMEMCPY(out+1, buf, numlen);
9853
9854
   /* pad and store y */
9855
8.85k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9856
8.85k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9857
8.85k
   if (ret != MP_OKAY)
9858
10
      goto done;
9859
8.84k
   XMEMCPY(out+1+numlen, buf, numlen);
9860
9861
8.84k
   *outLen = 1 + 2*numlen;
9862
9863
8.85k
done:
9864
8.85k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9865
9866
8.85k
   return ret;
9867
8.84k
}
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.22k
{
9876
7.22k
    if (compressed == 0)
9877
3.92k
        return wc_ecc_export_x963(key, out, outLen);
9878
3.30k
#ifdef HAVE_COMP_KEY
9879
3.30k
    else
9880
3.30k
        return wc_ecc_export_x963_compressed(key, out, outLen);
9881
#else
9882
    return NOT_COMPILED_IN;
9883
#endif
9884
7.22k
}
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.19k
{
9893
3.19k
#if !defined(WOLFSSL_SP_MATH)
9894
3.19k
   int err;
9895
3.19k
#ifdef WOLFSSL_SMALL_STACK
9896
3.19k
   mp_int* t1;
9897
3.19k
   mp_int* t2;
9898
#else
9899
   mp_int  t1[1], t2[1];
9900
#endif
9901
9902
3.19k
#ifdef WOLFSSL_SMALL_STACK
9903
3.19k
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9904
3.19k
   if (t1 == NULL)
9905
72
       return MEMORY_E;
9906
3.12k
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9907
3.12k
   if (t2 == NULL) {
9908
43
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9909
43
       return MEMORY_E;
9910
43
   }
9911
3.08k
#endif
9912
9913
3.08k
   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.08k
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9920
9921
   /* compute y^2 */
9922
3.08k
   if (err == MP_OKAY)
9923
3.08k
       err = mp_sqr(ecp->y, t1);
9924
9925
   /* compute x^3 */
9926
3.08k
   if (err == MP_OKAY)
9927
3.06k
       err = mp_sqr(ecp->x, t2);
9928
3.08k
   if (err == MP_OKAY)
9929
3.03k
       err = mp_mod(t2, prime, t2);
9930
3.08k
   if (err == MP_OKAY)
9931
3.03k
       err = mp_mul(ecp->x, t2, t2);
9932
9933
   /* compute y^2 - x^3 */
9934
3.08k
   if (err == MP_OKAY)
9935
3.01k
       err = mp_submod(t1, t2, prime, t1);
9936
9937
   /* Determine if curve "a" should be used in calc */
9938
3.08k
#ifdef WOLFSSL_CUSTOM_CURVES
9939
3.08k
   if (err == MP_OKAY) {
9940
      /* Use a and prime to determine if a == 3 */
9941
2.95k
      err = mp_set(t2, 0);
9942
2.95k
      if (err == MP_OKAY)
9943
2.95k
          err = mp_submod(prime, a, prime, t2);
9944
2.95k
   }
9945
3.08k
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
9946
      /* compute y^2 - x^3 + a*x */
9947
1.52k
      if (err == MP_OKAY)
9948
1.52k
          err = mp_mulmod(t2, ecp->x, prime, t2);
9949
1.52k
      if (err == MP_OKAY)
9950
1.52k
          err = mp_addmod(t1, t2, prime, t1);
9951
1.52k
   }
9952
1.55k
   else
9953
1.55k
#endif /* WOLFSSL_CUSTOM_CURVES */
9954
1.55k
   {
9955
      /* assumes "a" == 3 */
9956
1.55k
      (void)a;
9957
9958
      /* compute y^2 - x^3 + 3x */
9959
1.55k
      if (err == MP_OKAY)
9960
1.41k
          err = mp_add(t1, ecp->x, t1);
9961
1.55k
      if (err == MP_OKAY)
9962
1.41k
          err = mp_add(t1, ecp->x, t1);
9963
1.55k
      if (err == MP_OKAY)
9964
1.41k
          err = mp_add(t1, ecp->x, t1);
9965
1.55k
      if (err == MP_OKAY)
9966
1.41k
          err = mp_mod(t1, prime, t1);
9967
1.55k
  }
9968
9969
   /* adjust range (0, prime) */
9970
3.08k
   while (err == MP_OKAY && mp_isneg(t1)) {
9971
0
      err = mp_add(t1, prime, t1);
9972
0
   }
9973
3.08k
   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.08k
   if (err == MP_OKAY) {
9979
2.93k
       if (mp_cmp(t1, b) != MP_EQ) {
9980
1.29k
          err = IS_POINT_E;
9981
1.64k
       } else {
9982
1.64k
          err = MP_OKAY;
9983
1.64k
       }
9984
2.93k
   }
9985
9986
3.08k
   mp_clear(t1);
9987
3.08k
   mp_clear(t2);
9988
9989
3.08k
   RESTORE_VECTOR_REGISTERS();
9990
9991
3.08k
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9992
3.08k
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9993
9994
3.08k
   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.08k
}
10027
10028
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10029
5.13k
{
10030
5.13k
    int err = MP_OKAY;
10031
10032
    /* Validate parameters. */
10033
5.13k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10034
0
        err = BAD_FUNC_ARG;
10035
0
    }
10036
10037
5.13k
    if (err == MP_OKAY) {
10038
        /* x must be in the range [0, p-1] */
10039
5.13k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10040
143
            err = ECC_OUT_OF_RANGE_E;
10041
143
        }
10042
5.13k
    }
10043
10044
5.13k
    if (err == MP_OKAY) {
10045
        /* y must be in the range [0, p-1] */
10046
4.99k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10047
160
            err = ECC_OUT_OF_RANGE_E;
10048
160
        }
10049
4.99k
    }
10050
10051
5.13k
    if (err == MP_OKAY) {
10052
        /* z must be one, that is point must be in affine form. */
10053
4.83k
        if (!mp_isone(ecp->z)) {
10054
1.03k
            err = ECC_BAD_ARG_E;
10055
1.03k
        }
10056
4.83k
    }
10057
10058
5.13k
    if (err == MP_OKAY) {
10059
        /* Check x and y are valid for curve equation. */
10060
3.79k
        err = _ecc_is_point(ecp, a, b, prime);
10061
3.79k
    }
10062
10063
5.13k
    return err;
10064
5.13k
}
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.81k
{
10322
5.81k
    ecc_point* inf = NULL;
10323
#ifdef WOLFSSL_NO_MALLOC
10324
    ecc_point  lcl_inf;
10325
#endif
10326
5.81k
    int err;
10327
10328
5.81k
    if (key == NULL)
10329
0
        return BAD_FUNC_ARG;
10330
5.81k
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10331
5.81k
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10332
5.81k
       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.81k
    err = wc_ecc_new_point_ex(&inf, key->heap);
10340
5.81k
    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.79k
#if !defined(WOLFSSL_SP_MATH)
10372
5.79k
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10373
5.79k
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10374
20
            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.79k
    }
10384
10385
5.81k
    wc_ecc_del_point_ex(inf, key->heap);
10386
10387
5.81k
    return err;
10388
5.81k
}
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.24k
{
10430
2.24k
    int err = MP_OKAY;
10431
2.24k
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10432
2.24k
    mp_int* b = NULL;
10433
2.24k
    #ifdef USE_ECC_B_PARAM
10434
2.24k
        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.24k
#endif
10442
10443
2.24k
    ASSERT_SAVED_VECTOR_REGISTERS();
10444
10445
2.24k
    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.24k
#ifndef WOLFSSL_SP_MATH
10492
2.24k
    #ifdef USE_ECC_B_PARAM
10493
2.24k
        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.24k
    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.24k
    if (err == MP_OKAY)
10530
2.09k
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10531
2.09k
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10532
2.09k
#ifdef USE_ECC_B_PARAM
10533
2.09k
            | ECC_CURVE_FIELD_BF
10534
2.09k
#endif
10535
2.09k
    ));
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.24k
    if (err == MP_OKAY)
10545
2.09k
        b = curve->Bf;
10546
2.24k
#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.24k
    if (err == MP_OKAY) {
10552
2.09k
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10553
2.08k
                mp_isneg(key->pubkey.x)) {
10554
10
            err = ECC_OUT_OF_RANGE_E;
10555
10
        }
10556
2.09k
    }
10557
10558
    /* Qy must be in the range [0, p-1] */
10559
2.24k
    if (err == MP_OKAY) {
10560
2.08k
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10561
2.07k
                mp_isneg(key->pubkey.y)) {
10562
14
            err = ECC_OUT_OF_RANGE_E;
10563
14
        }
10564
2.08k
    }
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.24k
    if (err == MP_OKAY)
10570
2.07k
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10571
10572
2.24k
    if (!partial) {
10573
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10574
        /* pubkey * order must be at infinity */
10575
2.24k
        if (err == MP_OKAY)
10576
1.37k
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10577
1.37k
                    curve->prime, curve->order);
10578
2.24k
    }
10579
10580
2.24k
    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.24k
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10584
295
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10585
295
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10586
        #ifdef WOLFSSL_KCAPI_ECC
10587
            && key->handle == NULL
10588
        #endif
10589
2.24k
        ) {
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.24k
    }
10600
10601
2.24k
    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.24k
    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.24k
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10615
10616
2.24k
    (void)partial;
10617
2.24k
    (void)priv;
10618
2.24k
    return err;
10619
2.24k
}
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.1k
{
10626
14.1k
    int ret;
10627
14.1k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10628
14.1k
    ret = _ecc_validate_public_key(key, 0, 1);
10629
14.1k
    RESTORE_VECTOR_REGISTERS();
10630
14.1k
    return ret;
10631
14.1k
}
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.60k
{
10639
6.60k
    int err = MP_OKAY;
10640
6.60k
#ifdef HAVE_COMP_KEY
10641
6.60k
    int compressed = 0;
10642
6.60k
#endif
10643
6.60k
    int keysize = 0;
10644
6.60k
    byte pointType;
10645
#ifdef WOLFSSL_CRYPTOCELL
10646
    const CRYS_ECPKI_Domain_t* pDomain;
10647
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10648
#endif
10649
6.60k
    if (in == NULL || key == NULL)
10650
0
        return BAD_FUNC_ARG;
10651
10652
    /* must be odd */
10653
6.60k
    if ((inLen & 1) == 0) {
10654
52
        return ECC_BAD_ARG_E;
10655
52
    }
10656
10657
    /* make sure required variables are reset */
10658
6.55k
    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.55k
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10678
6.55k
    #ifndef WOLFSSL_ECC_BLIND_K
10679
6.55k
                                                                      NULL, NULL
10680
    #else
10681
                                                                key->kb, key->ku
10682
    #endif
10683
6.55k
                            );
10684
6.55k
    #endif
10685
6.55k
    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.55k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10692
10693
    /* check for point type (4, 2, or 3) */
10694
6.55k
    pointType = in[0];
10695
6.55k
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10696
1.77k
                                         pointType != ECC_POINT_COMP_ODD) {
10697
235
        err = ASN_PARSE_E;
10698
235
    }
10699
10700
6.55k
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10701
4.23k
    #ifdef HAVE_COMP_KEY
10702
4.23k
        compressed = 1;
10703
    #else
10704
        err = NOT_COMPILED_IN;
10705
    #endif
10706
4.23k
    }
10707
10708
    /* adjust to skip first byte */
10709
6.55k
    inLen -= 1;
10710
6.55k
    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.55k
    if (err == MP_OKAY) {
10725
6.31k
    #ifdef HAVE_COMP_KEY
10726
        /* adjust inLen if compressed */
10727
6.31k
        if (compressed)
10728
4.23k
            inLen = inLen*2 + 1;  /* used uncompressed len */
10729
6.31k
    #endif
10730
10731
        /* determine key size */
10732
6.31k
        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.31k
        err = wc_ecc_set_curve(key, keysize, curve_id);
10736
6.31k
        key->type = ECC_PUBLICKEY;
10737
6.31k
    }
10738
10739
    /* read data */
10740
6.55k
    if (err == MP_OKAY)
10741
6.30k
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10742
10743
6.55k
#ifdef HAVE_COMP_KEY
10744
6.55k
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10745
4.22k
#if !defined(WOLFSSL_SP_MATH)
10746
4.22k
    #ifdef WOLFSSL_SMALL_STACK
10747
4.22k
        mp_int* t1 = NULL;
10748
4.22k
        mp_int* t2 = NULL;
10749
    #else
10750
        mp_int t1[1], t2[1];
10751
    #endif
10752
4.22k
        int did_init = 0;
10753
10754
4.22k
        DECLARE_CURVE_SPECS(3);
10755
4.22k
        ALLOC_CURVE_SPECS(3, err);
10756
10757
4.22k
        #ifdef WOLFSSL_SMALL_STACK
10758
4.22k
        if (err == MP_OKAY) {
10759
4.15k
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10760
4.15k
            if (t1 == NULL) {
10761
41
                err = MEMORY_E;
10762
41
            }
10763
4.15k
        }
10764
4.22k
        if (err == MP_OKAY) {
10765
4.11k
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10766
4.11k
            if (t2 == NULL) {
10767
27
                err = MEMORY_E;
10768
27
            }
10769
4.11k
        }
10770
4.22k
        #endif
10771
4.22k
        if (err == MP_OKAY) {
10772
4.08k
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10773
0
                err = MEMORY_E;
10774
4.08k
            else
10775
4.08k
                did_init = 1;
10776
4.08k
        }
10777
10778
        /* load curve info */
10779
4.22k
        if (err == MP_OKAY)
10780
4.08k
            err = wc_ecc_curve_load(key->dp, &curve,
10781
4.08k
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10782
4.08k
                 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.22k
        if (err == MP_OKAY)
10797
4.08k
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10798
4.22k
        if (err == MP_OKAY)
10799
3.97k
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10800
10801
        /* compute x^3 + a*x */
10802
4.22k
        if (err == MP_OKAY)
10803
3.86k
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10804
4.22k
        if (err == MP_OKAY)
10805
3.83k
            err = mp_add(t1, t2, t1);
10806
10807
        /* compute x^3 + a*x + b */
10808
4.22k
        if (err == MP_OKAY)
10809
3.83k
            err = mp_add(t1, curve->Bf, t1);
10810
10811
        /* compute sqrt(x^3 + a*x + b) */
10812
4.22k
        if (err == MP_OKAY)
10813
3.83k
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10814
10815
        /* adjust y */
10816
4.22k
        if (err == MP_OKAY) {
10817
1.78k
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10818
1.33k
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10819
875
                err = mp_mod(t2, curve->prime, t2);
10820
875
            }
10821
908
            else {
10822
908
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10823
908
            }
10824
1.78k
            if (err == MP_OKAY)
10825
1.78k
                err = mp_copy(t2, key->pubkey.y);
10826
1.78k
        }
10827
10828
4.22k
        if (did_init) {
10829
4.08k
            mp_clear(t2);
10830
4.08k
            mp_clear(t1);
10831
4.08k
        }
10832
4.22k
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10833
4.22k
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10834
10835
4.22k
        wc_ecc_curve_free(curve);
10836
4.22k
        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.22k
    }
10870
6.55k
#endif /* HAVE_COMP_KEY */
10871
10872
6.55k
    if (err == MP_OKAY) {
10873
3.85k
    #ifdef HAVE_COMP_KEY
10874
3.85k
        if (compressed == 0)
10875
2.07k
    #endif
10876
2.07k
        {
10877
2.07k
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10878
2.07k
                (word32)keysize);
10879
2.07k
        }
10880
3.85k
    }
10881
6.55k
    if (err == MP_OKAY)
10882
3.85k
        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.55k
    if (err != MP_OKAY) {
10930
2.69k
        mp_clear(key->pubkey.x);
10931
2.69k
        mp_clear(key->pubkey.y);
10932
2.69k
        mp_clear(key->pubkey.z);
10933
2.69k
        mp_clear(key->k);
10934
2.69k
    }
10935
10936
6.55k
    RESTORE_VECTOR_REGISTERS();
10937
10938
6.55k
    return err;
10939
6.55k
}
10940
10941
WOLFSSL_ABI
10942
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
10943
224
{
10944
224
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
10945
224
}
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.52k
{
11098
8.52k
    int ret;
11099
#ifdef WOLFSSL_CRYPTOCELL
11100
    const CRYS_ECPKI_Domain_t* pDomain;
11101
#endif
11102
8.52k
    if (key == NULL || priv == NULL)
11103
105
        return BAD_FUNC_ARG;
11104
11105
    /* public optional, NULL if only importing private */
11106
8.42k
    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.42k
    else {
11119
        /* make sure required variables are reset */
11120
8.42k
        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.42k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11126
8.42k
        key->type = ECC_PRIVATEKEY_ONLY;
11127
8.42k
    }
11128
11129
8.42k
    if (ret != 0)
11130
821
        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.60k
    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.60k
#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.60k
    return ret;
11291
8.42k
}
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.58k
{
11315
2.58k
    int err;
11316
2.58k
#ifdef WOLFSSL_SMALL_STACK
11317
2.58k
    mp_int* rtmp = NULL;
11318
2.58k
    mp_int* stmp = NULL;
11319
#else
11320
    mp_int  rtmp[1];
11321
    mp_int  stmp[1];
11322
#endif
11323
11324
2.58k
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11325
9
        return ECC_BAD_ARG_E;
11326
11327
2.57k
#ifdef WOLFSSL_SMALL_STACK
11328
2.57k
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11329
2.57k
    if (rtmp == NULL)
11330
5
        return MEMORY_E;
11331
2.56k
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11332
2.56k
    if (stmp == NULL) {
11333
4
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11334
4
        return MEMORY_E;
11335
4
    }
11336
2.56k
#endif
11337
11338
2.56k
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11339
2.56k
    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.56k
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11346
2.56k
    if (err == MP_OKAY)
11347
2.53k
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11348
11349
2.56k
    if (err == MP_OKAY) {
11350
2.53k
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11351
38
            err = MP_ZERO_E;
11352
2.53k
    }
11353
2.56k
    if (err == MP_OKAY) {
11354
2.49k
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11355
0
            err = MP_READ_E;
11356
0
        }
11357
2.49k
    }
11358
11359
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11360
2.56k
    if (err == MP_OKAY)
11361
2.49k
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11362
11363
2.56k
    mp_clear(rtmp);
11364
2.56k
    mp_clear(stmp);
11365
2.56k
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11366
2.56k
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11367
11368
2.56k
    return err;
11369
2.56k
}
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
351
{
11384
351
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11385
2
        return ECC_BAD_ARG_E;
11386
11387
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11388
349
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11389
351
}
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.68k
{
11415
5.68k
    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.68k
    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.68k
    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.68k
    err = wc_ecc_set_curve(key, 0, curve_id);
11440
5.68k
    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.68k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11462
5.68k
#ifndef WOLFSSL_ECC_BLIND_K
11463
5.68k
                                                                      NULL, NULL
11464
#else
11465
                                                                key->kb, key->ku
11466
#endif
11467
5.68k
                        );
11468
5.68k
#endif
11469
5.68k
    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.68k
    if (err == MP_OKAY) {
11477
5.68k
        if (encType == WC_TYPE_HEX_STR)
11478
5.68k
            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.68k
        if (mp_isneg(key->pubkey.x)) {
11484
0
            WOLFSSL_MSG("Invalid Qx");
11485
0
            err = BAD_FUNC_ARG;
11486
0
        }
11487
5.68k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11488
46
            err = BAD_FUNC_ARG;
11489
46
        }
11490
5.68k
    }
11491
11492
    /* read Qy */
11493
5.68k
    if (err == MP_OKAY) {
11494
5.58k
        if (encType == WC_TYPE_HEX_STR)
11495
5.58k
            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.58k
        if (mp_isneg(key->pubkey.y)) {
11501
0
            WOLFSSL_MSG("Invalid Qy");
11502
0
            err = BAD_FUNC_ARG;
11503
0
        }
11504
5.58k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11505
44
            err = BAD_FUNC_ARG;
11506
44
        }
11507
5.58k
    }
11508
11509
5.68k
    if (err == MP_OKAY) {
11510
5.50k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11511
91
            WOLFSSL_MSG("Invalid Qx and Qy");
11512
91
            err = ECC_INF_E;
11513
91
        }
11514
5.50k
    }
11515
11516
5.68k
    if (err == MP_OKAY)
11517
5.41k
        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.68k
    if (err == MP_OKAY) {
11603
5.41k
        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.41k
        } else {
11677
5.41k
            key->type = ECC_PUBLICKEY;
11678
5.41k
        }
11679
5.41k
    }
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.68k
    if (err != MP_OKAY) {
11706
267
        mp_clear(key->pubkey.x);
11707
267
        mp_clear(key->pubkey.y);
11708
267
        mp_clear(key->pubkey.z);
11709
267
        mp_clear(key->k);
11710
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11711
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11712
#endif
11713
267
    }
11714
11715
5.68k
    return err;
11716
5.68k
}
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
138k
    for (x = 0; ecc_sets[x].size != 0; x++) {
11766
138k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11767
138k
                     XSTRLEN(curveName)) == 0) {
11768
11.8k
            break;
11769
11.8k
        }
11770
138k
    }
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
311
{
11788
311
    if (key == NULL || key->dp == NULL)
11789
0
        return BAD_FUNC_ARG;
11790
11791
    /* 'Uncompressed' | x | y */
11792
311
    *sz = 1 + 2 * (word32)key->dp->size;
11793
11794
311
    return 0;
11795
311
}
11796
#endif
11797
11798
/* key size in octets */
11799
WOLFSSL_ABI
11800
int wc_ecc_size(ecc_key* key)
11801
292
{
11802
292
    if (key == NULL || key->dp == NULL)
11803
0
        return 0;
11804
11805
292
    return key->dp->size;
11806
292
}
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
698
{
11830
698
    int maxSigSz;
11831
698
    int orderBits, keySz;
11832
11833
698
    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
698
    keySz = key->dp->size;
11840
698
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11841
698
    if (orderBits > keySz * 8) {
11842
0
        keySz = (orderBits + 7) >> 3;
11843
0
    }
11844
    /* maximum possible signature header size is 7 bytes */
11845
698
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11846
698
    if ((orderBits % 8) == 0) {
11847
        /* MSB can be set, so add 2 */
11848
404
        maxSigSz += ECC_MAX_PAD_SZ;
11849
404
    }
11850
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11851
698
    if (maxSigSz < (128 + 2)) {
11852
404
        maxSigSz -= 1;
11853
404
    }
11854
11855
698
    return maxSigSz;
11856
698
}
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.83k
{
13717
4.83k
    int err = 0;
13718
13719
4.83k
#ifdef ECC_TIMING_RESISTANT
13720
4.83k
    if (key == NULL) {
13721
0
        err = BAD_FUNC_ARG;
13722
0
    }
13723
4.83k
    else {
13724
4.83k
        key->rng = rng;
13725
4.83k
    }
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.83k
    return err;
13733
4.83k
}
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
603
{
13961
603
    if (ctx) {
13962
603
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
13963
13964
603
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13965
603
        #ifdef WOLFSSL_AES_128
13966
603
            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
603
        ctx->kdfAlgo  = ecHKDF_SHA256;
13980
603
        ctx->macAlgo  = ecHMAC_SHA256;
13981
603
        ctx->protocol = (byte)flags;
13982
603
        ctx->rng      = rng;
13983
13984
603
        if (flags == REQ_RESP_CLIENT)
13985
0
            ctx->cliSt = ecCLI_INIT;
13986
603
        if (flags == REQ_RESP_SERVER)
13987
0
            ctx->srvSt = ecSRV_INIT;
13988
603
    }
13989
603
}
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
603
{
14048
603
    if (ctx) {
14049
603
        switch (ctx->encAlgo) {
14050
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14051
603
            case ecAES_128_CBC:
14052
603
                *encKeySz = KEY_SIZE_128;
14053
603
                *ivSz     = IV_SIZE_128;
14054
603
                *blockSz  = WC_AES_BLOCK_SIZE;
14055
603
                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
603
        }
14077
14078
603
        switch (ctx->macAlgo) {
14079
603
            case ecHMAC_SHA256:
14080
603
                *digestSz = WC_SHA256_DIGEST_SIZE;
14081
603
                break;
14082
0
            default:
14083
0
                return BAD_FUNC_ARG;
14084
603
        }
14085
603
    } else
14086
0
        return BAD_FUNC_ARG;
14087
14088
#ifdef WOLFSSL_ECIES_OLD
14089
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14090
#else
14091
603
    *keysLen  = *encKeySz + (int)*digestSz;
14092
603
#endif
14093
14094
603
    return 0;
14095
603
}
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
322
{
14105
322
    int          ret = 0;
14106
322
    word32       blockSz = 0;
14107
322
#ifndef WOLFSSL_ECIES_OLD
14108
322
#ifndef WOLFSSL_ECIES_GEN_IV
14109
322
    byte         iv[ECC_MAX_IV_SIZE];
14110
322
#endif
14111
322
    word32       pubKeySz = 0;
14112
322
#endif
14113
322
    word32       digestSz = 0;
14114
322
    ecEncCtx     localCtx;
14115
322
#ifdef WOLFSSL_SMALL_STACK
14116
322
    byte*        sharedSecret;
14117
322
    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
322
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14127
322
    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
322
    int          keysLen = 0;
14133
322
    int          encKeySz = 0;
14134
322
    int          ivSz = 0;
14135
322
    int          offset = 0;         /* keys offset if doing msg exchange */
14136
322
    byte*        encKey = NULL;
14137
322
    byte*        encIv = NULL;
14138
322
    byte*        macKey = NULL;
14139
14140
322
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14141
292
                           outSz  == NULL)
14142
30
        return BAD_FUNC_ARG;
14143
14144
292
    if (ctx == NULL) {  /* use defaults */
14145
292
        ecc_ctx_init(&localCtx, 0, NULL);
14146
292
        ctx = &localCtx;
14147
292
    }
14148
14149
292
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14150
292
                            &blockSz);
14151
292
    if (ret != 0)
14152
0
        return ret;
14153
14154
292
#ifndef WOLFSSL_ECIES_OLD
14155
292
    if (!compressed) {
14156
292
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14157
292
    }
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
292
    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
292
    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
292
    if (keysLen > ECC_BUFSIZE) /* keys size */
14182
0
        return BUFFER_E;
14183
14184
292
    if ((msgSz % blockSz) != 0)
14185
49
        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
243
    if (*outSz < (pubKeySz + msgSz + digestSz))
14195
13
        return BUFFER_E;
14196
230
#endif
14197
14198
230
#ifdef ECC_TIMING_RESISTANT
14199
230
    if (ctx->rng != NULL && privKey->rng == NULL)
14200
0
        privKey->rng = ctx->rng;
14201
230
#endif
14202
14203
230
#ifndef WOLFSSL_ECIES_OLD
14204
230
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14205
230
#ifdef ECC_TIMING_RESISTANT
14206
230
        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
230
        if (ret != 0)
14211
37
            return ret;
14212
230
    }
14213
193
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14214
193
    if (ret != 0)
14215
1
        return ret;
14216
192
    out += pubKeySz;
14217
192
#endif
14218
14219
192
#ifdef WOLFSSL_SMALL_STACK
14220
192
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14221
192
    if (sharedSecret == NULL)
14222
1
        return MEMORY_E;
14223
14224
191
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14225
191
    if (keys == NULL) {
14226
1
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14227
1
        return MEMORY_E;
14228
1
    }
14229
190
#endif
14230
14231
190
    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
190
    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
190
    #ifndef WOLFSSL_ECIES_ISO18033
14245
190
        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
190
    }
14251
190
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14252
14253
190
    if (ret == 0) {
14254
    #ifdef WOLFSSL_ECIES_ISO18033
14255
        /* KDF data is encoded public key and secret. */
14256
        sharedSz += pubKeySz;
14257
    #endif
14258
184
        switch (ctx->kdfAlgo) {
14259
184
            case ecHKDF_SHA256 :
14260
184
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14261
184
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14262
184
                           keys, (word32)keysLen);
14263
184
                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
184
        }
14293
184
    }
14294
14295
190
    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
173
        XMEMSET(iv, 0, (size_t)ivSz);
14308
173
        encKey = keys + offset;
14309
173
        encIv  = iv;
14310
173
        macKey = encKey + encKeySz;
14311
173
    #endif
14312
173
    }
14313
14314
190
    if (ret == 0) {
14315
173
       switch (ctx->encAlgo) {
14316
173
            case ecAES_128_CBC:
14317
173
            case ecAES_256_CBC:
14318
173
            {
14319
173
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14320
173
            #ifdef WOLFSSL_SMALL_STACK
14321
173
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14322
173
                                          DYNAMIC_TYPE_AES);
14323
173
                if (aes == NULL) {
14324
1
                    ret = MEMORY_E;
14325
1
                    break;
14326
1
                }
14327
            #else
14328
                Aes aes[1];
14329
            #endif
14330
172
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14331
172
                if (ret == 0) {
14332
172
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14333
172
                                                                AES_ENCRYPTION);
14334
172
                    if (ret == 0) {
14335
172
                        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
172
                    }
14342
172
                    wc_AesFree(aes);
14343
172
                }
14344
172
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14345
        #else
14346
                ret = NOT_COMPILED_IN;
14347
        #endif
14348
172
                break;
14349
173
            }
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
173
        }
14395
173
    }
14396
14397
190
    if (ret == 0) {
14398
172
        switch (ctx->macAlgo) {
14399
172
            case ecHMAC_SHA256:
14400
172
            {
14401
172
            #ifdef WOLFSSL_SMALL_STACK
14402
172
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14403
172
                                             DYNAMIC_TYPE_HMAC);
14404
172
                if (hmac == NULL) {
14405
1
                    ret = MEMORY_E;
14406
1
                    break;
14407
1
                }
14408
            #else
14409
                Hmac hmac[1];
14410
            #endif
14411
171
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14412
171
                if (ret == 0) {
14413
171
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14414
171
                                                         WC_SHA256_DIGEST_SIZE);
14415
171
                    if (ret == 0) {
14416
171
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14417
171
                        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
171
                    }
14423
171
                    if (ret == 0)
14424
170
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14425
171
                    if (ret == 0)
14426
170
                        ret = wc_HmacFinal(hmac, out+msgSz);
14427
171
                    wc_HmacFree(hmac);
14428
171
                }
14429
171
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14430
171
                break;
14431
172
            }
14432
14433
0
            default:
14434
0
                ret = BAD_FUNC_ARG;
14435
0
                break;
14436
172
        }
14437
172
    }
14438
14439
190
    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
170
        *outSz = pubKeySz + msgSz + digestSz;
14446
170
#endif
14447
170
    }
14448
14449
190
    RESTORE_VECTOR_REGISTERS();
14450
14451
190
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14452
190
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14453
14454
190
    return ret;
14455
190
}
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
322
{
14465
322
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14466
322
}
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
338
{
14475
338
    int          ret = 0;
14476
338
    word32       blockSz = 0;
14477
338
#ifndef WOLFSSL_ECIES_OLD
14478
338
#ifndef WOLFSSL_ECIES_GEN_IV
14479
338
    byte         iv[ECC_MAX_IV_SIZE];
14480
338
#endif
14481
338
    word32       pubKeySz = 0;
14482
338
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
14483
338
#endif
14484
338
    word32       digestSz = 0;
14485
338
    ecEncCtx     localCtx;
14486
338
#ifdef WOLFSSL_SMALL_STACK
14487
338
    byte*        sharedSecret;
14488
338
    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
338
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14498
338
    word32       sharedSz = ECC_MAXSIZE;
14499
#else
14500
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14501
#endif
14502
338
    int          keysLen = 0;
14503
338
    int          encKeySz = 0;
14504
338
    int          ivSz = 0;
14505
338
    int          offset = 0;       /* in case using msg exchange */
14506
338
    byte*        encKey = NULL;
14507
338
    const byte*  encIv = NULL;
14508
338
    byte*        macKey = NULL;
14509
14510
14511
338
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14512
27
        return BAD_FUNC_ARG;
14513
#ifdef WOLFSSL_ECIES_OLD
14514
    if (pubKey == NULL)
14515
        return BAD_FUNC_ARG;
14516
#endif
14517
14518
311
    if (ctx == NULL) {  /* use defaults */
14519
311
        ecc_ctx_init(&localCtx, 0, NULL);
14520
311
        ctx = &localCtx;
14521
311
    }
14522
14523
311
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14524
311
                            &blockSz);
14525
311
    if (ret != 0)
14526
0
        return ret;
14527
14528
311
#ifndef WOLFSSL_ECIES_OLD
14529
311
    ret = ecc_public_key_size(privKey, &pubKeySz);
14530
311
    if (ret != 0)
14531
0
        return ret;
14532
311
#ifdef HAVE_COMP_KEY
14533
311
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14534
124
        pubKeySz = (pubKeySz / 2) + 1;
14535
124
    }
14536
311
#endif /* HAVE_COMP_KEY */
14537
311
#endif /* WOLFSSL_ECIES_OLD */
14538
14539
311
    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
311
    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
311
    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
311
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14574
101
        return BAD_PADDING_E;
14575
14576
210
    if (msgSz < pubKeySz + blockSz + digestSz)
14577
17
        return BAD_FUNC_ARG;
14578
193
    if (*outSz < (msgSz - digestSz - pubKeySz))
14579
16
        return BUFFER_E;
14580
177
#endif
14581
14582
177
#ifdef ECC_TIMING_RESISTANT
14583
177
    if (ctx->rng != NULL && privKey->rng == NULL)
14584
0
        privKey->rng = ctx->rng;
14585
177
#endif
14586
14587
177
#ifdef WOLFSSL_SMALL_STACK
14588
177
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14589
177
    if (sharedSecret == NULL) {
14590
12
    #ifndef WOLFSSL_ECIES_OLD
14591
12
        if (pubKey == peerKey)
14592
0
            wc_ecc_free(peerKey);
14593
12
    #endif
14594
12
        return MEMORY_E;
14595
12
    }
14596
14597
165
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14598
165
    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
157
#endif
14607
14608
157
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14609
14610
157
#ifndef WOLFSSL_ECIES_OLD
14611
157
    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
157
    else {
14617
        /* if a public key was passed in we should free it here before init
14618
         * and import */
14619
157
        wc_ecc_free(pubKey);
14620
157
    }
14621
157
    if (ret == 0) {
14622
157
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14623
157
    }
14624
157
    if (ret == 0) {
14625
157
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14626
157
    }
14627
157
    if (ret == 0) {
14628
        /* Point is not MACed. */
14629
73
        msg += pubKeySz;
14630
73
        msgSz -= pubKeySz;
14631
73
    }
14632
157
#endif
14633
14634
157
    if (ret == 0) {
14635
    #ifdef WOLFSSL_ECIES_ISO18033
14636
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14637
        sharedSz -= pubKeySz;
14638
    #endif
14639
14640
73
        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
73
        #ifndef WOLFSSL_ECIES_ISO18033
14648
73
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14649
73
                                                                    &sharedSz);
14650
        #else
14651
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14652
                                                          pubKeySz, &sharedSz);
14653
        #endif
14654
73
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14655
73
    }
14656
157
    if (ret == 0) {
14657
    #ifdef WOLFSSL_ECIES_ISO18033
14658
        /* KDF data is encoded public key and secret. */
14659
        sharedSz += pubKeySz;
14660
    #endif
14661
65
        switch (ctx->kdfAlgo) {
14662
65
            case ecHKDF_SHA256 :
14663
65
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14664
65
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14665
65
                           keys, (word32)keysLen);
14666
65
                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
65
         }
14695
65
    }
14696
14697
157
    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
65
        XMEMSET(iv, 0, (size_t)ivSz);
14710
65
        encKey = keys + offset;
14711
65
        encIv  = iv;
14712
65
        macKey = encKey + encKeySz;
14713
65
    #endif
14714
14715
65
        switch (ctx->macAlgo) {
14716
65
            case ecHMAC_SHA256:
14717
65
            {
14718
65
                byte verify[WC_SHA256_DIGEST_SIZE];
14719
65
            #ifdef WOLFSSL_SMALL_STACK
14720
65
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14721
65
                                             DYNAMIC_TYPE_HMAC);
14722
65
                if (hmac == NULL) {
14723
0
                    ret = MEMORY_E;
14724
0
                    break;
14725
0
                }
14726
            #else
14727
                Hmac hmac[1];
14728
            #endif
14729
65
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14730
65
                if (ret == 0) {
14731
65
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14732
65
                                                         WC_SHA256_DIGEST_SIZE);
14733
65
                    if (ret == 0)
14734
65
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14735
65
                        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
65
                    if (ret == 0)
14741
65
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14742
14743
65
                    if (ret == 0)
14744
65
                        ret = wc_HmacFinal(hmac, verify);
14745
65
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14746
65
                                                             digestSz) != 0)) {
14747
47
                        ret = HASH_TYPE_E;
14748
47
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14749
47
                    }
14750
14751
65
                    wc_HmacFree(hmac);
14752
65
                }
14753
65
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14754
65
                break;
14755
65
            }
14756
14757
0
            default:
14758
0
                ret = BAD_FUNC_ARG;
14759
0
                break;
14760
65
        }
14761
65
    }
14762
14763
157
    if (ret == 0) {
14764
18
        switch (ctx->encAlgo) {
14765
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14766
18
            case ecAES_128_CBC:
14767
18
            case ecAES_256_CBC:
14768
18
            {
14769
18
            #ifdef WOLFSSL_SMALL_STACK
14770
18
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14771
18
                                          DYNAMIC_TYPE_AES);
14772
18
                if (aes == NULL) {
14773
0
                    ret = MEMORY_E;
14774
0
                    break;
14775
0
                }
14776
            #else
14777
                Aes aes[1];
14778
            #endif
14779
18
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14780
18
                if (ret == 0) {
14781
18
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14782
18
                                                                AES_DECRYPTION);
14783
18
                    if (ret == 0) {
14784
18
                        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
18
                    }
14791
18
                    wc_AesFree(aes);
14792
18
                }
14793
18
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14794
18
                break;
14795
18
            }
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
18
        }
14838
18
    }
14839
14840
157
    if (ret == 0)
14841
18
       *outSz = msgSz - digestSz;
14842
14843
157
    RESTORE_VECTOR_REGISTERS();
14844
14845
157
#ifndef WOLFSSL_ECIES_OLD
14846
157
    if (pubKey == peerKey)
14847
0
        wc_ecc_free(peerKey);
14848
157
#endif
14849
157
#ifdef WOLFSSL_SMALL_STACK
14850
157
#ifndef WOLFSSL_ECIES_OLD
14851
157
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14852
157
#endif
14853
157
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14854
157
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14855
157
#endif
14856
14857
157
    return ret;
14858
157
}
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
630
{
14874
630
#ifdef WOLFSSL_SMALL_STACK
14875
630
    mp_int*  a1 = NULL;
14876
630
    mp_int*  n1 = NULL;
14877
#else
14878
    mp_int   a1[1], n1[1];
14879
#endif
14880
630
    int      res;
14881
630
    int      s = 1;
14882
630
    int      k;
14883
630
    mp_int*  t[2];
14884
630
    mp_int*  ts;
14885
630
    mp_digit residue;
14886
14887
630
    if (mp_isneg(a) == MP_YES) {
14888
0
        return MP_VAL;
14889
0
    }
14890
630
    if (mp_isneg(n) == MP_YES) {
14891
0
        return MP_VAL;
14892
0
    }
14893
630
    if (mp_iseven(n) == MP_YES) {
14894
0
        return MP_VAL;
14895
0
    }
14896
14897
630
#ifdef WOLFSSL_SMALL_STACK
14898
630
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14899
630
    if (a1 == NULL) {
14900
4
        return MP_MEM;
14901
4
    }
14902
626
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14903
626
    if (n1 == NULL) {
14904
7
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
14905
7
        return MP_MEM;
14906
7
    }
14907
619
#endif
14908
14909
619
    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
619
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
14916
14917
619
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
14918
0
        goto done;
14919
0
    }
14920
14921
619
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
14922
0
        goto done;
14923
0
    }
14924
14925
619
    t[0] = a1;
14926
619
    t[1] = n1;
14927
14928
    /* Keep reducing until first number is 0. */
14929
17.8k
    while (!mp_iszero(t[0])) {
14930
        /* Divide by 2 until odd. */
14931
17.2k
        k = mp_cnt_lsb(t[0]);
14932
17.2k
        if (k > 0) {
14933
9.51k
            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.51k
            residue = t[1]->dp[0] & 7;
14939
9.51k
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
14940
3.28k
                s = -s;
14941
3.28k
            }
14942
9.51k
        }
14943
14944
        /* Swap t[0] and t[1]. */
14945
17.2k
        ts   = t[0];
14946
17.2k
        t[0] = t[1];
14947
17.2k
        t[1] = ts;
14948
14949
        /* Negate s if both numbers == 3 mod 4. */
14950
17.2k
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
14951
4.35k
             s = -s;
14952
4.35k
        }
14953
14954
        /* Reduce first number modulo second. */
14955
17.2k
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
14956
1.85k
            res = mp_sub(t[0], t[1], t[0]);
14957
1.85k
        }
14958
15.4k
        else {
14959
15.4k
            res = mp_mod(t[0], t[1], t[0]);
14960
15.4k
        }
14961
17.2k
        if (res != MP_OKAY) {
14962
16
            goto done;
14963
16
        }
14964
17.2k
    }
14965
14966
    /* When the two numbers have divisors in common. */
14967
603
    if (!mp_isone(t[1])) {
14968
0
        s = 0;
14969
0
    }
14970
603
    *c = s;
14971
14972
619
done:
14973
14974
619
    RESTORE_VECTOR_REGISTERS();
14975
14976
    /* cleanup */
14977
619
    mp_clear(n1);
14978
619
    mp_clear(a1);
14979
14980
619
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14981
619
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14982
14983
619
  return res;
14984
603
}
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.83k
{
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.83k
  int res, legendre, done = 0;
15043
3.83k
  mp_digit i;
15044
3.83k
#ifdef WOLFSSL_SMALL_STACK
15045
3.83k
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15046
3.83k
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15047
3.83k
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15048
3.83k
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15049
3.83k
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15050
3.83k
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15051
3.83k
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15052
3.83k
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15053
3.83k
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15054
3.83k
  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.83k
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15060
15061
3.83k
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15062
3.83k
      (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.83k
#ifdef WOLFSSL_SMALL_STACK
15068
3.83k
  if ((t1 == NULL) ||
15069
3.68k
      (C == NULL) ||
15070
3.65k
      (Q == NULL) ||
15071
3.64k
      (S == NULL) ||
15072
3.62k
      (Z == NULL) ||
15073
3.61k
      (M == NULL) ||
15074
3.59k
      (T == NULL) ||
15075
3.59k
      (R == NULL) ||
15076
3.58k
      (N == NULL) ||
15077
3.58k
      (two == NULL)) {
15078
261
    res = MP_MEM;
15079
261
    goto out;
15080
261
  }
15081
3.57k
#endif
15082
15083
  /* first handle the simple cases n = 0 or n = 1 */
15084
3.57k
  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.56k
  if (mp_cmp_d(n, 1) == MP_EQ) {
15090
3
    res = mp_set(ret, 1);
15091
3
    goto out;
15092
3
  }
15093
15094
  /* prime must be odd */
15095
3.56k
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15096
3
    res = MP_VAL;
15097
3
    goto out;
15098
3
  }
15099
15100
  /* reduce n to less than prime */
15101
3.56k
  res = mp_mod(n, prime, N);
15102
3.56k
  if (res != MP_OKAY) {
15103
9
    goto out;
15104
9
  }
15105
  /* when N is zero, sqrt is zero */
15106
3.55k
  if (mp_iszero(N)) {
15107
7
    mp_set(ret, 0);
15108
7
    goto out;
15109
7
  }
15110
15111
  /* is quadratic non-residue mod prime */
15112
3.54k
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15113
568
    goto out;
15114
568
  }
15115
2.97k
  if (legendre == -1) {
15116
596
    res = MP_VAL;
15117
596
    goto out;
15118
596
  }
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.38k
  res = mp_mod_d(prime, 4, &i);
15125
2.38k
  if (res == MP_OKAY && i == 3) {
15126
1.63k
    res = mp_add_d(prime, 1, t1);
15127
15128
1.63k
    if (res == MP_OKAY)
15129
1.63k
      res = mp_div_2(t1, t1);
15130
1.63k
    if (res == MP_OKAY)
15131
1.63k
      res = mp_div_2(t1, t1);
15132
1.63k
    if (res == MP_OKAY)
15133
1.63k
      res = mp_exptmod(N, t1, prime, ret);
15134
15135
1.63k
    done = 1;
15136
1.63k
  }
15137
15138
  /* NOW: TonelliShanks algorithm */
15139
2.38k
  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
751
    res = mp_copy(prime, Q);
15145
751
    if (res == MP_OKAY)
15146
751
      res = mp_sub_d(Q, 1, Q);
15147
15148
    /* S = 0 */
15149
751
    if (res == MP_OKAY)
15150
751
      mp_zero(S);
15151
15152
44.1k
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15153
      /* Q = Q / 2 */
15154
43.3k
      res = mp_div_2(Q, Q);
15155
15156
      /* S = S + 1 */
15157
43.3k
      if (res == MP_OKAY)
15158
43.3k
        res = mp_add_d(S, 1, S);
15159
43.3k
    }
15160
15161
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15162
    /* Z = 2 */
15163
751
    if (res == MP_OKAY)
15164
751
      res = mp_set_int(Z, 2);
15165
15166
5.00k
    while (res == MP_OKAY) {
15167
4.97k
      res = mp_jacobi(Z, prime, &legendre);
15168
4.97k
      if (res == MP_OKAY && legendre == -1)
15169
708
        break;
15170
15171
4.26k
#if defined(WOLFSSL_CUSTOM_CURVES)
15172
      /* P224R1 succeeds with a value of 11. */
15173
4.26k
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15174
        /* This is to clamp the loop in case 'prime' is not really prime */
15175
3
        res = MP_VAL;
15176
3
        break;
15177
3
      }
15178
4.25k
#endif
15179
15180
      /* Z = Z + 1 */
15181
4.25k
      if (res == MP_OKAY)
15182
4.22k
        res = mp_add_d(Z, 1, Z);
15183
15184
4.25k
      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
3
        res = MP_VAL;
15187
3
        break;
15188
3
      }
15189
4.25k
    }
15190
15191
    /* C = Z ^ Q mod prime */
15192
751
    if (res == MP_OKAY)
15193
708
      res = mp_exptmod(Z, Q, prime, C);
15194
15195
    /* t1 = (Q + 1) / 2 */
15196
751
    if (res == MP_OKAY)
15197
621
      res = mp_add_d(Q, 1, t1);
15198
751
    if (res == MP_OKAY)
15199
621
      res = mp_div_2(t1, t1);
15200
15201
    /* R = n ^ ((Q + 1) / 2) mod prime */
15202
751
    if (res == MP_OKAY)
15203
621
      res = mp_exptmod(N, t1, prime, R);
15204
15205
    /* T = n ^ Q mod prime */
15206
751
    if (res == MP_OKAY)
15207
617
      res = mp_exptmod(N, Q, prime, T);
15208
15209
    /* M = S */
15210
751
    if (res == MP_OKAY)
15211
611
      res = mp_copy(S, M);
15212
15213
751
    if (res == MP_OKAY)
15214
611
      res = mp_set_int(two, 2);
15215
15216
16.0k
    while (res == MP_OKAY && done == 0) {
15217
15.3k
      res = mp_copy(T, t1);
15218
15219
      /* reduce to 1 and count */
15220
15.3k
      i = 0;
15221
717k
      while (res == MP_OKAY) {
15222
717k
        if (mp_cmp_d(t1, 1) == MP_EQ)
15223
15.2k
            break;
15224
702k
        res = mp_exptmod(t1, two, prime, t1);
15225
702k
        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
24
          res = MP_VAL;
15228
24
          break;
15229
24
        }
15230
702k
        if (res == MP_OKAY)
15231
702k
          i++;
15232
702k
      }
15233
15.3k
      if (res == MP_OKAY && i == 0) {
15234
460
        res = mp_copy(R, ret);
15235
460
        done = 1;
15236
460
      }
15237
15238
15.3k
      if (done == 0) {
15239
        /* t1 = 2 ^ (M - i - 1) */
15240
14.8k
        if (res == MP_OKAY)
15241
14.7k
          res = mp_sub_d(M, i, t1);
15242
14.8k
        if (res == MP_OKAY)
15243
14.7k
          res = mp_sub_d(t1, 1, t1);
15244
14.8k
        if (res == MP_OKAY)
15245
14.7k
          res = mp_exptmod(two, t1, prime, t1);
15246
15247
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15248
14.8k
        if (res == MP_OKAY)
15249
14.7k
          res = mp_exptmod(C, t1, prime, t1);
15250
15251
        /* C = (t1 * t1) mod prime */
15252
14.8k
        if (res == MP_OKAY)
15253
14.7k
          res = mp_sqrmod(t1, prime, C);
15254
15255
        /* R = (R * t1) mod prime */
15256
14.8k
        if (res == MP_OKAY)
15257
14.7k
          res = mp_mulmod(R, t1, prime, R);
15258
15259
        /* T = (T * C) mod prime */
15260
14.8k
        if (res == MP_OKAY)
15261
14.7k
          res = mp_mulmod(T, C, prime, T);
15262
15263
        /* M = i */
15264
14.8k
        if (res == MP_OKAY)
15265
14.7k
          res = mp_set(M, i);
15266
14.8k
      }
15267
15.3k
    }
15268
751
  }
15269
15270
3.83k
  out:
15271
15272
3.83k
  RESTORE_VECTOR_REGISTERS();
15273
15274
3.83k
#ifdef WOLFSSL_SMALL_STACK
15275
3.83k
  if (t1) {
15276
3.68k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15277
3.68k
      mp_clear(t1);
15278
3.68k
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15279
3.68k
  }
15280
3.83k
  if (C) {
15281
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15282
3.66k
      mp_clear(C);
15283
3.66k
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15284
3.66k
  }
15285
3.83k
  if (Q) {
15286
3.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15287
3.66k
      mp_clear(Q);
15288
3.66k
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15289
3.66k
  }
15290
3.83k
  if (S) {
15291
3.65k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15292
3.65k
      mp_clear(S);
15293
3.65k
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15294
3.65k
  }
15295
3.83k
  if (Z) {
15296
3.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15297
3.64k
      mp_clear(Z);
15298
3.64k
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15299
3.64k
  }
15300
3.83k
  if (M) {
15301
3.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15302
3.64k
      mp_clear(M);
15303
3.64k
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15304
3.64k
  }
15305
3.83k
  if (T) {
15306
3.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15307
3.64k
      mp_clear(T);
15308
3.64k
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15309
3.64k
  }
15310
3.83k
  if (R) {
15311
3.63k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15312
3.63k
      mp_clear(R);
15313
3.63k
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15314
3.63k
  }
15315
3.83k
  if (N) {
15316
3.63k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15317
3.63k
      mp_clear(N);
15318
3.63k
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15319
3.63k
  }
15320
3.83k
  if (two) {
15321
3.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15322
3.64k
      mp_clear(two);
15323
3.64k
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15324
3.64k
  }
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.83k
  return res;
15341
2.38k
#endif
15342
2.38k
}
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.38k
{
15350
2.38k
   word32 numlen;
15351
2.38k
   int    ret = MP_OKAY;
15352
15353
2.38k
   if (key == NULL || outLen == NULL)
15354
0
       return BAD_FUNC_ARG;
15355
15356
2.38k
   if (key->type == ECC_PRIVATEKEY_ONLY)
15357
54
       return ECC_PRIVATEONLY_E;
15358
15359
2.33k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15360
367
       return ECC_BAD_ARG_E;
15361
367
   }
15362
15363
1.96k
   numlen = (word32)key->dp->size;
15364
15365
1.96k
   if (*outLen < (1 + numlen)) {
15366
982
      *outLen = 1 + numlen;
15367
982
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15368
982
   }
15369
15370
982
   if (out == NULL)
15371
0
       return BAD_FUNC_ARG;
15372
15373
982
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15374
0
       return ECC_BAD_ARG_E;
15375
15376
   /* store first byte */
15377
982
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15378
15379
   /* pad and store x */
15380
982
   XMEMSET(out+1, 0, numlen);
15381
982
   ret = mp_to_unsigned_bin(
15382
982
       key->pubkey.x,
15383
982
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15384
982
   *outLen = 1 + numlen;
15385
15386
982
   return ret;
15387
982
}
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.31k
{
15411
6.31k
    int x;
15412
6.31k
    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.31k
    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
27.5k
    for (x = 0; ecc_sets[x].size != 0; x++) {
15437
25.2k
        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.94k
            if (oidSz) {
15461
3.94k
                *oidSz = ecc_sets[x].oidSz;
15462
3.94k
            }
15463
3.94k
            if (oid) {
15464
3.94k
                *oid = ecc_sets[x].oid;
15465
3.94k
            }
15466
3.94k
            ret = ecc_sets[x].id;
15467
3.94k
            break;
15468
3.94k
        #endif
15469
3.94k
        }
15470
25.2k
    }
15471
15472
#ifdef HAVE_OID_ENCODING
15473
    wc_UnLockMutex(&ecc_oid_cache_lock);
15474
#endif
15475
15476
6.27k
    return ret;
15477
6.31k
}
15478
15479
#ifdef WOLFSSL_CUSTOM_CURVES
15480
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15481
150
{
15482
150
    if (key == NULL || dp == NULL) {
15483
0
        return BAD_FUNC_ARG;
15484
0
    }
15485
15486
150
    key->idx = ECC_CUSTOM_IDX;
15487
150
    key->dp = dp;
15488
15489
150
    return 0;
15490
150
}
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 */