Coverage Report

Created: 2026-01-06 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math/wolfcrypt/src/ecc.c
Line
Count
Source
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
25
#undef WOLFSSL_SMALL_STACK
26
#undef WOLFSSL_SMALL_STACK_CACHE
27
#endif
28
29
/*
30
Possible ECC enable options:
31
 * HAVE_ECC:            Overall control of ECC                  default: on
32
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
33
 * HAVE_ECC_SIGN:       ECC sign                                default: on
34
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
35
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
36
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
37
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
38
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
39
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
40
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
41
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
42
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
43
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
44
 *                        Includes the curve "a" variable in calculation
45
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
46
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
47
 *                                                              default: off
48
 * FP_ECC:              ECC Fixed Point Cache                   default: off
49
 *                      FP cache is not supported for SECP160R1, SECP160R2,
50
 *                      SECP160K1 and SECP224K1. These do not work with scalars
51
 *                      that are the length of the order when the order is
52
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
53
 * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
54
 *                      (on for HAVE_COMP_KEY)
55
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
56
 *                      For the ECC curve parameters `ecc_set_type` use fixed
57
 *                      array for hex string
58
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
59
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
60
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
61
 *                      normal blocking API's
62
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
63
 *                      signing. If the value is invalid, a new random 'k' is
64
 *                      generated in the loop. (For testing)
65
 *                                                              default: off
66
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
67
 *                      Enables the setting of the 'k' value to use during ECDSA
68
 *                      signing. If the value is invalid then an error is
69
 *                      returned rather than generating a new 'k'. (For testing)
70
 *                                                              default: off
71
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
72
 *                      deterministic ECC signatures. The following function
73
 *                      can be used to set the deterministic signing flag in the
74
 *                      ecc key structure.
75
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
76
 *                                                              default: off
77
 *
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
79
 *                      hash directly instead of doing bits2octets(H(m)), when
80
 *                      the variant macro is used the bits2octets operation on
81
 *                      the hash is removed.
82
 *                                                              default: off
83
 *
84
 * WC_PROTECT_ENCRYPTED_MEM:
85
 *                      Enables implementations that protect data that is in
86
 *                      encrypted memory.
87
 *                                                              default: off
88
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
89
 *                      Enables generation of scalar (private key and ECDSA
90
 *                      nonce) to be performed using reject sampling algorithm.
91
 *                      Use this when CPU state can be closely observed by
92
 *                      attacker.
93
 *                                                              default: off
94
 * WOLFSSL_ECC_BLIND_K
95
 *                      Blind the private key k by using a random mask.
96
 *                      The private key is never stored unprotected but an
97
 *                      unmasked copy is computed and stored each time it is
98
 *                      needed.
99
 *                                                              default: off
100
 * WOLFSSL_CHECK_VER_FAULTS
101
 *                      Sanity check on verification steps in case of faults.
102
 *                                                              default: off
103
 */
104
105
/*
106
ECC Curve Types:
107
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
108
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
109
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
110
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
111
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
112
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
113
 */
114
115
/*
116
ECC Curve Sizes:
117
 * ECC_USER_CURVES: Allows custom combination of key sizes below
118
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
119
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
120
 * HAVE_ECC112: 112 bit key
121
 * HAVE_ECC128: 128 bit key
122
 * HAVE_ECC160: 160 bit key
123
 * HAVE_ECC192: 192 bit key
124
 * HAVE_ECC224: 224 bit key
125
 * HAVE_ECC239: 239 bit key
126
 * NO_ECC256: Disables 256 bit key (on by default)
127
 * HAVE_ECC320: 320 bit key
128
 * HAVE_ECC384: 384 bit key
129
 * HAVE_ECC512: 512 bit key
130
 * HAVE_ECC521: 521 bit key
131
 */
132
133
134
#ifdef HAVE_ECC
135
136
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
137
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
138
    !defined(WOLFSSL_CUSTOM_CURVES)
139
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
140
#endif
141
142
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
143
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
144
    #define FIPS_NO_WRAPPERS
145
146
    #ifdef USE_WINDOWS_API
147
        #pragma code_seg(".fipsA$f")
148
        #pragma const_seg(".fipsB$f")
149
    #endif
150
#endif
151
152
/* public ASN interface */
153
#include <wolfssl/wolfcrypt/asn_public.h>
154
155
#include <wolfssl/wolfcrypt/ecc.h>
156
#include <wolfssl/wolfcrypt/asn.h>
157
158
#ifdef WOLFSSL_HAVE_SP_ECC
159
#include <wolfssl/wolfcrypt/sp.h>
160
#endif
161
162
#ifdef HAVE_ECC_ENCRYPT
163
    #include <wolfssl/wolfcrypt/kdf.h>
164
    #include <wolfssl/wolfcrypt/aes.h>
165
#endif
166
167
#ifdef HAVE_X963_KDF
168
    #include <wolfssl/wolfcrypt/hash.h>
169
#endif
170
171
#ifdef WOLF_CRYPTO_CB
172
    #include <wolfssl/wolfcrypt/cryptocb.h>
173
#endif
174
175
#ifdef NO_INLINE
176
    #include <wolfssl/wolfcrypt/misc.h>
177
#else
178
    #define WOLFSSL_MISC_INCLUDED
179
    #include <wolfcrypt/src/misc.c>
180
#endif
181
182
#if FIPS_VERSION3_GE(6,0,0)
183
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
184
                                                     { 0x1a2b3c4d, 0x00000005 };
185
    int wolfCrypt_FIPS_ECC_sanity(void)
186
    {
187
        return 0;
188
    }
189
#endif
190
191
#if defined(FREESCALE_LTC_ECC)
192
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
193
#endif
194
195
#if defined(WOLFSSL_STM32_PKA)
196
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
197
#endif
198
199
#if defined(WOLFSSL_PSOC6_CRYPTO)
200
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
201
#endif
202
203
#if defined(WOLFSSL_CAAM)
204
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
205
#endif
206
207
#if defined(WOLFSSL_KCAPI_ECC)
208
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
209
#endif
210
211
#ifdef WOLFSSL_SE050
212
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
213
#endif
214
215
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
216
    #include <xsecure_ellipticclient.h>
217
#endif
218
219
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
220
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
221
    #include <wolfssl/wolfcrypt/hmac.h>
222
#endif
223
224
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WOLFSSL_SP_ASM)
225
    /* force off unneeded vector register save/restore. */
226
    #undef SAVE_VECTOR_REGISTERS
227
    #define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
228
    #undef RESTORE_VECTOR_REGISTERS
229
    #define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
230
#endif
231
232
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
233
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
234
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
235
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) && \
236
    !defined(WOLFSSL_PSOC6_CRYPTO)
237
    #undef  HAVE_ECC_VERIFY_HELPER
238
    #define HAVE_ECC_VERIFY_HELPER
239
#endif
240
241
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
242
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
243
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
244
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
245
    #undef  HAVE_ECC_MAKE_PUB
246
    #define HAVE_ECC_MAKE_PUB
247
#endif
248
249
250
/* macro guard for ecc_check_pubkey_order functionality */
251
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
252
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
253
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
254
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
255
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
256
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
257
258
    /* CAAM builds use public key validation as a means to check if an
259
     * imported private key is an encrypted black key or not */
260
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
261
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
262
#endif
263
264
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
265
#define MAX_ECC_BITS_USE    SP_INT_BITS
266
#else
267
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
268
#endif
269
270
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
271
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
272
273
#define ECC_KEY_MAX_BITS(key)                                       \
274
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
275
        ((unsigned)((key)->dp->size * 8)))
276
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
277
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
278
        ((unsigned)((key)->dp->size * 8)))
279
280
#else
281
282
/* Add one bit for cases when order is a bit greater than prime. */
283
#define ECC_KEY_MAX_BITS(key)                                       \
284
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
285
        ((unsigned)((key)->dp->size * 8 + 1)))
286
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
287
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
288
        ((unsigned)((key)->dp->size * 8 + 1)))
289
290
#endif
291
292
#ifdef WOLFSSL_ECC_BLIND_K
293
mp_int* ecc_get_k(ecc_key* key)
294
{
295
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
296
    return key->ku;
297
}
298
void ecc_blind_k(ecc_key* key, mp_int* b)
299
{
300
    mp_xor_ct(key->k, b, key->dp->size, key->k);
301
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
302
}
303
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
304
{
305
    int ret = 0;
306
    WC_RNG local_rng;
307
308
#ifdef ECC_TIMING_RESISTANT
309
    if (rng == NULL) {
310
        rng = key->rng;
311
    }
312
#endif
313
    if (rng == NULL) {
314
        ret = wc_InitRng(&local_rng);
315
        if (ret == 0) {
316
            rng = &local_rng;
317
        }
318
    }
319
    if (ret == 0) {
320
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
321
            sizeof(mp_digit), rng);
322
        if (ret == 0) {
323
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
324
        }
325
    }
326
327
    if (rng == &local_rng) {
328
        wc_FreeRng(&local_rng);
329
    }
330
    return ret;
331
}
332
333
mp_int* wc_ecc_key_get_priv(ecc_key* key)
334
{
335
    return ecc_get_k(key);
336
}
337
#endif
338
339
/* forward declarations */
340
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
341
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
342
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
343
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
344
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
345
#endif
346
347
/* internal ECC states */
348
enum {
349
    ECC_STATE_NONE = 0,
350
351
    ECC_STATE_SHARED_SEC_GEN,
352
    ECC_STATE_SHARED_SEC_RES,
353
354
    ECC_STATE_SIGN_DO,
355
    ECC_STATE_SIGN_ENCODE,
356
357
    ECC_STATE_VERIFY_DECODE,
358
    ECC_STATE_VERIFY_DO,
359
    ECC_STATE_VERIFY_RES
360
};
361
362
363
/* map
364
   ptmul -> mulmod
365
*/
366
367
/* 256-bit curve on by default whether user curves or not */
368
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
369
    #define ECC112
370
#endif
371
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
372
    #define ECC128
373
#endif
374
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
375
    #define ECC160
376
#endif
377
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
378
    #define ECC192
379
#endif
380
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
381
    #define ECC224
382
#endif
383
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
384
    #define ECC239
385
#endif
386
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
387
    #define ECC256
388
#endif
389
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
390
    #define ECC320
391
#endif
392
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
393
    #define ECC384
394
#endif
395
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
396
    #define ECC512
397
#endif
398
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
399
    #define ECC521
400
#endif
401
402
/* The encoded OID's for ECC curves */
403
#ifdef ECC112
404
    #ifndef NO_ECC_SECP
405
        #ifdef HAVE_OID_ENCODING
406
            #define CODED_SECP112R1    {1,3,132,0,6}
407
            #define CODED_SECP112R1_SZ 5
408
        #else
409
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
410
            #define CODED_SECP112R1_SZ 5
411
        #endif
412
        #ifndef WOLFSSL_ECC_CURVE_STATIC
413
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
414
        #else
415
            #define ecc_oid_secp112r1 CODED_SECP112R1
416
        #endif
417
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
418
    #endif /* !NO_ECC_SECP */
419
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
420
        #ifdef HAVE_OID_ENCODING
421
            #define CODED_SECP112R2    {1,3,132,0,7}
422
            #define CODED_SECP112R2_SZ 5
423
        #else
424
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
425
            #define CODED_SECP112R2_SZ 5
426
        #endif
427
        #ifndef WOLFSSL_ECC_CURVE_STATIC
428
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
429
        #else
430
            #define ecc_oid_secp112r2 CODED_SECP112R2
431
        #endif
432
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
433
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
434
#endif /* ECC112 */
435
#ifdef ECC128
436
    #ifndef NO_ECC_SECP
437
        #ifdef HAVE_OID_ENCODING
438
            #define CODED_SECP128R1    {1,3,132,0,28}
439
            #define CODED_SECP128R1_SZ 5
440
        #else
441
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
442
            #define CODED_SECP128R1_SZ 5
443
        #endif
444
        #ifndef WOLFSSL_ECC_CURVE_STATIC
445
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
446
        #else
447
            #define ecc_oid_secp128r1 CODED_SECP128R1
448
        #endif
449
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
450
    #endif /* !NO_ECC_SECP */
451
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
452
        #ifdef HAVE_OID_ENCODING
453
            #define CODED_SECP128R2    {1,3,132,0,29}
454
            #define CODED_SECP128R2_SZ 5
455
        #else
456
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
457
            #define CODED_SECP128R2_SZ 5
458
        #endif
459
        #ifndef WOLFSSL_ECC_CURVE_STATIC
460
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
461
        #else
462
            #define ecc_oid_secp128r2 CODED_SECP128R2
463
        #endif
464
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
465
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
466
#endif /* ECC128 */
467
#ifdef ECC160
468
#ifndef FP_ECC
469
    #ifndef NO_ECC_SECP
470
        #ifdef HAVE_OID_ENCODING
471
            #define CODED_SECP160R1    {1,3,132,0,8}
472
            #define CODED_SECP160R1_SZ 5
473
        #else
474
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
475
            #define CODED_SECP160R1_SZ 5
476
        #endif
477
        #ifndef WOLFSSL_ECC_CURVE_STATIC
478
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
479
        #else
480
            #define ecc_oid_secp160r1 CODED_SECP160R1
481
        #endif
482
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
483
    #endif /* !NO_ECC_SECP */
484
    #ifdef HAVE_ECC_SECPR2
485
        #ifdef HAVE_OID_ENCODING
486
            #define CODED_SECP160R2    {1,3,132,0,30}
487
            #define CODED_SECP160R2_SZ 5
488
        #else
489
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
490
            #define CODED_SECP160R2_SZ 5
491
        #endif
492
        #ifndef WOLFSSL_ECC_CURVE_STATIC
493
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
494
        #else
495
            #define ecc_oid_secp160r2 CODED_SECP160R2
496
        #endif
497
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
498
    #endif /* HAVE_ECC_SECPR2 */
499
    #ifdef HAVE_ECC_KOBLITZ
500
        #ifdef HAVE_OID_ENCODING
501
            #define CODED_SECP160K1    {1,3,132,0,9}
502
            #define CODED_SECP160K1_SZ 5
503
        #else
504
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
505
            #define CODED_SECP160K1_SZ 5
506
        #endif
507
        #ifndef WOLFSSL_ECC_CURVE_STATIC
508
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
509
        #else
510
            #define ecc_oid_secp160k1 CODED_SECP160K1
511
        #endif
512
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
513
    #endif /* HAVE_ECC_KOBLITZ */
514
#endif /* !FP_ECC */
515
    #ifdef HAVE_ECC_BRAINPOOL
516
        #ifdef HAVE_OID_ENCODING
517
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
518
            #define CODED_BRAINPOOLP160R1_SZ 10
519
        #else
520
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
521
            #define CODED_BRAINPOOLP160R1_SZ 9
522
        #endif
523
        #ifndef WOLFSSL_ECC_CURVE_STATIC
524
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
525
        #else
526
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
527
        #endif
528
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
529
    #endif /* HAVE_ECC_BRAINPOOL */
530
#endif /* ECC160 */
531
#ifdef ECC192
532
    #ifndef NO_ECC_SECP
533
        #ifdef HAVE_OID_ENCODING
534
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
535
            #define CODED_SECP192R1_SZ 7
536
        #else
537
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
538
            #define CODED_SECP192R1_SZ 8
539
        #endif
540
        #ifndef WOLFSSL_ECC_CURVE_STATIC
541
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
542
        #else
543
            #define ecc_oid_secp192r1 CODED_SECP192R1
544
        #endif
545
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
546
    #endif /* !NO_ECC_SECP */
547
    #ifdef HAVE_ECC_SECPR2
548
        #ifdef HAVE_OID_ENCODING
549
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
550
            #define CODED_PRIME192V2_SZ 7
551
        #else
552
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
553
            #define CODED_PRIME192V2_SZ 8
554
        #endif
555
        #ifndef WOLFSSL_ECC_CURVE_STATIC
556
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
557
        #else
558
            #define ecc_oid_prime192v2 CODED_PRIME192V2
559
        #endif
560
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
561
    #endif /* HAVE_ECC_SECPR2 */
562
    #ifdef HAVE_ECC_SECPR3
563
        #ifdef HAVE_OID_ENCODING
564
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
565
            #define CODED_PRIME192V3_SZ 7
566
        #else
567
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
568
            #define CODED_PRIME192V3_SZ 8
569
        #endif
570
        #ifndef WOLFSSL_ECC_CURVE_STATIC
571
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
572
        #else
573
            #define ecc_oid_prime192v3 CODED_PRIME192V3
574
        #endif
575
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
576
    #endif /* HAVE_ECC_SECPR3 */
577
    #ifdef HAVE_ECC_KOBLITZ
578
        #ifdef HAVE_OID_ENCODING
579
            #define CODED_SECP192K1    {1,3,132,0,31}
580
            #define CODED_SECP192K1_SZ 5
581
        #else
582
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
583
            #define CODED_SECP192K1_SZ 5
584
        #endif
585
        #ifndef WOLFSSL_ECC_CURVE_STATIC
586
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
587
        #else
588
            #define ecc_oid_secp192k1 CODED_SECP192K1
589
        #endif
590
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
591
    #endif /* HAVE_ECC_KOBLITZ */
592
    #ifdef HAVE_ECC_BRAINPOOL
593
        #ifdef HAVE_OID_ENCODING
594
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
595
            #define CODED_BRAINPOOLP192R1_SZ 10
596
        #else
597
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
598
            #define CODED_BRAINPOOLP192R1_SZ 9
599
        #endif
600
        #ifndef WOLFSSL_ECC_CURVE_STATIC
601
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
602
        #else
603
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
604
        #endif
605
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
606
    #endif /* HAVE_ECC_BRAINPOOL */
607
#endif /* ECC192 */
608
#ifdef ECC224
609
    #ifndef NO_ECC_SECP
610
        #ifdef HAVE_OID_ENCODING
611
            #define CODED_SECP224R1    {1,3,132,0,33}
612
            #define CODED_SECP224R1_SZ 5
613
        #else
614
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
615
            #define CODED_SECP224R1_SZ 5
616
        #endif
617
        #ifndef WOLFSSL_ECC_CURVE_STATIC
618
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
619
        #else
620
            #define ecc_oid_secp224r1 CODED_SECP224R1
621
        #endif
622
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
623
    #endif /* !NO_ECC_SECP */
624
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
625
        #ifdef HAVE_OID_ENCODING
626
            #define CODED_SECP224K1    {1,3,132,0,32}
627
            #define CODED_SECP224K1_SZ 5
628
        #else
629
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
630
            #define CODED_SECP224K1_SZ 5
631
        #endif
632
        #ifndef WOLFSSL_ECC_CURVE_STATIC
633
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
634
        #else
635
            #define ecc_oid_secp224k1 CODED_SECP224K1
636
        #endif
637
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
638
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
639
    #ifdef HAVE_ECC_BRAINPOOL
640
        #ifdef HAVE_OID_ENCODING
641
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
642
            #define CODED_BRAINPOOLP224R1_SZ 10
643
        #else
644
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
645
            #define CODED_BRAINPOOLP224R1_SZ 9
646
        #endif
647
        #ifndef WOLFSSL_ECC_CURVE_STATIC
648
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
649
        #else
650
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
651
        #endif
652
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
653
    #endif /* HAVE_ECC_BRAINPOOL */
654
#endif /* ECC224 */
655
#ifdef ECC239
656
    #ifndef NO_ECC_SECP
657
        #ifdef HAVE_OID_ENCODING
658
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
659
            #define CODED_PRIME239V1_SZ 7
660
        #else
661
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
662
            #define CODED_PRIME239V1_SZ 8
663
        #endif
664
        #ifndef WOLFSSL_ECC_CURVE_STATIC
665
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
666
        #else
667
            #define ecc_oid_prime239v1 CODED_PRIME239V1
668
        #endif
669
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
670
    #endif /* !NO_ECC_SECP */
671
    #ifdef HAVE_ECC_SECPR2
672
        #ifdef HAVE_OID_ENCODING
673
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
674
            #define CODED_PRIME239V2_SZ 7
675
        #else
676
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
677
            #define CODED_PRIME239V2_SZ 8
678
        #endif
679
        #ifndef WOLFSSL_ECC_CURVE_STATIC
680
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
681
        #else
682
            #define ecc_oid_prime239v2 CODED_PRIME239V2
683
        #endif
684
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
685
    #endif /* HAVE_ECC_SECPR2 */
686
    #ifdef HAVE_ECC_SECPR3
687
        #ifdef HAVE_OID_ENCODING
688
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
689
            #define CODED_PRIME239V3_SZ 7
690
        #else
691
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
692
            #define CODED_PRIME239V3_SZ 8
693
        #endif
694
        #ifndef WOLFSSL_ECC_CURVE_STATIC
695
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
696
        #else
697
            #define ecc_oid_prime239v3 CODED_PRIME239V3
698
        #endif
699
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
700
    #endif /* HAVE_ECC_SECPR3 */
701
#endif /* ECC239 */
702
#ifdef ECC256
703
    #ifndef NO_ECC_SECP
704
        #ifdef HAVE_OID_ENCODING
705
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
706
            #define CODED_SECP256R1_SZ 7
707
        #else
708
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
709
            #define CODED_SECP256R1_SZ 8
710
        #endif
711
        #ifndef WOLFSSL_ECC_CURVE_STATIC
712
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
713
        #else
714
            #define ecc_oid_secp256r1 CODED_SECP256R1
715
        #endif
716
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
717
    #endif /* !NO_ECC_SECP */
718
    #ifdef HAVE_ECC_KOBLITZ
719
        #ifdef HAVE_OID_ENCODING
720
            #define CODED_SECP256K1    {1,3,132,0,10}
721
            #define CODED_SECP256K1_SZ 5
722
        #else
723
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
724
            #define CODED_SECP256K1_SZ 5
725
        #endif
726
        #ifndef WOLFSSL_ECC_CURVE_STATIC
727
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
728
        #else
729
            #define ecc_oid_secp256k1 CODED_SECP256K1
730
        #endif
731
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
732
    #endif /* HAVE_ECC_KOBLITZ */
733
    #ifdef HAVE_ECC_BRAINPOOL
734
        #ifdef HAVE_OID_ENCODING
735
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
736
            #define CODED_BRAINPOOLP256R1_SZ 10
737
        #else
738
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
739
            #define CODED_BRAINPOOLP256R1_SZ 9
740
        #endif
741
        #ifndef WOLFSSL_ECC_CURVE_STATIC
742
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
743
        #else
744
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
745
        #endif
746
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
747
    #endif /* HAVE_ECC_BRAINPOOL */
748
#endif /* ECC256 */
749
    #if defined(WOLFSSL_SM2)
750
        #ifdef HAVE_OID_ENCODING
751
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
752
            #define CODED_SM2P256V1_SZ 6
753
        #else
754
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
755
            #define CODED_SM2P256V1_SZ 8
756
        #endif
757
        #ifndef WOLFSSL_ECC_CURVE_STATIC
758
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
759
        #else
760
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
761
        #endif
762
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
763
    #endif /* WOLFSSL_SM2 */
764
#ifdef ECC320
765
    #ifdef HAVE_ECC_BRAINPOOL
766
        #ifdef HAVE_OID_ENCODING
767
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
768
            #define CODED_BRAINPOOLP320R1_SZ 10
769
        #else
770
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
771
            #define CODED_BRAINPOOLP320R1_SZ 9
772
        #endif
773
        #ifndef WOLFSSL_ECC_CURVE_STATIC
774
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
775
        #else
776
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
777
        #endif
778
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
779
    #endif /* HAVE_ECC_BRAINPOOL */
780
#endif /* ECC320 */
781
#ifdef ECC384
782
    #ifndef NO_ECC_SECP
783
        #ifdef HAVE_OID_ENCODING
784
            #define CODED_SECP384R1    {1,3,132,0,34}
785
            #define CODED_SECP384R1_SZ 5
786
        #else
787
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
788
            #define CODED_SECP384R1_SZ 5
789
        #endif
790
        #ifndef WOLFSSL_ECC_CURVE_STATIC
791
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
792
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
793
        #else
794
            #define ecc_oid_secp384r1 CODED_SECP384R1
795
        #endif
796
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
797
    #endif /* !NO_ECC_SECP */
798
    #ifdef HAVE_ECC_BRAINPOOL
799
        #ifdef HAVE_OID_ENCODING
800
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
801
            #define CODED_BRAINPOOLP384R1_SZ 10
802
        #else
803
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
804
            #define CODED_BRAINPOOLP384R1_SZ 9
805
        #endif
806
        #ifndef WOLFSSL_ECC_CURVE_STATIC
807
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
808
        #else
809
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
810
        #endif
811
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
812
    #endif /* HAVE_ECC_BRAINPOOL */
813
#endif /* ECC384 */
814
#ifdef ECC512
815
    #ifdef HAVE_ECC_BRAINPOOL
816
        #ifdef HAVE_OID_ENCODING
817
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
818
            #define CODED_BRAINPOOLP512R1_SZ 10
819
        #else
820
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
821
            #define CODED_BRAINPOOLP512R1_SZ 9
822
        #endif
823
        #ifndef WOLFSSL_ECC_CURVE_STATIC
824
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
825
        #else
826
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
827
        #endif
828
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
829
    #endif /* HAVE_ECC_BRAINPOOL */
830
#endif /* ECC512 */
831
#ifdef ECC521
832
    #ifndef NO_ECC_SECP
833
        #ifdef HAVE_OID_ENCODING
834
            #define CODED_SECP521R1     {1,3,132,0,35}
835
            #define CODED_SECP521R1_SZ 5
836
        #else
837
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
838
            #define CODED_SECP521R1_SZ 5
839
        #endif
840
        #ifndef WOLFSSL_ECC_CURVE_STATIC
841
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
842
        #else
843
            #define ecc_oid_secp521r1 CODED_SECP521R1
844
        #endif
845
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
846
    #endif /* !NO_ECC_SECP */
847
#endif /* ECC521 */
848
849
850
/* This holds the key settings.
851
   ***MUST*** be organized by size from smallest to largest. */
852
853
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
854
    #undef ecc_sets
855
    #undef ecc_sets_count
856
#endif
857
858
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
859
static
860
#endif
861
const ecc_set_type ecc_sets[] = {
862
#ifdef ECC112
863
    #ifndef NO_ECC_SECP
864
    {
865
        14,                             /* size/bytes */
866
        ECC_SECP112R1,                  /* ID         */
867
        "SECP112R1",                    /* curve name */
868
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
869
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
870
        "659EF8BA043916EEDE8911702B22", /* B          */
871
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
872
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
873
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
874
        ecc_oid_secp112r1,              /* oid/oidSz  */
875
        ecc_oid_secp112r1_sz,
876
        ECC_SECP112R1_OID,              /* oid sum    */
877
        1,                              /* cofactor   */
878
    },
879
    #endif /* !NO_ECC_SECP */
880
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
881
    {
882
        14,                             /* size/bytes */
883
        ECC_SECP112R2,                  /* ID         */
884
        "SECP112R2",                    /* curve name */
885
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
886
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
887
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
888
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
889
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
890
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
891
        ecc_oid_secp112r2,              /* oid/oidSz  */
892
        ecc_oid_secp112r2_sz,
893
        ECC_SECP112R2_OID,              /* oid sum    */
894
        4,                              /* cofactor   */
895
    },
896
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
897
#endif /* ECC112 */
898
#ifdef ECC128
899
    #ifndef NO_ECC_SECP
900
    {
901
        16,                                 /* size/bytes */
902
        ECC_SECP128R1,                      /* ID         */
903
        "SECP128R1",                        /* curve name */
904
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
905
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
906
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
907
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
908
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
909
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
910
        ecc_oid_secp128r1,                  /* oid/oidSz  */
911
        ecc_oid_secp128r1_sz,
912
        ECC_SECP128R1_OID,                  /* oid sum    */
913
        1,                                  /* cofactor   */
914
    },
915
    #endif /* !NO_ECC_SECP */
916
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
917
    {
918
        16,                                 /* size/bytes */
919
        ECC_SECP128R2,                      /* ID         */
920
        "SECP128R2",                        /* curve name */
921
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
922
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
923
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
924
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
925
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
926
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
927
        ecc_oid_secp128r2,                  /* oid/oidSz  */
928
        ecc_oid_secp128r2_sz,
929
        ECC_SECP128R2_OID,                  /* oid sum    */
930
        4,                                  /* cofactor   */
931
    },
932
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
933
#endif /* ECC128 */
934
#ifdef ECC160
935
#ifndef FP_ECC
936
    #ifndef NO_ECC_SECP
937
    {
938
        20,                                         /* size/bytes */
939
        ECC_SECP160R1,                              /* ID         */
940
        "SECP160R1",                                /* curve name */
941
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
942
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
943
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
944
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
945
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
946
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
947
        ecc_oid_secp160r1,                          /* oid/oidSz  */
948
        ecc_oid_secp160r1_sz,
949
        ECC_SECP160R1_OID,                          /* oid sum    */
950
        1,                                          /* cofactor   */
951
    },
952
    #endif /* !NO_ECC_SECP */
953
    #ifdef HAVE_ECC_SECPR2
954
    {
955
        20,                                         /* size/bytes */
956
        ECC_SECP160R2,                              /* ID         */
957
        "SECP160R2",                                /* curve name */
958
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
959
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
960
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
961
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
962
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
963
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
964
        ecc_oid_secp160r2,                          /* oid/oidSz  */
965
        ecc_oid_secp160r2_sz,
966
        ECC_SECP160R2_OID,                          /* oid sum    */
967
        1,                                          /* cofactor   */
968
    },
969
    #endif /* HAVE_ECC_SECPR2 */
970
    #ifdef HAVE_ECC_KOBLITZ
971
    {
972
        20,                                         /* size/bytes */
973
        ECC_SECP160K1,                              /* ID         */
974
        "SECP160K1",                                /* curve name */
975
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
976
        "0000000000000000000000000000000000000000", /* A          */
977
        "0000000000000000000000000000000000000007", /* B          */
978
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
979
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
980
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
981
        ecc_oid_secp160k1,                          /* oid/oidSz  */
982
        ecc_oid_secp160k1_sz,
983
        ECC_SECP160K1_OID,                          /* oid sum    */
984
        1,                                          /* cofactor   */
985
    },
986
    #endif /* HAVE_ECC_KOBLITZ */
987
#endif /* !FP_ECC */
988
    #ifdef HAVE_ECC_BRAINPOOL
989
    {
990
        20,                                         /* size/bytes */
991
        ECC_BRAINPOOLP160R1,                        /* ID         */
992
        "BRAINPOOLP160R1",                          /* curve name */
993
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
994
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
995
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
996
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
997
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
998
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
999
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1000
        ecc_oid_brainpoolp160r1_sz,
1001
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1002
        1,                                          /* cofactor   */
1003
    },
1004
    #endif /* HAVE_ECC_BRAINPOOL */
1005
#endif /* ECC160 */
1006
#ifdef ECC192
1007
    #ifndef NO_ECC_SECP
1008
    {
1009
        24,                                                 /* size/bytes */
1010
        ECC_SECP192R1,                                      /* ID         */
1011
        "SECP192R1",                                        /* curve name */
1012
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1013
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1014
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1015
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1016
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1017
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1018
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1019
        ecc_oid_secp192r1_sz,
1020
        ECC_SECP192R1_OID,                                  /* oid sum    */
1021
        1,                                                  /* cofactor   */
1022
    },
1023
    #endif /* !NO_ECC_SECP */
1024
    #ifdef HAVE_ECC_SECPR2
1025
    {
1026
        24,                                                 /* size/bytes */
1027
        ECC_PRIME192V2,                                     /* ID         */
1028
        "PRIME192V2",                                       /* curve name */
1029
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1030
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1031
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1032
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1033
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1034
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1035
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1036
        ecc_oid_prime192v2_sz,
1037
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1038
        1,                                                  /* cofactor   */
1039
    },
1040
    #endif /* HAVE_ECC_SECPR2 */
1041
    #ifdef HAVE_ECC_SECPR3
1042
    {
1043
        24,                                                 /* size/bytes */
1044
        ECC_PRIME192V3,                                     /* ID         */
1045
        "PRIME192V3",                                       /* curve name */
1046
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1047
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1048
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1049
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1050
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1051
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1052
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1053
        ecc_oid_prime192v3_sz,
1054
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1055
        1,                                                  /* cofactor   */
1056
    },
1057
    #endif /* HAVE_ECC_SECPR3 */
1058
    #ifdef HAVE_ECC_KOBLITZ
1059
    {
1060
        24,                                                 /* size/bytes */
1061
        ECC_SECP192K1,                                      /* ID         */
1062
        "SECP192K1",                                        /* curve name */
1063
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1064
        "000000000000000000000000000000000000000000000000", /* A          */
1065
        "000000000000000000000000000000000000000000000003", /* B          */
1066
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1067
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1068
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1069
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1070
        ecc_oid_secp192k1_sz,
1071
        ECC_SECP192K1_OID,                                  /* oid sum    */
1072
        1,                                                  /* cofactor   */
1073
    },
1074
    #endif /* HAVE_ECC_KOBLITZ */
1075
    #ifdef HAVE_ECC_BRAINPOOL
1076
    {
1077
        24,                                                 /* size/bytes */
1078
        ECC_BRAINPOOLP192R1,                                /* ID         */
1079
        "BRAINPOOLP192R1",                                  /* curve name */
1080
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1081
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1082
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1083
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1084
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1085
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1086
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1087
        ecc_oid_brainpoolp192r1_sz,
1088
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1089
        1,                                                  /* cofactor   */
1090
    },
1091
    #endif /* HAVE_ECC_BRAINPOOL */
1092
#endif /* ECC192 */
1093
#ifdef ECC224
1094
    #ifndef NO_ECC_SECP
1095
    {
1096
        28,                                                         /* size/bytes */
1097
        ECC_SECP224R1,                                              /* ID         */
1098
        "SECP224R1",                                                /* curve name */
1099
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1100
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1101
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1102
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1103
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1104
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1105
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1106
        ecc_oid_secp224r1_sz,
1107
        ECC_SECP224R1_OID,                                          /* oid sum    */
1108
        1,                                                          /* cofactor   */
1109
    },
1110
    #endif /* !NO_ECC_SECP */
1111
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1112
    {
1113
        28,                                                         /* size/bytes */
1114
        ECC_SECP224K1,                                              /* ID         */
1115
        "SECP224K1",                                                /* curve name */
1116
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1117
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1118
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1119
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1120
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1121
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1122
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1123
        ecc_oid_secp224k1_sz,
1124
        ECC_SECP224K1_OID,                                          /* oid sum    */
1125
        1,                                                          /* cofactor   */
1126
    },
1127
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1128
    #ifdef HAVE_ECC_BRAINPOOL
1129
    {
1130
        28,                                                         /* size/bytes */
1131
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1132
        "BRAINPOOLP224R1",                                          /* curve name */
1133
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1134
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1135
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1136
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1137
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1138
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1139
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1140
        ecc_oid_brainpoolp224r1_sz,
1141
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1142
        1,                                                          /* cofactor   */
1143
    },
1144
    #endif /* HAVE_ECC_BRAINPOOL */
1145
#endif /* ECC224 */
1146
#ifdef ECC239
1147
    #ifndef NO_ECC_SECP
1148
    {
1149
        30,                                                             /* size/bytes */
1150
        ECC_PRIME239V1,                                                 /* ID         */
1151
        "PRIME239V1",                                                   /* curve name */
1152
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1153
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1154
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1155
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1156
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1157
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1158
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1159
        ecc_oid_prime239v1_sz,
1160
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1161
        1,                                                              /* cofactor   */
1162
    },
1163
    #endif /* !NO_ECC_SECP */
1164
    #ifdef HAVE_ECC_SECPR2
1165
    {
1166
        30,                                                             /* size/bytes */
1167
        ECC_PRIME239V2,                                                 /* ID         */
1168
        "PRIME239V2",                                                   /* curve name */
1169
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1170
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1171
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1172
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1173
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1174
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1175
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1176
        ecc_oid_prime239v2_sz,
1177
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1178
        1,                                                              /* cofactor   */
1179
    },
1180
    #endif /* HAVE_ECC_SECPR2 */
1181
    #ifdef HAVE_ECC_SECPR3
1182
    {
1183
        30,                                                             /* size/bytes */
1184
        ECC_PRIME239V3,                                                 /* ID         */
1185
        "PRIME239V3",                                                   /* curve name */
1186
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1187
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1188
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1189
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1190
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1191
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1192
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1193
        ecc_oid_prime239v3_sz,
1194
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1195
        1,                                                              /* cofactor   */
1196
    },
1197
    #endif /* HAVE_ECC_SECPR3 */
1198
#endif /* ECC239 */
1199
#ifdef ECC256
1200
    #ifndef NO_ECC_SECP
1201
    {
1202
        32,                                                                 /* size/bytes */
1203
        ECC_SECP256R1,                                                      /* ID         */
1204
        "SECP256R1",                                                        /* curve name */
1205
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1206
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1207
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1208
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1209
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1210
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1211
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1212
        ecc_oid_secp256r1_sz,
1213
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1214
        1,                                                                  /* cofactor   */
1215
    },
1216
    #endif /* !NO_ECC_SECP */
1217
    #ifdef HAVE_ECC_KOBLITZ
1218
    {
1219
        32,                                                                 /* size/bytes */
1220
        ECC_SECP256K1,                                                      /* ID         */
1221
        "SECP256K1",                                                        /* curve name */
1222
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1223
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1224
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1225
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1226
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1227
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1228
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1229
        ecc_oid_secp256k1_sz,
1230
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1231
        1,                                                                  /* cofactor   */
1232
    },
1233
    #endif /* HAVE_ECC_KOBLITZ */
1234
    #ifdef HAVE_ECC_BRAINPOOL
1235
    {
1236
        32,                                                                 /* size/bytes */
1237
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1238
        "BRAINPOOLP256R1",                                                  /* curve name */
1239
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1240
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1241
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1242
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1243
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1244
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1245
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1246
        ecc_oid_brainpoolp256r1_sz,
1247
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1248
        1,                                                                  /* cofactor   */
1249
    },
1250
    #endif /* HAVE_ECC_BRAINPOOL */
1251
#endif /* ECC256 */
1252
    #if defined(WOLFSSL_SM2)
1253
    {
1254
        32,                                                     /* size/bytes */
1255
        ECC_SM2P256V1,                                          /* ID         */
1256
        "SM2P256V1",                                            /* curve name */
1257
1258
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1259
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1260
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1261
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1262
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1263
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1264
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1265
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1266
        ecc_oid_sm2p256v1_sz,
1267
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1268
        1,                                                      /* cofactor   */
1269
    },
1270
    #endif /* WOLFSSL_SM2 */
1271
#ifdef ECC320
1272
    #ifdef HAVE_ECC_BRAINPOOL
1273
    {
1274
        40,                                                                                 /* size/bytes */
1275
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1276
        "BRAINPOOLP320R1",                                                                  /* curve name */
1277
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1278
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1279
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1280
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1281
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1282
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1283
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1284
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1285
        1,                                                                                  /* cofactor   */
1286
    },
1287
    #endif /* HAVE_ECC_BRAINPOOL */
1288
#endif /* ECC320 */
1289
#ifdef ECC384
1290
    #ifndef NO_ECC_SECP
1291
    {
1292
        48,                                                                                                 /* size/bytes */
1293
        ECC_SECP384R1,                                                                                      /* ID         */
1294
        "SECP384R1",                                                                                        /* curve name */
1295
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1296
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1297
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1298
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1299
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1300
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1301
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1302
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1303
        1,                                                                                                  /* cofactor   */
1304
    },
1305
    #endif /* !NO_ECC_SECP */
1306
    #ifdef HAVE_ECC_BRAINPOOL
1307
    {
1308
        48,                                                                                                 /* size/bytes */
1309
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1310
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1311
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1312
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1313
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1314
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1315
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1316
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1317
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1318
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1319
        1,                                                                                                  /* cofactor   */
1320
    },
1321
    #endif /* HAVE_ECC_BRAINPOOL */
1322
#endif /* ECC384 */
1323
#ifdef ECC512
1324
    #ifdef HAVE_ECC_BRAINPOOL
1325
    {
1326
        64,                                                                                                                                 /* size/bytes */
1327
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1328
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1329
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1330
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1331
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1332
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1333
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1334
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1335
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1336
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1337
        1,                                                                                                                                  /* cofactor   */
1338
    },
1339
    #endif /* HAVE_ECC_BRAINPOOL */
1340
#endif /* ECC512 */
1341
#ifdef ECC521
1342
    #ifndef NO_ECC_SECP
1343
    {
1344
        66,                                                                                                                                    /* size/bytes */
1345
        ECC_SECP521R1,                                                                                                                         /* ID         */
1346
        "SECP521R1",                                                                                                                           /* curve name */
1347
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1348
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1349
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1350
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1351
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1352
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1353
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1354
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1355
        1,                                                                                                                                     /* cofactor   */
1356
    },
1357
    #endif /* !NO_ECC_SECP */
1358
#endif /* ECC521 */
1359
#ifdef WOLFCRYPT_HAVE_SAKKE
1360
    {
1361
        128,
1362
        ECC_SAKKE_1,
1363
        "SAKKE1",
1364
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1365
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1366
        "0",
1367
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1368
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1369
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1370
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1371
            NULL, 0,
1372
        #else
1373
            {0}, 0,
1374
        #endif
1375
        0,
1376
        4,
1377
    },
1378
#endif
1379
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1380
    /* place holder for custom curve index for cache */
1381
    {
1382
        1, /* non-zero */
1383
        ECC_CURVE_CUSTOM,
1384
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1385
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1386
        #else
1387
            {0},{0},{0},{0},{0},{0},{0},{0},
1388
        #endif
1389
        0, 0, 0
1390
    },
1391
#endif
1392
    {
1393
        0,
1394
        ECC_CURVE_INVALID,
1395
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1396
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1397
        #else
1398
            {0},{0},{0},{0},{0},{0},{0},{0},
1399
        #endif
1400
        0, 0, 0
1401
    }
1402
};
1403
78.1k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1404
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1405
static
1406
#endif
1407
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1408
1409
220k
const ecc_set_type *wc_ecc_get_sets(void) {
1410
220k
    return ecc_sets;
1411
220k
}
1412
0
size_t wc_ecc_get_sets_count(void) {
1413
0
    return ecc_sets_count;
1414
0
}
1415
1416
#ifdef HAVE_OID_ENCODING
1417
    /* encoded OID cache */
1418
    typedef struct {
1419
        word32 oidSz;
1420
        byte oid[ECC_MAX_OID_LEN];
1421
    } oid_cache_t;
1422
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1423
1424
    static wolfSSL_Mutex ecc_oid_cache_lock
1425
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1426
#ifndef WOLFSSL_MUTEX_INITIALIZER
1427
    static volatile int eccOidLockInit = 0;
1428
#endif
1429
#endif /* HAVE_OID_ENCODING */
1430
1431
/* Forward declarations */
1432
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1433
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1434
#endif
1435
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1436
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1437
    mp_int* prime, mp_int* order);
1438
#endif
1439
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1440
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1441
    !defined(WOLFSSL_KCAPI_ECC)
1442
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1443
#endif
1444
1445
1446
#ifdef HAVE_COMP_KEY
1447
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1448
    !defined(WOLFSSL_CRYPTOCELL)
1449
1450
#ifndef WOLFSSL_SP_MATH
1451
#if !defined(SQRTMOD_USE_MOD_EXP)
1452
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1453
#endif
1454
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1455
#endif
1456
#endif
1457
#endif
1458
1459
1460
/* Curve Specs */
1461
typedef struct ecc_curve_spec {
1462
    const ecc_set_type* dp;
1463
1464
    mp_int* prime;
1465
    mp_int* Af;
1466
    #ifdef USE_ECC_B_PARAM
1467
        mp_int* Bf;
1468
    #endif
1469
    mp_int* order;
1470
    mp_int* Gx;
1471
    mp_int* Gy;
1472
1473
#ifdef ECC_CACHE_CURVE
1474
    mp_int prime_lcl;
1475
    mp_int Af_lcl;
1476
    #ifdef USE_ECC_B_PARAM
1477
        mp_int Bf_lcl;
1478
    #endif
1479
    mp_int order_lcl;
1480
    mp_int Gx_lcl;
1481
    mp_int Gy_lcl;
1482
#else
1483
#ifdef WOLFSSL_SP_MATH_ALL
1484
    unsigned char* spec_ints;
1485
#else
1486
    mp_int* spec_ints;
1487
#endif
1488
    word32 spec_count;
1489
    word32 spec_use;
1490
#endif
1491
1492
    byte load_mask;
1493
} ecc_curve_spec;
1494
1495
    #define ECC_CURVE_FIELD_NONE    0x00
1496
257k
    #define ECC_CURVE_FIELD_PRIME   0x01
1497
257k
    #define ECC_CURVE_FIELD_AF      0x02
1498
#ifdef USE_ECC_B_PARAM
1499
255k
    #define ECC_CURVE_FIELD_BF      0x04
1500
#endif
1501
236k
    #define ECC_CURVE_FIELD_ORDER   0x08
1502
196k
    #define ECC_CURVE_FIELD_GX      0x10
1503
196k
    #define ECC_CURVE_FIELD_GY      0x20
1504
#ifdef USE_ECC_B_PARAM
1505
4.77k
    #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
        unsigned char* spec_ints = NULL;                                \
1571
        ecc_curve_spec curve_lcl;                                       \
1572
        ecc_curve_spec* curve = &curve_lcl;                             \
1573
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1574
        curve->spec_count = intcount
1575
1576
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1577
    do {                                                                \
1578
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1579
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1580
            DYNAMIC_TYPE_ECC);                                          \
1581
        if (spec_ints == NULL)                                          \
1582
            (err) = MEMORY_E;                                           \
1583
        else {                                                          \
1584
            curve->spec_ints = spec_ints;                               \
1585
            (err) = MP_OKAY;                                            \
1586
        }                                                               \
1587
    } while (0)
1588
#else
1589
    #define DECLARE_CURVE_SPECS(intcount)                               \
1590
16.5k
        mp_int* spec_ints = NULL;                                       \
1591
16.5k
        ecc_curve_spec curve_lcl;                                       \
1592
16.5k
        ecc_curve_spec* curve = &curve_lcl;                             \
1593
16.5k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1594
16.5k
        curve->spec_count = intcount
1595
1596
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1597
14.9k
    do {                                                                \
1598
14.9k
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1599
14.9k
                            DYNAMIC_TYPE_ECC);                          \
1600
14.9k
        if (spec_ints == NULL)                                          \
1601
14.9k
            (err) = MEMORY_E;                                           \
1602
14.9k
        else {                                                          \
1603
14.7k
            curve->spec_ints = spec_ints;                               \
1604
14.7k
            (err) = MP_OKAY;                                            \
1605
14.7k
        }                                                               \
1606
14.9k
    } while (0)
1607
#endif
1608
    #define FREE_CURVE_SPECS()                                          \
1609
14.9k
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1610
#else
1611
#ifdef WOLFSSL_SP_MATH_ALL
1612
    #define DECLARE_CURVE_SPECS(intcount)                               \
1613
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1614
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1615
        ecc_curve_spec curve_lcl;                                       \
1616
        ecc_curve_spec* curve = &curve_lcl;                             \
1617
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1618
        curve->spec_ints = spec_ints;                                   \
1619
        curve->spec_count = (intcount)
1620
#else
1621
    #define DECLARE_CURVE_SPECS(intcount)                               \
1622
        mp_int spec_ints[(intcount)];                                   \
1623
        ecc_curve_spec curve_lcl;                                       \
1624
        ecc_curve_spec* curve = &curve_lcl;                             \
1625
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1626
        curve->spec_ints = spec_ints;                                   \
1627
        curve->spec_count = (intcount)
1628
#endif
1629
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1630
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1631
#endif /* ECC_CACHE_CURVE */
1632
1633
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1634
    byte mask)
1635
286k
{
1636
286k
    if (item) {
1637
    #ifdef HAVE_WOLF_BIGINT
1638
        wc_bigint_free(&item->raw);
1639
    #endif
1640
286k
        mp_clear(item);
1641
286k
    }
1642
286k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1643
286k
}
1644
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1645
69.3k
{
1646
69.3k
    if (curve == NULL) {
1647
0
        return;
1648
0
    }
1649
1650
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1651
57.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1652
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1653
57.2k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1654
69.3k
#ifdef USE_ECC_B_PARAM
1655
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1656
55.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1657
69.3k
#endif
1658
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1659
47.9k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1660
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1661
29.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1662
69.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1663
29.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1664
1665
69.3k
    curve->load_mask = 0;
1666
69.3k
}
1667
1668
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1669
71.8k
{
1670
71.8k
    if (curve) {
1671
    #ifdef ECC_CACHE_CURVE
1672
        #ifdef WOLFSSL_CUSTOM_CURVES
1673
        /* only free custom curves (rest are globally cached) */
1674
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1675
            wc_ecc_curve_cache_free_spec(curve);
1676
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1677
        }
1678
        #endif
1679
    #else
1680
71.8k
        wc_ecc_curve_cache_free_spec(curve);
1681
71.8k
    #endif
1682
71.8k
    }
1683
71.8k
}
1684
1685
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1686
    mp_int** dst, byte mask)
1687
84.1k
{
1688
84.1k
    int err;
1689
1690
84.1k
#ifndef ECC_CACHE_CURVE
1691
    /* get mp_int from temp */
1692
84.1k
    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
#ifdef WOLFSSL_SP_MATH_ALL
1697
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1698
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1699
#else
1700
84.1k
    *dst = &curve->spec_ints[curve->spec_use++];
1701
84.1k
#endif
1702
84.1k
#endif
1703
1704
#ifdef WOLFSSL_SP_MATH_ALL
1705
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1706
#else
1707
84.1k
    err = mp_init(*dst);
1708
84.1k
#endif
1709
84.1k
    if (err == MP_OKAY) {
1710
84.1k
        curve->load_mask |= mask;
1711
1712
84.1k
        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
84.1k
    }
1719
84.1k
    return err;
1720
84.1k
}
1721
1722
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1723
    byte load_mask)
1724
67.7k
{
1725
67.7k
    int ret = 0;
1726
67.7k
    ecc_curve_spec* curve;
1727
67.7k
    byte load_items = 0; /* mask of items to load */
1728
#ifdef ECC_CACHE_CURVE
1729
    int x;
1730
#endif
1731
1732
67.7k
    if (dp == NULL || pCurve == NULL)
1733
0
        return BAD_FUNC_ARG;
1734
1735
#ifdef ECC_CACHE_CURVE
1736
    x = wc_ecc_get_curve_idx(dp->id);
1737
    if (x == ECC_CURVE_INVALID)
1738
        return ECC_BAD_ARG_E;
1739
1740
#if !defined(SINGLE_THREADED)
1741
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1742
    if (ret != 0) {
1743
        return ret;
1744
    }
1745
#endif
1746
1747
#ifdef WOLFSSL_NO_MALLOC
1748
    curve = &ecc_curve_spec_cache[x];
1749
#else
1750
    /* make sure cache has been allocated */
1751
    if (ecc_curve_spec_cache[x] == NULL
1752
    #ifdef WOLFSSL_CUSTOM_CURVES
1753
        || dp->id == ECC_CURVE_CUSTOM
1754
    #endif
1755
    ) {
1756
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1757
        if (curve == NULL) {
1758
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1759
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1760
        #endif
1761
            return MEMORY_E;
1762
        }
1763
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1764
1765
        /* set curve pointer to cache */
1766
    #ifdef WOLFSSL_CUSTOM_CURVES
1767
        if (dp->id != ECC_CURVE_CUSTOM)
1768
    #endif
1769
        {
1770
            ecc_curve_spec_cache[x] = curve;
1771
        }
1772
    }
1773
    else {
1774
        curve = ecc_curve_spec_cache[x];
1775
    }
1776
#endif /* WOLFSSL_NO_MALLOC */
1777
1778
    /* return new or cached curve */
1779
    *pCurve = curve;
1780
#else
1781
67.7k
    curve = *pCurve;
1782
67.7k
#endif /* ECC_CACHE_CURVE */
1783
1784
    /* make sure the curve is initialized */
1785
67.7k
    if (curve->dp != dp) {
1786
67.7k
        curve->load_mask = 0;
1787
1788
    #ifdef ECC_CACHE_CURVE
1789
        curve->prime = &curve->prime_lcl;
1790
        curve->Af = &curve->Af_lcl;
1791
        #ifdef USE_ECC_B_PARAM
1792
            curve->Bf = &curve->Bf_lcl;
1793
        #endif
1794
        curve->order = &curve->order_lcl;
1795
        curve->Gx = &curve->Gx_lcl;
1796
        curve->Gy = &curve->Gy_lcl;
1797
    #endif
1798
67.7k
    }
1799
67.7k
    curve->dp = dp; /* set dp info */
1800
1801
    /* determine items to load */
1802
67.7k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1803
67.7k
    curve->load_mask |= load_items;
1804
1805
    /* load items */
1806
67.7k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1807
57.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1808
57.2k
            ECC_CURVE_FIELD_PRIME);
1809
67.7k
    if (load_items & ECC_CURVE_FIELD_AF)
1810
57.2k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1811
57.2k
            ECC_CURVE_FIELD_AF);
1812
67.7k
#ifdef USE_ECC_B_PARAM
1813
67.7k
    if (load_items & ECC_CURVE_FIELD_BF)
1814
55.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1815
55.8k
            ECC_CURVE_FIELD_BF);
1816
67.7k
#endif
1817
67.7k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1818
47.9k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1819
47.9k
            ECC_CURVE_FIELD_ORDER);
1820
67.7k
    if (load_items & ECC_CURVE_FIELD_GX)
1821
29.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1822
29.8k
            ECC_CURVE_FIELD_GX);
1823
67.7k
    if (load_items & ECC_CURVE_FIELD_GY)
1824
29.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1825
29.8k
            ECC_CURVE_FIELD_GY);
1826
1827
    /* check for error */
1828
67.7k
    if (ret != 0) {
1829
182
        wc_ecc_curve_free(curve);
1830
182
        ret = MP_READ_E;
1831
182
    }
1832
1833
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1834
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1835
#endif
1836
1837
67.7k
    return ret;
1838
67.7k
}
1839
1840
#ifdef ECC_CACHE_CURVE
1841
int wc_ecc_curve_cache_init(void)
1842
{
1843
    int ret = 0;
1844
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1845
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1846
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1847
#endif
1848
    return ret;
1849
}
1850
1851
void wc_ecc_curve_cache_free(void)
1852
{
1853
    int x;
1854
1855
    /* free all ECC curve caches */
1856
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1857
    #ifdef WOLFSSL_NO_MALLOC
1858
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1859
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1860
    #else
1861
        if (ecc_curve_spec_cache[x]) {
1862
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1863
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1864
            ecc_curve_spec_cache[x] = NULL;
1865
        }
1866
    #endif /* WOLFSSL_NO_MALLOC */
1867
    }
1868
1869
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1870
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1871
    wc_FreeMutex(&ecc_curve_cache_mutex);
1872
#endif
1873
}
1874
#endif /* ECC_CACHE_CURVE */
1875
1876
1877
/* Retrieve the curve name for the ECC curve id.
1878
 *
1879
 * curve_id  The id of the curve.
1880
 * returns the name stored from the curve if available, otherwise NULL.
1881
 */
1882
const char* wc_ecc_get_name(int curve_id)
1883
11.8k
{
1884
11.8k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1885
11.8k
    if (curve_idx == ECC_CURVE_INVALID)
1886
48
        return NULL;
1887
11.8k
    return ecc_sets[curve_idx].name;
1888
11.8k
}
1889
1890
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1891
56.9k
{
1892
56.9k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1893
0
        return BAD_FUNC_ARG;
1894
0
    }
1895
1896
56.9k
    if (keysize > ECC_MAXSIZE) {
1897
847
        return ECC_BAD_ARG_E;
1898
847
    }
1899
1900
    /* handle custom case */
1901
56.0k
    if (key->idx != ECC_CUSTOM_IDX) {
1902
55.9k
        int x;
1903
1904
        /* default values */
1905
55.9k
        key->idx = 0;
1906
55.9k
        key->dp = NULL;
1907
1908
        /* find ecc_set based on curve_id or key size */
1909
822k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1910
822k
            if (curve_id > ECC_CURVE_DEF) {
1911
717k
                if (curve_id == ecc_sets[x].id)
1912
50.4k
                  break;
1913
717k
            }
1914
105k
            else if (keysize <= ecc_sets[x].size) {
1915
5.31k
                break;
1916
5.31k
            }
1917
822k
        }
1918
55.9k
        if (ecc_sets[x].size == 0) {
1919
192
            WOLFSSL_MSG("ECC Curve not found");
1920
192
            return ECC_CURVE_OID_E;
1921
192
        }
1922
1923
55.7k
        key->idx = x;
1924
55.7k
        key->dp  = &ecc_sets[x];
1925
55.7k
    }
1926
1927
55.8k
    return 0;
1928
56.0k
}
1929
1930
1931
#ifdef ALT_ECC_SIZE
1932
static void alt_fp_init(mp_int* a)
1933
{
1934
    a->size = FP_SIZE_ECC;
1935
    mp_zero(a);
1936
}
1937
#endif /* ALT_ECC_SIZE */
1938
1939
1940
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1941
    !defined(WOLFSSL_CRYPTOCELL) && \
1942
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
1943
      defined(WOLFSSL_IMXRT1170_CAAM))
1944
1945
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
1946
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
1947
                                     mp_int* modulus, mp_digit mp);
1948
1949
/**
1950
   Add two ECC points
1951
   P        The point to add
1952
   Q        The point to add
1953
   R        [out] The destination of the double
1954
   a        ECC curve parameter a
1955
   modulus  The modulus of the field the ECC curve is in
1956
   mp       The "b" value from montgomery_setup()
1957
   return   MP_OKAY on success
1958
*/
1959
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
1960
                                     mp_int* a, mp_int* modulus, mp_digit mp)
1961
1.63k
{
1962
#if !defined(WOLFSSL_SP_MATH)
1963
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1964
   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
   mp_int  *x, *y, *z;
1971
   int     err;
1972
1973
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1974
   if (Q == R) {
1975
      ecc_point* tPt  = P;
1976
      P = Q;
1977
      Q = tPt;
1978
   }
1979
1980
#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
#endif /* WOLFSSL_SMALL_STACK */
1994
   {
1995
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1996
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1997
   #ifdef MP_INT_SIZE_CHECK_NULL
1998
      if (t1 == NULL || t2 == NULL) {
1999
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2000
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2001
         return MEMORY_E;
2002
      }
2003
   #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
   }
2020
2021
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2022
   if (err == MP_OKAY) {
2023
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2024
   }
2025
   if (err != MP_OKAY) {
2026
#ifdef WOLFSSL_SMALL_STACK
2027
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2028
      if (R->key == NULL)
2029
   #endif
2030
#endif
2031
      {
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
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2038
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2039
      }
2040
      return err;
2041
   }
2042
2043
   /* should we dbl instead? */
2044
   if (err == MP_OKAY) {
2045
#ifdef ECC_TIMING_RESISTANT
2046
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2047
#else
2048
      err = mp_sub(modulus, Q->y, t1);
2049
#endif
2050
   }
2051
   if (err == MP_OKAY) {
2052
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2053
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2054
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2055
          mp_clear(t1);
2056
          mp_clear(t2);
2057
   #ifdef WOLFSSL_SMALL_STACK
2058
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2059
         if (R->key == NULL)
2060
      #endif
2061
   #endif
2062
         {
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
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2069
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2070
         }
2071
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2072
      }
2073
   }
2074
2075
   if (err != MP_OKAY) {
2076
      goto done;
2077
   }
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
   x = R->x;
2100
   y = R->y;
2101
   z = R->z;
2102
#endif
2103
2104
   if (err == MP_OKAY)
2105
       err = mp_copy(P->x, x);
2106
   if (err == MP_OKAY)
2107
       err = mp_copy(P->y, y);
2108
   if (err == MP_OKAY)
2109
       err = mp_copy(P->z, z);
2110
2111
   /* if Z is one then these are no-operations */
2112
   if (err == MP_OKAY) {
2113
       if (!mp_iszero(Q->z)) {
2114
           /* T1 = Z' * Z' */
2115
           err = mp_sqr(Q->z, t1);
2116
           if (err == MP_OKAY)
2117
               err = mp_montgomery_reduce(t1, modulus, mp);
2118
2119
           /* X = X * T1 */
2120
           if (err == MP_OKAY)
2121
               err = mp_mul(t1, x, x);
2122
           if (err == MP_OKAY)
2123
               err = mp_montgomery_reduce(x, modulus, mp);
2124
2125
           /* T1 = Z' * T1 */
2126
           if (err == MP_OKAY)
2127
               err = mp_mul(Q->z, t1, t1);
2128
           if (err == MP_OKAY)
2129
               err = mp_montgomery_reduce(t1, modulus, mp);
2130
2131
           /* Y = Y * T1 */
2132
           if (err == MP_OKAY)
2133
               err = mp_mul(t1, y, y);
2134
           if (err == MP_OKAY)
2135
               err = mp_montgomery_reduce(y, modulus, mp);
2136
       }
2137
   }
2138
2139
   /* T1 = Z*Z */
2140
   if (err == MP_OKAY)
2141
       err = mp_sqr(z, t1);
2142
   if (err == MP_OKAY)
2143
       err = mp_montgomery_reduce(t1, modulus, mp);
2144
2145
   /* T2 = X' * T1 */
2146
   if (err == MP_OKAY)
2147
       err = mp_mul(Q->x, t1, t2);
2148
   if (err == MP_OKAY)
2149
       err = mp_montgomery_reduce(t2, modulus, mp);
2150
2151
   /* T1 = Z * T1 */
2152
   if (err == MP_OKAY)
2153
       err = mp_mul(z, t1, t1);
2154
   if (err == MP_OKAY)
2155
       err = mp_montgomery_reduce(t1, modulus, mp);
2156
2157
   /* T1 = Y' * T1 */
2158
   if (err == MP_OKAY)
2159
       err = mp_mul(Q->y, t1, t1);
2160
   if (err == MP_OKAY)
2161
       err = mp_montgomery_reduce(t1, modulus, mp);
2162
2163
   /* Y = Y - T1 */
2164
   if (err == MP_OKAY)
2165
       err = mp_submod_ct(y, t1, modulus, y);
2166
   /* T1 = 2T1 */
2167
   if (err == MP_OKAY)
2168
       err = mp_addmod_ct(t1, t1, modulus, t1);
2169
   /* T1 = Y + T1 */
2170
   if (err == MP_OKAY)
2171
       err = mp_addmod_ct(t1, y, modulus, t1);
2172
   /* X = X - T2 */
2173
   if (err == MP_OKAY)
2174
       err = mp_submod_ct(x, t2, modulus, x);
2175
   /* T2 = 2T2 */
2176
   if (err == MP_OKAY)
2177
       err = mp_addmod_ct(t2, t2, modulus, t2);
2178
   /* T2 = X + T2 */
2179
   if (err == MP_OKAY)
2180
       err = mp_addmod_ct(t2, x, modulus, t2);
2181
2182
   if (err == MP_OKAY) {
2183
       if (!mp_iszero(Q->z)) {
2184
           /* Z = Z * Z' */
2185
           err = mp_mul(z, Q->z, z);
2186
           if (err == MP_OKAY)
2187
               err = mp_montgomery_reduce(z, modulus, mp);
2188
       }
2189
   }
2190
2191
   /* Z = Z * X */
2192
   if (err == MP_OKAY)
2193
       err = mp_mul(z, x, z);
2194
   if (err == MP_OKAY)
2195
       err = mp_montgomery_reduce(z, modulus, mp);
2196
2197
   /* T1 = T1 * X  */
2198
   if (err == MP_OKAY)
2199
       err = mp_mul(t1, x, t1);
2200
   if (err == MP_OKAY)
2201
       err = mp_montgomery_reduce(t1, modulus, mp);
2202
2203
   /* X = X * X */
2204
   if (err == MP_OKAY)
2205
       err = mp_sqr(x, x);
2206
   if (err == MP_OKAY)
2207
       err = mp_montgomery_reduce(x, modulus, mp);
2208
2209
   /* T2 = T2 * x */
2210
   if (err == MP_OKAY)
2211
       err = mp_mul(t2, x, t2);
2212
   if (err == MP_OKAY)
2213
       err = mp_montgomery_reduce(t2, modulus, mp);
2214
2215
   /* T1 = T1 * X  */
2216
   if (err == MP_OKAY)
2217
       err = mp_mul(t1, x, t1);
2218
   if (err == MP_OKAY)
2219
       err = mp_montgomery_reduce(t1, modulus, mp);
2220
2221
   /* X = Y*Y */
2222
   if (err == MP_OKAY)
2223
       err = mp_sqr(y, x);
2224
   if (err == MP_OKAY)
2225
       err = mp_montgomery_reduce(x, modulus, mp);
2226
2227
   /* X = X - T2 */
2228
   if (err == MP_OKAY)
2229
       err = mp_submod_ct(x, t2, modulus, x);
2230
   /* T2 = T2 - X */
2231
   if (err == MP_OKAY)
2232
       err = mp_submod_ct(t2, x, modulus, t2);
2233
   /* T2 = T2 - X */
2234
   if (err == MP_OKAY)
2235
       err = mp_submod_ct(t2, x, modulus, t2);
2236
   /* T2 = T2 * Y */
2237
   if (err == MP_OKAY)
2238
       err = mp_mul(t2, y, t2);
2239
   if (err == MP_OKAY)
2240
       err = mp_montgomery_reduce(t2, modulus, mp);
2241
2242
   /* Y = T2 - T1 */
2243
   if (err == MP_OKAY)
2244
       err = mp_submod_ct(t2, t1, modulus, y);
2245
   /* Y = Y/2 */
2246
   if (err == MP_OKAY)
2247
       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
done:
2259
2260
   /* clean up */
2261
   mp_clear(t1);
2262
   mp_clear(t2);
2263
#ifdef WOLFSSL_SMALL_STACK
2264
#ifdef WOLFSSL_SMALL_STACK_CACHE
2265
   if (R->key == NULL)
2266
#endif
2267
#endif
2268
   {
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
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2275
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2276
   }
2277
2278
   return err;
2279
#else
2280
1.63k
    int modBits = mp_count_bits(modulus);
2281
2282
1.63k
    (void)a;
2283
1.63k
    (void)mp;
2284
2285
1.63k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2286
1.63k
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2287
354
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2288
354
                                            R->x, R->y, R->z);
2289
354
    }
2290
1.27k
#endif
2291
1.27k
#ifndef WOLFSSL_SP_NO_256
2292
1.27k
    if (modBits == 256) {
2293
326
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2294
326
                                         R->x, R->y, R->z);
2295
326
    }
2296
951
#endif
2297
951
#ifdef WOLFSSL_SP_384
2298
951
    if (modBits == 384) {
2299
444
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2300
444
                                         R->x, R->y, R->z);
2301
444
    }
2302
507
#endif
2303
507
#ifdef WOLFSSL_SP_521
2304
507
    if (modBits == 521) {
2305
507
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2306
507
                                         R->x, R->y, R->z);
2307
507
    }
2308
0
#endif
2309
0
    return ECC_BAD_ARG_E;
2310
507
#endif
2311
507
}
2312
2313
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2314
                             mp_int* a, mp_int* modulus, mp_digit mp)
2315
2.94k
{
2316
2.94k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2317
0
        return ECC_BAD_ARG_E;
2318
0
    }
2319
2320
2.94k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2321
2.92k
        mp_cmp(P->y, modulus) != MP_LT ||
2322
2.88k
        mp_cmp(P->z, modulus) != MP_LT ||
2323
2.88k
        mp_cmp(Q->x, modulus) != MP_LT ||
2324
2.84k
        mp_cmp(Q->y, modulus) != MP_LT ||
2325
2.80k
        mp_cmp(Q->z, modulus) != MP_LT) {
2326
140
        return ECC_OUT_OF_RANGE_E;
2327
140
    }
2328
2329
2.80k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2330
2.94k
}
2331
2332
/* ### Point doubling in Jacobian coordinate system ###
2333
 *
2334
 * let us have a curve:                 y^2 = x^3 + a*x + b
2335
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2336
 *
2337
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2338
 * Xr = M^2 - 2*S
2339
 * Yr = M * (S - Xr) - 8*T
2340
 * Zr = 2 * Yp * Zp
2341
 *
2342
 * M = 3 * Xp^2 + a*Zp^4
2343
 * T = Yp^4
2344
 * S = 4 * Xp * Yp^2
2345
 *
2346
 * SPECIAL CASE: when a == 3 we can compute M as
2347
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2348
 */
2349
2350
/**
2351
   Double an ECC point
2352
   P   The point to double
2353
   R   [out] The destination of the double
2354
   a   ECC curve parameter a
2355
   modulus  The modulus of the field the ECC curve is in
2356
   mp       The "b" value from montgomery_setup()
2357
   return   MP_OKAY on success
2358
*/
2359
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2360
                                     mp_int* modulus, mp_digit mp)
2361
944
{
2362
#if !defined(WOLFSSL_SP_MATH)
2363
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2364
   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
   mp_int *x, *y, *z;
2371
   int    err;
2372
2373
#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
#endif
2387
   {
2388
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2389
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2390
   #ifdef MP_INT_SIZE_CHECK_NULL
2391
      if (t1 == NULL || t2 == NULL) {
2392
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2393
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2394
         return MEMORY_E;
2395
      }
2396
   #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
   }
2413
2414
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2415
   if (err == MP_OKAY) {
2416
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2417
   }
2418
   if (err != MP_OKAY) {
2419
#ifdef WOLFSSL_SMALL_STACK
2420
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2421
      if (R->key == NULL)
2422
   #endif
2423
#endif
2424
      {
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
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2431
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2432
      }
2433
      return err;
2434
   }
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
   x = R->x;
2471
   y = R->y;
2472
   z = R->z;
2473
#endif
2474
2475
   if (err == MP_OKAY)
2476
       err = mp_copy(P->x, x);
2477
   if (err == MP_OKAY)
2478
       err = mp_copy(P->y, y);
2479
   if (err == MP_OKAY)
2480
       err = mp_copy(P->z, z);
2481
2482
   /* T1 = Z * Z */
2483
   if (err == MP_OKAY)
2484
       err = mp_sqr(z, t1);
2485
   if (err == MP_OKAY)
2486
       err = mp_montgomery_reduce(t1, modulus, mp);
2487
2488
   /* Z = Y * Z */
2489
   if (err == MP_OKAY)
2490
       err = mp_mul(z, y, z);
2491
   if (err == MP_OKAY)
2492
       err = mp_montgomery_reduce(z, modulus, mp);
2493
2494
   /* Z = 2Z */
2495
   if (err == MP_OKAY)
2496
       err = mp_addmod_ct(z, z, modulus, z);
2497
2498
   /* Determine if curve "a" should be used in calc */
2499
#ifdef WOLFSSL_CUSTOM_CURVES
2500
   if (err == MP_OKAY) {
2501
      /* Use a and prime to determine if a == 3 */
2502
      err = mp_submod(modulus, a, modulus, t2);
2503
   }
2504
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2505
      /* T2 = X * X */
2506
      err = mp_sqr(x, t2);
2507
      if (err == MP_OKAY)
2508
          err = mp_montgomery_reduce(t2, modulus, mp);
2509
      /* T1 = T2 + T1 */
2510
      if (err == MP_OKAY)
2511
          err = mp_addmod_ct(t2, t2, modulus, t1);
2512
      /* T1 = T2 + T1 */
2513
      if (err == MP_OKAY)
2514
          err = mp_addmod_ct(t1, t2, modulus, t1);
2515
   }
2516
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2517
      /* use "a" in calc */
2518
2519
      /* T2 = T1 * T1 */
2520
      err = mp_sqr(t1, t2);
2521
      if (err == MP_OKAY)
2522
          err = mp_montgomery_reduce(t2, modulus, mp);
2523
      /* T1 = T2 * a */
2524
      if (err == MP_OKAY)
2525
          err = mp_mulmod(t2, a, modulus, t1);
2526
      /* T2 = X * X */
2527
      if (err == MP_OKAY)
2528
          err = mp_sqr(x, t2);
2529
      if (err == MP_OKAY)
2530
          err = mp_montgomery_reduce(t2, modulus, mp);
2531
      /* T1 = T2 + T1 */
2532
      if (err == MP_OKAY)
2533
          err = mp_addmod_ct(t1, t2, modulus, t1);
2534
      /* T1 = T2 + T1 */
2535
      if (err == MP_OKAY)
2536
          err = mp_addmod_ct(t1, t2, modulus, t1);
2537
      /* T1 = T2 + T1 */
2538
      if (err == MP_OKAY)
2539
          err = mp_addmod_ct(t1, t2, modulus, t1);
2540
   }
2541
   else
2542
#endif /* WOLFSSL_CUSTOM_CURVES */
2543
   {
2544
      /* assumes "a" == 3 */
2545
      (void)a;
2546
2547
      /* T2 = X - T1 */
2548
      if (err == MP_OKAY)
2549
          err = mp_submod_ct(x, t1, modulus, t2);
2550
      /* T1 = X + T1 */
2551
      if (err == MP_OKAY)
2552
          err = mp_addmod_ct(t1, x, modulus, t1);
2553
      /* T2 = T1 * T2 */
2554
      if (err == MP_OKAY)
2555
          err = mp_mul(t1, t2, t2);
2556
      if (err == MP_OKAY)
2557
          err = mp_montgomery_reduce(t2, modulus, mp);
2558
2559
      /* T1 = 2T2 */
2560
      if (err == MP_OKAY)
2561
          err = mp_addmod_ct(t2, t2, modulus, t1);
2562
      /* T1 = T1 + T2 */
2563
      if (err == MP_OKAY)
2564
          err = mp_addmod_ct(t1, t2, modulus, t1);
2565
   }
2566
2567
   /* Y = 2Y */
2568
   if (err == MP_OKAY)
2569
       err = mp_addmod_ct(y, y, modulus, y);
2570
   /* Y = Y * Y */
2571
   if (err == MP_OKAY)
2572
       err = mp_sqr(y, y);
2573
   if (err == MP_OKAY)
2574
       err = mp_montgomery_reduce(y, modulus, mp);
2575
2576
   /* T2 = Y * Y */
2577
   if (err == MP_OKAY)
2578
       err = mp_sqr(y, t2);
2579
   if (err == MP_OKAY)
2580
       err = mp_montgomery_reduce(t2, modulus, mp);
2581
2582
   /* T2 = T2/2 */
2583
   if (err == MP_OKAY)
2584
       err = mp_div_2_mod_ct(t2, modulus, t2);
2585
2586
   /* Y = Y * X */
2587
   if (err == MP_OKAY)
2588
       err = mp_mul(y, x, y);
2589
   if (err == MP_OKAY)
2590
       err = mp_montgomery_reduce(y, modulus, mp);
2591
2592
   /* X = T1 * T1 */
2593
   if (err == MP_OKAY)
2594
       err = mp_sqr(t1, x);
2595
   if (err == MP_OKAY)
2596
       err = mp_montgomery_reduce(x, modulus, mp);
2597
2598
   /* X = X - Y */
2599
   if (err == MP_OKAY)
2600
       err = mp_submod_ct(x, y, modulus, x);
2601
   /* X = X - Y */
2602
   if (err == MP_OKAY)
2603
       err = mp_submod_ct(x, y, modulus, x);
2604
2605
   /* Y = Y - X */
2606
   if (err == MP_OKAY)
2607
       err = mp_submod_ct(y, x, modulus, y);
2608
   /* Y = Y * T1 */
2609
   if (err == MP_OKAY)
2610
       err = mp_mul(y, t1, y);
2611
   if (err == MP_OKAY)
2612
       err = mp_montgomery_reduce(y, modulus, mp);
2613
2614
   /* Y = Y - T2 */
2615
   if (err == MP_OKAY)
2616
       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
   mp_clear(t1);
2629
   mp_clear(t2);
2630
2631
#ifdef WOLFSSL_SMALL_STACK
2632
#ifdef WOLFSSL_SMALL_STACK_CACHE
2633
   if (R->key == NULL)
2634
#endif
2635
#endif
2636
   {
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
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2643
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2644
    }
2645
2646
   return err;
2647
#else
2648
944
    int modBits = mp_count_bits(modulus);
2649
2650
944
    (void)a;
2651
944
    (void)mp;
2652
2653
944
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2654
944
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2655
193
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2656
193
    }
2657
751
#endif
2658
751
#ifndef WOLFSSL_SP_NO_256
2659
751
    if (modBits == 256) {
2660
318
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2661
318
    }
2662
433
#endif
2663
433
#ifdef WOLFSSL_SP_384
2664
433
    if (modBits == 384) {
2665
229
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2666
229
    }
2667
204
#endif
2668
204
#ifdef WOLFSSL_SP_521
2669
204
    if (modBits == 521) {
2670
204
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2671
204
    }
2672
0
#endif
2673
0
    return ECC_BAD_ARG_E;
2674
204
#endif
2675
204
}
2676
2677
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2678
                             mp_int* modulus, mp_digit mp)
2679
4.54k
{
2680
4.54k
    if (P == NULL || R == NULL || modulus == NULL)
2681
0
        return ECC_BAD_ARG_E;
2682
2683
4.54k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2684
4.51k
        mp_cmp(P->y, modulus) != MP_LT ||
2685
4.47k
        mp_cmp(P->z, modulus) != MP_LT) {
2686
67
        return ECC_OUT_OF_RANGE_E;
2687
67
    }
2688
2689
4.47k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2690
4.54k
}
2691
2692
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2693
    !defined(WOLFSSL_CRYPTOCELL)
2694
2695
2696
/**
2697
  Map a projective Jacobian point back to affine space
2698
  P        [in/out] The point to map
2699
  modulus  The modulus of the field the ECC curve is in
2700
  mp       The "b" value from montgomery_setup()
2701
  ct       Operation should be constant time.
2702
  return   MP_OKAY on success
2703
*/
2704
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2705
2.49k
{
2706
2.49k
   int err = MP_OKAY;
2707
#if !defined(WOLFSSL_SP_MATH)
2708
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2709
   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
   mp_int *x, *y, *z;
2716
2717
   (void)ct;
2718
2719
   if (P == NULL || modulus == NULL)
2720
       return ECC_BAD_ARG_E;
2721
2722
   /* special case for point at infinity */
2723
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2724
       err = mp_set(P->x, 0);
2725
       if (err == MP_OKAY)
2726
           err = mp_set(P->y, 0);
2727
       if (err == MP_OKAY)
2728
           err = mp_set(P->z, 1);
2729
       return err;
2730
   }
2731
2732
#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
#endif
2746
   {
2747
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2748
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2749
   #ifdef MP_INT_SIZE_CHECK_NULL
2750
      if (t1 == NULL || t2 == NULL) {
2751
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2752
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2753
         return MEMORY_E;
2754
      }
2755
   #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
   }
2772
2773
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2774
   if (err == MP_OKAY) {
2775
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2776
   }
2777
   if (err != MP_OKAY) {
2778
#ifdef WOLFSSL_SMALL_STACK
2779
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2780
      if (P->key == NULL)
2781
   #endif
2782
#endif
2783
      {
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
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2790
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2791
      }
2792
      return MEMORY_E;
2793
   }
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
   x = P->x;
2825
   y = P->y;
2826
   z = P->z;
2827
#endif
2828
2829
   /* get 1/z */
2830
   if (err == MP_OKAY) {
2831
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2832
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2833
       if (ct) {
2834
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2835
           if (err == MP_OKAY)
2836
               err = mp_montgomery_reduce(t1, modulus, mp);
2837
       }
2838
       else
2839
#endif
2840
       {
2841
           /* first map z back to normal */
2842
           err = mp_montgomery_reduce(z, modulus, mp);
2843
           if (err == MP_OKAY)
2844
               err = mp_invmod(z, modulus, t1);
2845
       }
2846
   }
2847
2848
   /* get 1/z^2 and 1/z^3 */
2849
   if (err == MP_OKAY)
2850
       err = mp_sqr(t1, t2);
2851
   if (err == MP_OKAY)
2852
       err = mp_mod(t2, modulus, t2);
2853
   if (err == MP_OKAY)
2854
       err = mp_mul(t1, t2, t1);
2855
   if (err == MP_OKAY)
2856
       err = mp_mod(t1, modulus, t1);
2857
2858
   /* multiply against x/y */
2859
   if (err == MP_OKAY)
2860
       err = mp_mul(x, t2, x);
2861
   if (err == MP_OKAY)
2862
       err = mp_montgomery_reduce(x, modulus, mp);
2863
   if (err == MP_OKAY)
2864
       err = mp_mul(y, t1, y);
2865
   if (err == MP_OKAY)
2866
       err = mp_montgomery_reduce(y, modulus, mp);
2867
2868
   if (err == MP_OKAY)
2869
       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
   mp_clear(t1);
2885
   mp_clear(t2);
2886
2887
#ifdef WOLFSSL_SMALL_STACK
2888
#ifdef WOLFSSL_SMALL_STACK_CACHE
2889
   if (P->key == NULL)
2890
#endif
2891
#endif
2892
   {
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
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2899
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2900
   }
2901
2902
   return err;
2903
   /* end !defined(WOLFSSL_SP_MATH) */
2904
2905
#else
2906
   /* begin defined(WOLFSSL_SP_MATH) */
2907
2.49k
   if (P == NULL || modulus == NULL)
2908
0
       return ECC_BAD_ARG_E;
2909
2910
2.49k
   (void)mp;
2911
2.49k
   (void)ct;
2912
2913
2.49k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2914
2.49k
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
2915
539
       err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
2916
539
   }
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
2.49k
   WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
2934
2.49k
   return err;
2935
2.49k
#endif /* WOLFSSL_SP_MATH */
2936
2.49k
}
2937
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2938
2939
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2940
21.1k
{
2941
21.1k
    return ecc_map_ex(P, modulus, mp, 0);
2942
21.1k
}
2943
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2944
2945
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2946
    !defined(WOLFSSL_CRYPTOCELL)
2947
#if !defined(WOLFSSL_SP_MATH)
2948
2949
#ifndef ECC_TIMING_RESISTANT
2950
2951
/* size of sliding window, don't change this! */
2952
#define WINSIZE  4
2953
#define M_POINTS 8
2954
2955
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2956
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2957
{
2958
   int      err = MP_OKAY;
2959
   int      i;
2960
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2961
   int      bitcnt = 0, mode = 0, digidx = 0;
2962
   mp_digit buf;
2963
   int      infinity;
2964
2965
   (void)rng;
2966
2967
   /* calc the M tab, which holds kG for k==8..15 */
2968
   /* M[0] == 8G */
2969
   if (err == MP_OKAY)
2970
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2971
   if (err == MP_OKAY)
2972
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2973
   if (err == MP_OKAY)
2974
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2975
2976
   /* now find (8+k)G for k=1..7 */
2977
   if (err == MP_OKAY)
2978
       for (j = 9; j < 16; j++) {
2979
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2980
                                                        modulus, mp, &infinity);
2981
           if (err != MP_OKAY) break;
2982
       }
2983
2984
   /* setup sliding window */
2985
   if (err == MP_OKAY) {
2986
       mode   = 0;
2987
       bitcnt = 1;
2988
       buf    = 0;
2989
       digidx = mp_get_digit_count(k) - 1;
2990
       bitcpy = bitbuf = 0;
2991
       first  = 1;
2992
2993
       /* perform ops */
2994
       for (;;) {
2995
           /* grab next digit as required */
2996
           if (--bitcnt == 0) {
2997
               if (digidx == -1) {
2998
                   break;
2999
               }
3000
               buf    = mp_get_digit(k, digidx);
3001
               bitcnt = (int) DIGIT_BIT;
3002
               --digidx;
3003
           }
3004
3005
           /* grab the next msb from the ltiplicand */
3006
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3007
           buf <<= 1;
3008
3009
           /* skip leading zero bits */
3010
           if (mode == 0 && i == 0)
3011
               continue;
3012
3013
           /* if the bit is zero and mode == 1 then we double */
3014
           if (mode == 1 && i == 0) {
3015
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3016
               if (err != MP_OKAY) break;
3017
               continue;
3018
           }
3019
3020
           /* else we add it to the window */
3021
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3022
           mode = 2;
3023
3024
           if (bitcpy == WINSIZE) {
3025
               /* if this is the first window we do a simple copy */
3026
               if (first == 1) {
3027
                   /* R = kG [k = first window] */
3028
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3029
                   if (err != MP_OKAY) break;
3030
3031
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3032
                   if (err != MP_OKAY) break;
3033
3034
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3035
                   first = 0;
3036
               } else {
3037
                   /* normal window */
3038
                   /* ok window is filled so double as required and add  */
3039
                   /* double first */
3040
                   for (j = 0; j < WINSIZE; j++) {
3041
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3042
                                                                            mp);
3043
                       if (err != MP_OKAY) break;
3044
                   }
3045
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3046
3047
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3048
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3049
                                                     a, modulus, mp, &infinity);
3050
               }
3051
               if (err != MP_OKAY) break;
3052
               /* empty window and reset */
3053
               bitcpy = bitbuf = 0;
3054
               mode = 1;
3055
           }
3056
       }
3057
   }
3058
3059
   /* if bits remain then double/add */
3060
   if (err == MP_OKAY) {
3061
       if (mode == 2 && bitcpy > 0) {
3062
           /* double then add */
3063
           for (j = 0; j < bitcpy; j++) {
3064
               /* only double if we have had at least one add first */
3065
               if (first == 0) {
3066
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3067
                   if (err != MP_OKAY) break;
3068
               }
3069
3070
               bitbuf <<= 1;
3071
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3072
                   if (first == 1) {
3073
                       /* first add, so copy */
3074
                       err = mp_copy(tG->x, R->x);
3075
                       if (err != MP_OKAY) break;
3076
3077
                       err = mp_copy(tG->y, R->y);
3078
                       if (err != MP_OKAY) break;
3079
3080
                       err = mp_copy(tG->z, R->z);
3081
                       if (err != MP_OKAY) break;
3082
                       first = 0;
3083
                   } else {
3084
                       /* then add */
3085
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3086
                                                                 mp, &infinity);
3087
                       if (err != MP_OKAY) break;
3088
                   }
3089
               }
3090
           }
3091
       }
3092
   }
3093
3094
   #undef WINSIZE
3095
3096
   return err;
3097
}
3098
3099
#else
3100
3101
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3102
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3103
{
3104
    int err = MP_OKAY;
3105
3106
    err = mp_montgomery_calc_normalization(mu, modulus);
3107
    /* Generate random value to multiply into p->z. */
3108
    if (err == MP_OKAY)
3109
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3110
    /* Convert to montogmery form. */
3111
    if (err == MP_OKAY)
3112
        err = mp_mulmod(ty, mu, modulus, ty);
3113
    /* Multiply random value into p->z. */
3114
    if (err == MP_OKAY)
3115
        err = mp_mul(p->z, ty, p->z);
3116
    if (err == MP_OKAY)
3117
        err = mp_montgomery_reduce(p->z, modulus, mp);
3118
    /* Square random value for X (X' = X / Z^2). */
3119
    if (err == MP_OKAY)
3120
        err = mp_sqr(ty, tx);
3121
    if (err == MP_OKAY)
3122
        err = mp_montgomery_reduce(tx, modulus, mp);
3123
    /* Multiply square of random by random value for Y. */
3124
    if (err == MP_OKAY)
3125
        err = mp_mul(ty, tx, ty);
3126
    if (err == MP_OKAY)
3127
        err = mp_montgomery_reduce(ty, modulus, mp);
3128
    /* Multiply square into X. */
3129
    if (err == MP_OKAY)
3130
        err = mp_mul(p->x, tx, p->x);
3131
    if (err == MP_OKAY)
3132
        err = mp_montgomery_reduce(p->x, modulus, mp);
3133
    /* Multiply cube into Y (Y' = Y / Z^3). */
3134
    if (err == MP_OKAY)
3135
        err = mp_mul(p->y, ty, p->y);
3136
    if (err == MP_OKAY)
3137
        err = mp_montgomery_reduce(p->y, modulus, mp);
3138
3139
    return err;
3140
}
3141
3142
#ifndef WC_PROTECT_ENCRYPTED_MEM
3143
#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
{
3164
    int      err = MP_OKAY;
3165
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3166
    int      i;
3167
    int      j = 1;
3168
    int      cnt = DIGIT_BIT;
3169
    int      t = 0;
3170
    mp_digit b;
3171
    mp_digit v = 0;
3172
    mp_int*  kt = R[2]->x;
3173
#ifndef WC_NO_CACHE_RESISTANT
3174
    /* First bit always 1 (fix at end) and swap equals first bit */
3175
    int      swap = 1;
3176
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3177
#endif
3178
    int      infinity;
3179
3180
#ifndef WC_NO_CACHE_RESISTANT
3181
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3182
    if (err == MP_OKAY)
3183
        err = mp_init(tmp);
3184
#endif
3185
3186
    /* Step 1: R[0] = P; R[1] = P */
3187
    /* R[0] = P */
3188
    if (err == MP_OKAY)
3189
        err = mp_copy(P->x, R[0]->x);
3190
    if (err == MP_OKAY)
3191
        err = mp_copy(P->y, R[0]->y);
3192
    if (err == MP_OKAY)
3193
        err = mp_copy(P->z, R[0]->z);
3194
3195
    /* R[1] = P */
3196
    if (err == MP_OKAY)
3197
        err = mp_copy(P->x, R[1]->x);
3198
    if (err == MP_OKAY)
3199
        err = mp_copy(P->y, R[1]->y);
3200
    if (err == MP_OKAY)
3201
        err = mp_copy(P->z, R[1]->z);
3202
3203
    /* Randomize z ordinates to obfuscate timing. */
3204
    if ((err == MP_OKAY) && (rng != NULL))
3205
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3206
    if ((err == MP_OKAY) && (rng != NULL))
3207
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3208
3209
    if (err == MP_OKAY) {
3210
        /* Order could be one greater than the size of the modulus. */
3211
        t = mp_count_bits(modulus) + 1;
3212
        v = k->dp[0] >> 1;
3213
        if (cnt > t) {
3214
            cnt = t;
3215
        }
3216
        err = mp_copy(k, kt);
3217
    }
3218
    if (err == MP_OKAY) {
3219
        err = mp_grow(kt, (int)modulus->used + 1);
3220
    }
3221
    /* Step 2: for j = 1 to t-1 do */
3222
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3223
        if (--cnt == 0) {
3224
            v = kt->dp[j++];
3225
            cnt = DIGIT_BIT;
3226
        }
3227
3228
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3229
        b = v & 1;
3230
        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
        swap ^= (int)b;
3240
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3241
            tmp);
3242
        if (err == MP_OKAY) {
3243
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3244
                tmp);
3245
        }
3246
        if (err == MP_OKAY) {
3247
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3248
                tmp);
3249
        }
3250
        swap = (int)b;
3251
3252
        if (err == MP_OKAY)
3253
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3254
        if (err == MP_OKAY) {
3255
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3256
                                                                 mp, &infinity);
3257
        }
3258
#endif /* WC_NO_CACHE_RESISTANT */
3259
    }
3260
    /* Step 4: end for */
3261
#ifndef WC_NO_CACHE_RESISTANT
3262
    /* Swap back if last bit is 0. */
3263
    swap ^= 1;
3264
    if (err == MP_OKAY) {
3265
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3266
            tmp);
3267
    }
3268
    if (err == MP_OKAY) {
3269
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3270
            tmp);
3271
    }
3272
    if (err == MP_OKAY) {
3273
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3274
            tmp);
3275
    }
3276
#endif
3277
3278
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3279
    /* R[2] = -P */
3280
    if (err == MP_OKAY)
3281
        err = mp_copy(P->x, R[2]->x);
3282
    if (err == MP_OKAY)
3283
        err = mp_sub(modulus, P->y, R[2]->y);
3284
    if (err == MP_OKAY)
3285
        err = mp_copy(P->z, R[2]->z);
3286
    /* Subtract point by adding negative. */
3287
    if (err == MP_OKAY) {
3288
        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
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3295
            tmp);
3296
        if (err == MP_OKAY) {
3297
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3298
                (int)b, tmp);
3299
        }
3300
        if (err == MP_OKAY) {
3301
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3302
                (int)b, tmp);
3303
        }
3304
        if (err == MP_OKAY)
3305
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3306
                                                                 mp, &infinity);
3307
        /* Swap back if necessary. */
3308
        if (err == MP_OKAY) {
3309
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3310
                (int)b, tmp);
3311
        }
3312
        if (err == MP_OKAY) {
3313
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3314
                (int)b, tmp);
3315
        }
3316
        if (err == MP_OKAY) {
3317
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3318
                (int)b, tmp);
3319
        }
3320
#endif
3321
    }
3322
3323
    /* Step 6: return R[0] */
3324
    if (err == MP_OKAY)
3325
        err = mp_copy(R[0]->x, Q->x);
3326
    if (err == MP_OKAY)
3327
        err = mp_copy(R[0]->y, Q->y);
3328
    if (err == MP_OKAY)
3329
        err = mp_copy(R[0]->z, Q->z);
3330
3331
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3332
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3333
#endif
3334
3335
    return err;
3336
}
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
{
3537
   int err = MP_OKAY;
3538
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3539
3540
   (void)heap;
3541
3542
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3543
#ifdef MP_INT_SIZE_CHECK_NULL
3544
   if (mu == NULL)
3545
       err = MEMORY_E;
3546
#endif
3547
   if (err == MP_OKAY)
3548
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3549
   if (err == MP_OKAY) {
3550
       err = mp_montgomery_calc_normalization(mu, modulus);
3551
3552
       if (err == MP_OKAY) {
3553
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3554
               err = mp_copy(p->x, r->x);
3555
               if (err == MP_OKAY)
3556
                   err = mp_copy(p->y, r->y);
3557
               if (err == MP_OKAY)
3558
                   err = mp_copy(p->z, r->z);
3559
           }
3560
           else {
3561
               err = mp_mulmod(p->x, mu, modulus, r->x);
3562
               if (err == MP_OKAY)
3563
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3564
               if (err == MP_OKAY)
3565
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3566
           }
3567
       }
3568
3569
       mp_clear(mu);
3570
   }
3571
3572
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3573
   return err;
3574
}
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
{
3688
   ecc_point     *tG, *M[M_POINTS];
3689
#ifdef WOLFSSL_NO_MALLOC
3690
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3691
#endif
3692
   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
   mp_digit      mp;
3697
3698
   /* init variables */
3699
   tG = NULL;
3700
   XMEMSET(M, 0, sizeof(M));
3701
3702
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3703
       err = ECC_BAD_ARG_E;
3704
       goto exit;
3705
   }
3706
3707
   /* k can't have more bits than modulus count plus 1 */
3708
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3709
       err = ECC_OUT_OF_RANGE_E;
3710
       goto exit;
3711
   }
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
  for (i = 0; i < M_POINTS; i++) {
3726
  #ifdef WOLFSSL_NO_MALLOC
3727
      M[i] = &lcl_M[i];
3728
  #endif
3729
      err = wc_ecc_new_point_ex(&M[i], heap);
3730
      if (err != MP_OKAY) {
3731
         goto exit;
3732
      }
3733
#ifdef WOLFSSL_SMALL_STACK_CACHE
3734
      M[i]->key = key;
3735
#endif
3736
  }
3737
3738
   /* make a copy of G in case R==G */
3739
#ifdef WOLFSSL_NO_MALLOC
3740
   tG = &lcl_tG;
3741
#endif
3742
   err = wc_ecc_new_point_ex(&tG, heap);
3743
   if (err != MP_OKAY) {
3744
       goto exit;
3745
   }
3746
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3747
       goto exit;
3748
   }
3749
3750
   /* init montgomery reduction */
3751
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3752
       goto exit;
3753
   }
3754
3755
#ifdef FP_ECC
3756
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3757
#else
3758
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3759
#endif
3760
   /* map R back from projective space */
3761
   if (err == MP_OKAY && map)
3762
       err = ecc_map(R, modulus, mp);
3763
3764
exit:
3765
3766
   /* done */
3767
   wc_ecc_del_point_ex(tG, heap);
3768
   for (i = 0; i < M_POINTS; i++) {
3769
       wc_ecc_del_point_ex(M[i], heap);
3770
   }
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
   return err;
3783
}
3784
#else
3785
641
{
3786
641
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3787
0
       return ECC_BAD_ARG_E;
3788
0
   }
3789
3790
641
   (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
641
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3796
26
       return ECC_OUT_OF_RANGE_E;
3797
26
   }
3798
615
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3799
603
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3800
583
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3801
32
       return IS_POINT_E;
3802
32
   }
3803
3804
583
#ifdef WOLFSSL_HAVE_SP_ECC
3805
583
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3806
583
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3807
49
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3808
49
   }
3809
534
#endif
3810
534
#ifndef WOLFSSL_SP_NO_256
3811
534
   if (mp_count_bits(modulus) == 256) {
3812
161
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3813
161
   }
3814
373
#endif
3815
373
#ifdef WOLFSSL_SP_384
3816
373
   if (mp_count_bits(modulus) == 384) {
3817
101
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3818
101
   }
3819
272
#endif
3820
272
#ifdef WOLFSSL_SP_521
3821
272
   if (mp_count_bits(modulus) == 521) {
3822
272
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3823
272
   }
3824
0
#endif
3825
#else
3826
   (void)map;
3827
   (void)map;
3828
   (void)heap;
3829
#endif
3830
0
   return ECC_BAD_ARG_E;
3831
272
}
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
{
3841
    int err;
3842
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3843
3844
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3845
#ifdef MP_INT_SIZE_CHECK_NULL
3846
    if (t == NULL) {
3847
        err = MEMORY_E;
3848
    }
3849
    else
3850
#endif
3851
    {
3852
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3853
    }
3854
    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
        err = mp_sub_d(order, 1, t);
3860
        if (err == MP_OKAY) {
3861
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3862
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3863
            if (err == MP_OKAY) {
3864
                err = mp_sub(modulus, tG->y, t);
3865
            }
3866
            if (err == MP_OKAY) {
3867
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3868
            }
3869
            if (err == MP_OKAY) {
3870
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3871
            }
3872
        }
3873
3874
        mp_free(t);
3875
    }
3876
3877
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3878
    return err;
3879
}
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
{
3899
   ecc_point     *tG, *M[M_POINTS];
3900
#ifdef WOLFSSL_NO_MALLOC
3901
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3902
#endif
3903
   int           i, err;
3904
#ifdef WOLFSSL_SMALL_STACK_CACHE
3905
   ecc_key       *key = NULL;
3906
#endif
3907
   mp_digit      mp;
3908
3909
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3910
      return ECC_BAD_ARG_E;
3911
   }
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
   if (mp_count_bits(k) > mp_count_bits(order)) {
3923
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3924
      return ECC_OUT_OF_RANGE_E;
3925
   }
3926
3927
   /* init variables */
3928
   tG = NULL;
3929
   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
   for (i = 0; i < M_POINTS; i++) {
3943
   #ifdef WOLFSSL_NO_MALLOC
3944
      M[i] = &lcl_M[i];
3945
   #endif
3946
      err = wc_ecc_new_point_ex(&M[i], heap);
3947
      if (err != MP_OKAY) {
3948
         goto exit;
3949
      }
3950
#ifdef WOLFSSL_SMALL_STACK_CACHE
3951
      M[i]->key = key;
3952
#endif
3953
  }
3954
3955
   /* make a copy of G in case R==G */
3956
#ifdef WOLFSSL_NO_MALLOC
3957
   tG = &lcl_tG;
3958
#endif
3959
   err = wc_ecc_new_point_ex(&tG, heap);
3960
   if (err != MP_OKAY) {
3961
       goto exit;
3962
   }
3963
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3964
       goto exit;
3965
   }
3966
3967
   /* init montgomery reduction */
3968
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3969
      goto exit;
3970
   }
3971
3972
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3973
#ifdef ECC_TIMING_RESISTANT
3974
   if (err == MP_OKAY) {
3975
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3976
   }
3977
#else
3978
   (void)order;
3979
#endif
3980
   /* map R back from projective space */
3981
   if (err == MP_OKAY && map)
3982
      err = ecc_map(R, modulus, mp);
3983
3984
exit:
3985
3986
   /* done */
3987
   wc_ecc_del_point_ex(tG, heap);
3988
   for (i = 0; i < M_POINTS; i++) {
3989
      wc_ecc_del_point_ex(M[i], heap);
3990
   }
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
   return err;
3998
}
3999
#else
4000
{
4001
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4002
       return ECC_BAD_ARG_E;
4003
   }
4004
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4005
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4006
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4007
       return IS_POINT_E;
4008
   }
4009
4010
   (void)a;
4011
   (void)order;
4012
   (void)rng;
4013
4014
#ifdef WOLFSSL_HAVE_SP_ECC
4015
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4016
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4017
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4018
   }
4019
#endif
4020
#ifndef WOLFSSL_SP_NO_256
4021
   if (mp_count_bits(modulus) == 256) {
4022
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4023
   }
4024
#endif
4025
#ifdef WOLFSSL_SP_384
4026
   if (mp_count_bits(modulus) == 384) {
4027
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4028
   }
4029
#endif
4030
#ifdef WOLFSSL_SP_521
4031
   if (mp_count_bits(modulus) == 521) {
4032
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4033
   }
4034
#endif
4035
#else
4036
   (void)map;
4037
   (void)heap;
4038
#endif
4039
   return ECC_BAD_ARG_E;
4040
}
4041
#endif /* !WOLFSSL_SP_MATH */
4042
#endif /* !FP_ECC */
4043
4044
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4045
4046
/** ECC Fixed Point mulmod global
4047
    k        The multiplicand
4048
    G        Base point to multiply
4049
    R        [out] Destination of product
4050
    a        ECC curve parameter a
4051
    modulus  The modulus for the curve
4052
    map      [boolean] If non-zero maps the point back to affine coordinates,
4053
             otherwise it's left in jacobian-montgomery form
4054
    return MP_OKAY if successful
4055
*/
4056
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4057
                  mp_int* modulus, int map)
4058
1.65k
{
4059
1.65k
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4060
14
        mp_zero(R->x);
4061
14
        mp_zero(R->y);
4062
14
        mp_set(R->z, 1);
4063
14
        return MP_OKAY;
4064
14
    }
4065
1.63k
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4066
1.65k
}
4067
4068
#endif
4069
4070
/**
4071
 * Allocate a new ECC point (if one not provided)
4072
 * use a heap hint when creating new ecc_point
4073
 * @return 0 on success
4074
 * @return BAD_FUNC_ARG for invalid arguments
4075
 * @return MEMORY_E on failure to allocate memory
4076
*/
4077
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4078
301k
{
4079
301k
   int err = MP_OKAY;
4080
301k
   ecc_point* p;
4081
4082
301k
   if (point == NULL) {
4083
0
       return BAD_FUNC_ARG;
4084
0
   }
4085
4086
301k
   p = *point;
4087
301k
   if (p == NULL) {
4088
301k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4089
301k
   }
4090
301k
   if (p == NULL) {
4091
1.65k
      return MEMORY_E;
4092
1.65k
   }
4093
299k
   XMEMSET(p, 0, sizeof(ecc_point));
4094
4095
299k
   if (*point == NULL)
4096
299k
       p->isAllocated = 1;
4097
4098
299k
#ifndef ALT_ECC_SIZE
4099
299k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4100
299k
   if (err != MP_OKAY) {
4101
0
      WOLFSSL_MSG("mp_init_multi failed.");
4102
0
      if (p->isAllocated)
4103
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4104
0
      p = NULL;
4105
0
   }
4106
#else
4107
   p->x = (mp_int*)&p->xyz[0];
4108
   p->y = (mp_int*)&p->xyz[1];
4109
   p->z = (mp_int*)&p->xyz[2];
4110
   alt_fp_init(p->x);
4111
   alt_fp_init(p->y);
4112
   alt_fp_init(p->z);
4113
#endif
4114
4115
299k
   *point = p;
4116
299k
   (void)heap;
4117
299k
   return err;
4118
301k
} /* wc_ecc_new_point_ex */
4119
4120
ecc_point* wc_ecc_new_point_h(void* heap)
4121
44.1k
{
4122
44.1k
    ecc_point* p = NULL;
4123
44.1k
    (void)wc_ecc_new_point_ex(&p, heap);
4124
44.1k
    return p;
4125
44.1k
}
4126
4127
ecc_point* wc_ecc_new_point(void)
4128
13.9k
{
4129
13.9k
   ecc_point* p = NULL;
4130
13.9k
   (void)wc_ecc_new_point_ex(&p, NULL);
4131
13.9k
   return p;
4132
13.9k
}
4133
4134
/** Free an ECC point from memory
4135
  p   The point to free
4136
*/
4137
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4138
358k
{
4139
358k
   if (p != NULL) {
4140
299k
      mp_clear(p->x);
4141
299k
      mp_clear(p->y);
4142
299k
      mp_clear(p->z);
4143
299k
      if (p->isAllocated)
4144
299k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4145
299k
   }
4146
358k
   (void)heap;
4147
358k
}
4148
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4149
414
{
4150
414
   wc_ecc_del_point_ex(p, heap);
4151
414
}
4152
void wc_ecc_del_point(ecc_point* p)
4153
112k
{
4154
112k
    wc_ecc_del_point_ex(p, NULL);
4155
112k
}
4156
4157
void wc_ecc_forcezero_point(ecc_point* p)
4158
0
{
4159
0
    if (p != NULL) {
4160
0
        mp_forcezero(p->x);
4161
0
        mp_forcezero(p->y);
4162
0
        mp_forcezero(p->z);
4163
0
    }
4164
0
}
4165
4166
4167
/** Copy the value of a point to an other one
4168
  p    The point to copy
4169
  r    The created point
4170
*/
4171
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4172
912k
{
4173
912k
    int ret;
4174
4175
    /* prevents null arguments */
4176
912k
    if (p == NULL || r == NULL)
4177
0
        return ECC_BAD_ARG_E;
4178
4179
912k
    ret = mp_copy(p->x, r->x);
4180
912k
    if (ret != MP_OKAY)
4181
2
        return ret;
4182
912k
    ret = mp_copy(p->y, r->y);
4183
912k
    if (ret != MP_OKAY)
4184
2
        return ret;
4185
912k
    ret = mp_copy(p->z, r->z);
4186
912k
    if (ret != MP_OKAY)
4187
3
        return ret;
4188
4189
912k
    return MP_OKAY;
4190
912k
}
4191
4192
/** Compare the value of a point with an other one
4193
 a    The point to compare
4194
 b    The other point to compare
4195
4196
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4197
 */
4198
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4199
2.96k
{
4200
2.96k
    int ret;
4201
4202
    /* prevents null arguments */
4203
2.96k
    if (a == NULL || b == NULL)
4204
0
        return BAD_FUNC_ARG;
4205
4206
2.96k
    ret = mp_cmp(a->x, b->x);
4207
2.96k
    if (ret != MP_EQ)
4208
2.21k
        return ret;
4209
746
    ret = mp_cmp(a->y, b->y);
4210
746
    if (ret != MP_EQ)
4211
393
        return ret;
4212
353
    ret = mp_cmp(a->z, b->z);
4213
353
    if (ret != MP_EQ)
4214
23
        return ret;
4215
4216
330
    return MP_EQ;
4217
353
}
4218
4219
4220
/** Returns whether an ECC idx is valid or not
4221
  n      The idx number to check
4222
  return 1 if valid, 0 if not
4223
*/
4224
int wc_ecc_is_valid_idx(int n)
4225
49.7k
{
4226
49.7k
   int x;
4227
4228
49.7k
   if (n >= (int)ECC_SET_COUNT)
4229
0
       return 0;
4230
4231
1.17M
   for (x = 0; ecc_sets[x].size != 0; x++)
4232
1.12M
       ;
4233
   /* -1 is a valid index --- indicating that the domain params
4234
      were supplied by the user */
4235
49.7k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4236
49.7k
      return 1;
4237
49.7k
   }
4238
4239
0
   return 0;
4240
49.7k
}
4241
4242
int wc_ecc_get_curve_idx(int curve_id)
4243
40.3k
{
4244
40.3k
    int curve_idx;
4245
517k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4246
517k
        if (curve_id == ecc_sets[curve_idx].id)
4247
40.2k
            break;
4248
517k
    }
4249
40.3k
    if (ecc_sets[curve_idx].size == 0) {
4250
110
        return ECC_CURVE_INVALID;
4251
110
    }
4252
40.2k
    return curve_idx;
4253
40.3k
}
4254
4255
int wc_ecc_get_curve_id(int curve_idx)
4256
1.87k
{
4257
1.87k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4258
1.87k
        return ecc_sets[curve_idx].id;
4259
1.87k
    }
4260
0
    return ECC_CURVE_INVALID;
4261
1.87k
}
4262
4263
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4264
 *
4265
 * id      curve id, from ecc_curve_id enum in ecc.h
4266
 * return  curve size, from ecc_sets[] on success, negative on error
4267
 */
4268
int wc_ecc_get_curve_size_from_id(int curve_id)
4269
1.13k
{
4270
1.13k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4271
1.13k
    if (curve_idx == ECC_CURVE_INVALID)
4272
0
        return ECC_BAD_ARG_E;
4273
1.13k
    return ecc_sets[curve_idx].size;
4274
1.13k
}
4275
4276
/* Returns the curve index that corresponds to a given curve name in
4277
 * ecc_sets[] of ecc.c
4278
 *
4279
 * name    curve name, from ecc_sets[].name in ecc.c
4280
 * return  curve index in ecc_sets[] on success, negative on error
4281
 */
4282
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4283
0
{
4284
0
    int curve_idx;
4285
4286
0
    if (curveName == NULL)
4287
0
        return BAD_FUNC_ARG;
4288
4289
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4290
0
        if (
4291
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4292
0
            ecc_sets[curve_idx].name &&
4293
0
        #endif
4294
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4295
0
            break;
4296
0
        }
4297
0
    }
4298
0
    if (ecc_sets[curve_idx].size == 0) {
4299
0
        WOLFSSL_MSG("ecc_set curve name not found");
4300
0
        return ECC_CURVE_INVALID;
4301
0
    }
4302
0
    return curve_idx;
4303
0
}
4304
4305
/* Returns the curve size that corresponds to a given curve name,
4306
 * as listed in ecc_sets[] of ecc.c.
4307
 *
4308
 * name    curve name, from ecc_sets[].name in ecc.c
4309
 * return  curve size, from ecc_sets[] on success, negative on error
4310
 */
4311
int wc_ecc_get_curve_size_from_name(const char* curveName)
4312
0
{
4313
0
    int curve_idx;
4314
4315
0
    if (curveName == NULL)
4316
0
        return BAD_FUNC_ARG;
4317
4318
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4319
0
    if (curve_idx < 0)
4320
0
        return curve_idx;
4321
4322
0
    return ecc_sets[curve_idx].size;
4323
0
}
4324
4325
/* Returns the curve id that corresponds to a given curve name,
4326
 * as listed in ecc_sets[] of ecc.c.
4327
 *
4328
 * name   curve name, from ecc_sets[].name in ecc.c
4329
 * return curve id, from ecc_sets[] on success, negative on error
4330
 */
4331
int wc_ecc_get_curve_id_from_name(const char* curveName)
4332
0
{
4333
0
    int curve_idx;
4334
4335
0
    if (curveName == NULL)
4336
0
        return BAD_FUNC_ARG;
4337
4338
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4339
0
    if (curve_idx < 0)
4340
0
        return curve_idx;
4341
4342
0
    return ecc_sets[curve_idx].id;
4343
0
}
4344
4345
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4346
 * parameter for equality.
4347
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4348
 * Returns MP_EQ on success, negative on error */
4349
static int wc_ecc_cmp_param(const char* curveParam,
4350
                            const byte* param, word32 paramSz, int encType)
4351
0
{
4352
0
    int err = MP_OKAY;
4353
0
#ifdef WOLFSSL_SMALL_STACK
4354
0
    mp_int* a = NULL;
4355
0
    mp_int* b = NULL;
4356
#else
4357
    mp_int  a[1], b[1];
4358
#endif
4359
4360
0
    if (param == NULL || curveParam == NULL)
4361
0
        return BAD_FUNC_ARG;
4362
4363
0
    if (encType == WC_TYPE_HEX_STR) {
4364
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4365
0
            return -1;
4366
0
        return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1;
4367
0
    }
4368
4369
0
#ifdef WOLFSSL_SMALL_STACK
4370
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4371
0
    if (a == NULL)
4372
0
        return MEMORY_E;
4373
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4374
0
    if (b == NULL) {
4375
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4376
0
        return MEMORY_E;
4377
0
    }
4378
0
#endif
4379
4380
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4381
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4382
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4383
0
        return err;
4384
0
    }
4385
4386
0
    if (err == MP_OKAY) {
4387
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4388
0
    }
4389
0
    if (err == MP_OKAY)
4390
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4391
4392
0
    if (err == MP_OKAY) {
4393
0
        if (mp_cmp(a, b) != MP_EQ) {
4394
0
            err = -1;
4395
0
        } else {
4396
0
            err = MP_EQ;
4397
0
        }
4398
0
    }
4399
4400
0
    mp_clear(a);
4401
0
    mp_clear(b);
4402
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4403
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4404
4405
0
    return err;
4406
0
}
4407
4408
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4409
 * curve parameters.
4410
 *
4411
 * fieldSize  the field size in bits
4412
 * prime      prime of the finite field
4413
 * primeSz    size of prime in octets
4414
 * Af         first coefficient a of the curve
4415
 * AfSz       size of Af in octets
4416
 * Bf         second coefficient b of the curve
4417
 * BfSz       size of Bf in octets
4418
 * order      curve order
4419
 * orderSz    size of curve in octets
4420
 * Gx         affine x coordinate of base point
4421
 * GxSz       size of Gx in octets
4422
 * Gy         affine y coordinate of base point
4423
 * GySz       size of Gy in octets
4424
 * cofactor   curve cofactor
4425
 *
4426
 * return curve id, from ecc_sets[] on success, negative on error
4427
 */
4428
int wc_ecc_get_curve_id_from_params(int fieldSize,
4429
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4430
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4431
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4432
0
{
4433
0
    int idx;
4434
0
    int curveSz;
4435
4436
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4437
0
        Gx == NULL || Gy == NULL)
4438
0
        return BAD_FUNC_ARG;
4439
4440
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4441
4442
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4443
0
        if (curveSz == ecc_sets[idx].size) {
4444
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4445
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4446
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4447
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4448
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4449
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4450
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4451
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4452
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4453
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4454
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4455
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4456
0
                (cofactor == ecc_sets[idx].cofactor)) {
4457
0
                    break;
4458
0
            }
4459
0
        }
4460
0
    }
4461
4462
0
    if (ecc_sets[idx].size == 0)
4463
0
        return ECC_CURVE_INVALID;
4464
4465
0
    return ecc_sets[idx].id;
4466
0
}
4467
4468
/* Returns the curve id in ecc_sets[] that corresponds
4469
 * to a given domain parameters pointer.
4470
 *
4471
 * dp   domain parameters pointer
4472
 *
4473
 * return curve id, from ecc_sets[] on success, negative on error
4474
 */
4475
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4476
0
{
4477
0
    int idx;
4478
4479
0
    if (dp == NULL
4480
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4481
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4482
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4483
0
    #endif
4484
0
    ) {
4485
0
        return BAD_FUNC_ARG;
4486
0
    }
4487
4488
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4489
0
        if (dp->size == ecc_sets[idx].size) {
4490
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4491
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4492
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4493
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4494
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4495
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4496
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4497
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4498
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4499
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4500
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4501
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4502
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4503
0
                    break;
4504
0
            }
4505
0
        }
4506
0
    }
4507
4508
0
    if (ecc_sets[idx].size == 0)
4509
0
        return ECC_CURVE_INVALID;
4510
4511
0
    return ecc_sets[idx].id;
4512
0
}
4513
4514
/* Returns the curve id that corresponds to a given OID,
4515
 * as listed in ecc_sets[] of ecc.c.
4516
 *
4517
 * oid   OID, from ecc_sets[].name in ecc.c
4518
 * len   OID len, from ecc_sets[].name in ecc.c
4519
 * return curve id, from ecc_sets[] on success, negative on error
4520
 */
4521
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4522
0
{
4523
0
    int curve_idx;
4524
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4525
    int ret;
4526
    #ifdef HAVE_OID_DECODING
4527
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4528
    #else
4529
    byte  decOid[MAX_OID_SZ];
4530
    #endif
4531
    word32 decOidSz;
4532
#endif
4533
4534
0
    if (oid == NULL)
4535
0
        return BAD_FUNC_ARG;
4536
4537
#ifdef HAVE_OID_DECODING
4538
    decOidSz = (word32)sizeof(decOid);
4539
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4540
    if (ret != 0) {
4541
        return ret;
4542
    }
4543
#endif
4544
4545
0
    if (len == 0) {
4546
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4547
0
        WOLFSSL_MSG("zero oidSz");
4548
0
        return ECC_CURVE_INVALID;
4549
0
    }
4550
4551
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4552
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4553
        decOidSz = (word32)sizeof(decOid);
4554
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4555
            decOid, &decOidSz);
4556
        if (ret != 0) {
4557
            continue;
4558
        }
4559
    #endif
4560
4561
0
        if (
4562
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4563
0
            ecc_sets[curve_idx].oid &&
4564
0
        #endif
4565
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4566
            decOidSz == len &&
4567
                XMEMCMP(decOid, oid, len) == 0
4568
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4569
            /* We double because decOidSz is a count of word16 elements. */
4570
            ecc_sets[curve_idx].oidSz == decOidSz &&
4571
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4572
        #else
4573
0
            ecc_sets[curve_idx].oidSz == len &&
4574
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4575
0
        #endif
4576
0
        ) {
4577
0
            break;
4578
0
        }
4579
0
    }
4580
0
    if (ecc_sets[curve_idx].size == 0) {
4581
0
        WOLFSSL_MSG("ecc_set curve name not found");
4582
0
        return ECC_CURVE_INVALID;
4583
0
    }
4584
4585
0
    return ecc_sets[curve_idx].id;
4586
0
}
4587
4588
/* Get curve parameters using curve index */
4589
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4590
28.4k
{
4591
28.4k
    const ecc_set_type* ecc_set = NULL;
4592
4593
28.4k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4594
28.4k
        ecc_set = &ecc_sets[curve_idx];
4595
28.4k
    }
4596
28.4k
    return ecc_set;
4597
28.4k
}
4598
4599
4600
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4601
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4602
{
4603
   if (key == NULL || mp == NULL)
4604
      return BAD_FUNC_ARG;
4605
   if (*mp == NULL) {
4606
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4607
      if (*mp == NULL) {
4608
         return MEMORY_E;
4609
      }
4610
      XMEMSET(*mp, 0, sizeof(mp_int));
4611
   }
4612
   return 0;
4613
}
4614
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4615
{
4616
   if (key && mp && *mp) {
4617
      mp_clear(*mp);
4618
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4619
      *mp = NULL;
4620
   }
4621
}
4622
4623
static int wc_ecc_alloc_async(ecc_key* key)
4624
{
4625
    int err = wc_ecc_alloc_mpint(key, &key->r);
4626
    if (err == 0)
4627
        err = wc_ecc_alloc_mpint(key, &key->s);
4628
    return err;
4629
}
4630
4631
static void wc_ecc_free_async(ecc_key* key)
4632
{
4633
    wc_ecc_free_mpint(key, &key->r);
4634
    wc_ecc_free_mpint(key, &key->s);
4635
#ifdef HAVE_CAVIUM_V
4636
    wc_ecc_free_mpint(key, &key->e);
4637
    wc_ecc_free_mpint(key, &key->signK);
4638
#endif /* HAVE_CAVIUM_V */
4639
}
4640
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4641
4642
4643
#ifdef HAVE_ECC_DHE
4644
/**
4645
  Create an ECC shared secret between two keys
4646
  private_key      The private ECC key (heap hint based off of private key)
4647
  public_key       The public key
4648
  out              [out] Destination of the shared secret
4649
                         Conforms to EC-DH from ANSI X9.63
4650
  outlen           [in/out] The max size and resulting size of the shared secret
4651
  return           MP_OKAY if successful
4652
*/
4653
WOLFSSL_ABI
4654
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4655
                      word32* outlen)
4656
1.42k
{
4657
1.42k
   int err = 0;
4658
4659
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4660
   !defined(WOLFSSL_ATECC608A)
4661
   CRYS_ECDH_TempData_t tempBuff;
4662
#endif
4663
4664
1.42k
   (void)err;
4665
4666
1.42k
   if (private_key == NULL || public_key == NULL || out == NULL ||
4667
1.42k
                                                            outlen == NULL) {
4668
0
       return BAD_FUNC_ARG;
4669
0
   }
4670
4671
1.42k
#ifdef WOLF_CRYPTO_CB
4672
1.42k
    #ifndef WOLF_CRYPTO_CB_FIND
4673
1.42k
    if (private_key->devId != INVALID_DEVID)
4674
0
    #endif
4675
0
    {
4676
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4677
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4678
0
            return err;
4679
        /* fall-through when unavailable */
4680
0
    }
4681
1.42k
#endif
4682
4683
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4684
    return NO_VALID_DEVID;
4685
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4686
   /* type valid? */
4687
1.42k
   if (private_key->type != ECC_PRIVATEKEY &&
4688
338
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4689
0
      return ECC_BAD_ARG_E;
4690
0
   }
4691
4692
   /* Verify domain params supplied */
4693
1.42k
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4694
1.42k
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4695
0
      return ECC_BAD_ARG_E;
4696
0
   }
4697
4698
   /* Verify curve id matches */
4699
1.42k
   if (private_key->dp->id != public_key->dp->id) {
4700
0
      return ECC_BAD_ARG_E;
4701
0
   }
4702
4703
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4704
   /* For SECP256R1 use hardware */
4705
   if (private_key->dp->id == ECC_SECP256R1) {
4706
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4707
       *outlen = private_key->dp->size;
4708
   }
4709
   else {
4710
      err = NOT_COMPILED_IN;
4711
   }
4712
#elif defined(WOLFSSL_CRYPTOCELL)
4713
4714
    /* generate a secret*/
4715
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4716
                            &private_key->ctx.privKey,
4717
                            out,
4718
                            (uint32_t*)outlen,
4719
                            &tempBuff);
4720
4721
    if (err != SA_SILIB_RET_OK){
4722
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4723
        return err;
4724
    }
4725
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4726
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4727
#elif defined(WOLFSSL_KCAPI_ECC)
4728
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4729
#elif defined(WOLFSSL_SE050)
4730
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4731
#else
4732
1.42k
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4733
1.42k
#endif /* WOLFSSL_ATECC508A */
4734
1.42k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4735
4736
1.42k
   return err;
4737
1.42k
}
4738
4739
4740
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4741
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4742
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4743
4744
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4745
                               byte* out, word32* outlen)
4746
101
{
4747
101
    int err = MP_OKAY;
4748
101
    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
101
#ifdef WOLFSSL_HAVE_SP_ECC
4782
4783
101
#ifndef WOLFSSL_SP_NO_256
4784
101
    if (private_key->idx != ECC_CUSTOM_IDX &&
4785
101
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4786
42
    #ifndef WC_ECC_NONBLOCK
4787
42
        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
42
    }
4807
59
    else
4808
59
#endif /* ! WOLFSSL_SP_NO_256 */
4809
59
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4810
59
    if (private_key->idx != ECC_CUSTOM_IDX &&
4811
59
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4812
13
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4813
13
                                                             private_key->heap);
4814
13
    }
4815
46
    else
4816
46
#endif
4817
46
#ifdef WOLFSSL_SP_384
4818
46
    if (private_key->idx != ECC_CUSTOM_IDX &&
4819
46
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4820
36
    #ifndef WC_ECC_NONBLOCK
4821
36
        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
36
    }
4841
10
    else
4842
10
#endif /* WOLFSSL_SP_384 */
4843
10
#ifdef WOLFSSL_SP_521
4844
10
    if (private_key->idx != ECC_CUSTOM_IDX &&
4845
10
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4846
10
    #ifndef WC_ECC_NONBLOCK
4847
10
        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
10
    }
4867
0
    else
4868
0
#endif /* WOLFSSL_SP_521 */
4869
#else
4870
    (void)point;
4871
    (void)out;
4872
    (void)outlen;
4873
    (void)k;
4874
#endif
4875
0
#if defined(WOLFSSL_SP_MATH)
4876
0
    {
4877
0
        err = WC_KEY_SIZE_E;
4878
0
        goto errout;
4879
0
    }
4880
#else
4881
    {
4882
        ecc_point* result = NULL;
4883
        #ifdef WOLFSSL_NO_MALLOC
4884
        ecc_point  lcl_result;
4885
        #endif
4886
        int x = 0;
4887
        mp_digit mp = 0;
4888
        DECLARE_CURVE_SPECS(3);
4889
4890
        /* load curve info */
4891
        ALLOC_CURVE_SPECS(3, err);
4892
        if (err == MP_OKAY) {
4893
            err = wc_ecc_curve_load(private_key->dp, &curve,
4894
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4895
                 ECC_CURVE_FIELD_ORDER));
4896
        }
4897
4898
        if (err != MP_OKAY) {
4899
            FREE_CURVE_SPECS();
4900
            goto errout;
4901
        }
4902
4903
        /* make new point */
4904
    #ifdef WOLFSSL_NO_MALLOC
4905
        result = &lcl_result;
4906
    #endif
4907
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4908
        if (err != MP_OKAY) {
4909
            wc_ecc_curve_free(curve);
4910
            FREE_CURVE_SPECS();
4911
            goto errout;
4912
        }
4913
4914
#ifdef ECC_TIMING_RESISTANT
4915
        if (private_key->rng == NULL) {
4916
            err = MISSING_RNG_E;
4917
        }
4918
#endif
4919
4920
        if (err == MP_OKAY) {
4921
            /* Map in a separate call as this should be constant time */
4922
#ifdef ECC_TIMING_RESISTANT
4923
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4924
                                              curve->order, private_key->rng, 0,
4925
                                              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
        }
4931
        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
            err = mp_montgomery_setup(curve->prime, &mp);
4939
        }
4940
        if (err == MP_OKAY) {
4941
            /* Use constant time map if compiled in */
4942
            err = ecc_map_ex(result, curve->prime, mp, 1);
4943
        }
4944
        if (err == MP_OKAY) {
4945
            x = mp_unsigned_bin_size(curve->prime);
4946
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4947
                err = BUFFER_E;
4948
            }
4949
        }
4950
4951
        if (err == MP_OKAY) {
4952
            XMEMSET(out, 0, (size_t)x);
4953
            err = mp_to_unsigned_bin(result->x, out +
4954
                                     (x - mp_unsigned_bin_size(result->x)));
4955
        }
4956
        *outlen = (word32)x;
4957
4958
        mp_forcezero(result->x);
4959
        mp_forcezero(result->y);
4960
        wc_ecc_del_point_ex(result, private_key->heap);
4961
4962
        wc_ecc_curve_free(curve);
4963
        FREE_CURVE_SPECS();
4964
    }
4965
#endif
4966
4967
101
  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
101
    return err;
4976
101
}
4977
4978
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4979
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
4980
            ecc_point* point, byte* out, word32 *outlen)
4981
{
4982
    int err = 0;
4983
4984
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
4985
    DECLARE_CURVE_SPECS(3);
4986
4987
    /* load curve info */
4988
    ALLOC_CURVE_SPECS(3, err);
4989
    if (err == MP_OKAY) {
4990
        err = wc_ecc_curve_load(private_key->dp, &curve,
4991
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4992
             ECC_CURVE_FIELD_ORDER));
4993
    }
4994
4995
    if (err != MP_OKAY) {
4996
        FREE_CURVE_SPECS();
4997
        return err;
4998
    }
4999
5000
    if (private_key->dp
5001
    #ifdef WOLFSSL_CUSTOM_CURVES
5002
        && private_key->dp->id != ECC_CURVE_CUSTOM
5003
    #endif
5004
    #ifdef HAVE_CAVIUM_V
5005
        /* verify the curve is supported by hardware */
5006
        && NitroxEccIsCurveSupported(private_key)
5007
    #endif
5008
    ) {
5009
        word32 keySz = private_key->dp->size;
5010
5011
        /* sync public key x/y */
5012
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5013
            &ecc_get_k(private_key)->raw, keySz);
5014
        if (err == MP_OKAY)
5015
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5016
        if (err == MP_OKAY)
5017
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5018
    #ifdef HAVE_CAVIUM_V
5019
        /* allocate buffer for output */
5020
        if (err == MP_OKAY)
5021
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5022
        if (err == MP_OKAY)
5023
            err = wc_bigint_alloc(&private_key->e->raw,
5024
                NitroxEccGetSize(private_key)*2);
5025
        if (err == MP_OKAY)
5026
            err = NitroxEcdh(private_key,
5027
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5028
                private_key->e->raw.buf, &private_key->e->raw.len,
5029
                &curve->prime->raw);
5030
    #else
5031
        if (err == MP_OKAY)
5032
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5033
        if (err == MP_OKAY)
5034
            err = IntelQaEcdh(&private_key->asyncDev,
5035
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5036
                out, outlen,
5037
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5038
                private_key->dp->cofactor);
5039
    #endif
5040
    }
5041
    else
5042
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5043
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5044
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5045
        sw->eccSharedSec.private_key = private_key;
5046
        sw->eccSharedSec.public_point = point;
5047
        sw->eccSharedSec.out = out;
5048
        sw->eccSharedSec.outLen = outlen;
5049
        err = WC_PENDING_E;
5050
    }
5051
    else
5052
#endif
5053
    {
5054
        /* use sync in other cases */
5055
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5056
    }
5057
5058
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5059
        private_key->state++;
5060
    }
5061
5062
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5063
    wc_ecc_curve_free(curve);
5064
    FREE_CURVE_SPECS();
5065
#endif
5066
5067
    return err;
5068
}
5069
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5070
5071
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5072
/**
5073
 Create an ECC shared secret between private key and public point
5074
 private_key      The private ECC key (heap hint based on private key)
5075
 point            The point to use (public key)
5076
 out              [out] Destination of the shared secret
5077
                        Conforms to EC-DH from ANSI X9.63
5078
 outlen           [in/out] The max size and resulting size of the shared secret
5079
 return           MP_OKAY if successful
5080
*/
5081
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5082
                            byte* out, word32 *outlen)
5083
1.42k
{
5084
1.42k
    int err;
5085
5086
1.42k
    if (private_key == NULL || point == NULL || out == NULL ||
5087
1.42k
                                                            outlen == NULL) {
5088
0
        return BAD_FUNC_ARG;
5089
0
    }
5090
5091
    /* type valid? */
5092
1.42k
    if (private_key->type != ECC_PRIVATEKEY &&
5093
338
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5094
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5095
0
        return ECC_BAD_ARG_E;
5096
0
    }
5097
5098
    /* Verify domain params supplied */
5099
1.42k
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5100
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5101
0
        return ECC_BAD_ARG_E;
5102
0
    }
5103
5104
1.42k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5105
5106
1.42k
    switch (private_key->state) {
5107
1.42k
        case ECC_STATE_NONE:
5108
1.42k
        case ECC_STATE_SHARED_SEC_GEN:
5109
1.42k
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5110
5111
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5112
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5113
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5114
                    out, outlen);
5115
            }
5116
            else
5117
        #endif
5118
1.42k
            {
5119
1.42k
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5120
1.42k
                    out, outlen);
5121
1.42k
            }
5122
1.42k
            if (err < 0) {
5123
89
                break;
5124
89
            }
5125
1.34k
            FALL_THROUGH;
5126
5127
1.34k
        case ECC_STATE_SHARED_SEC_RES:
5128
1.34k
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5129
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5130
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5131
            #ifdef HAVE_CAVIUM_V
5132
                /* verify the curve is supported by hardware */
5133
                if (NitroxEccIsCurveSupported(private_key)) {
5134
                    /* copy output */
5135
                    *outlen = private_key->dp->size;
5136
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5137
                }
5138
            #endif /* HAVE_CAVIUM_V */
5139
            }
5140
        #endif /* WOLFSSL_ASYNC_CRYPT */
5141
1.34k
            err = 0;
5142
1.34k
            break;
5143
5144
0
        default:
5145
0
            err = BAD_STATE_E;
5146
1.42k
    } /* switch */
5147
5148
1.42k
    RESTORE_VECTOR_REGISTERS();
5149
5150
    /* if async pending then return and skip done cleanup below */
5151
1.42k
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5152
0
        return err;
5153
0
    }
5154
5155
    /* cleanup */
5156
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5157
    wc_ecc_free_async(private_key);
5158
#endif
5159
1.42k
    private_key->state = ECC_STATE_NONE;
5160
5161
1.42k
    return err;
5162
1.42k
}
5163
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5164
#elif defined(WOLFSSL_KCAPI_ECC)
5165
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5166
                            byte* out, word32 *outlen)
5167
{
5168
    int err;
5169
    ecc_key public_key;
5170
5171
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
5172
    if (err == MP_OKAY) {
5173
        #if FIPS_VERSION3_GE(6,0,0)
5174
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5175
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5176
         * keysize here when relying on default selection */
5177
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5178
            if (private_key->dp->size == 0 &&
5179
                (private_key->dp->id == ECC_SECP256R1 ||
5180
                private_key->dp->id == ECC_SECP224R1 ||
5181
                private_key->dp->id == ECC_SECP384R1 ||
5182
                private_key->dp->id == ECC_SECP521R1)) {
5183
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5184
                err = 0;
5185
            } else {
5186
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5187
                err = ECC_CURVE_OID_E;
5188
            }
5189
        }
5190
        if (err == 0) { /* FIPS specific check */
5191
        #endif
5192
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
5193
                               private_key->dp->id);
5194
        if (err == MP_OKAY) {
5195
            err = mp_copy(point->x, public_key.pubkey.x);
5196
        }
5197
        #if FIPS_VERSION3_GE(6,0,0)
5198
        } /* end FIPS specific check */
5199
        #endif
5200
        if (err == MP_OKAY) {
5201
            err = mp_copy(point->y, public_key.pubkey.y);
5202
        }
5203
        if (err == MP_OKAY) {
5204
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
5205
        }
5206
5207
        wc_ecc_free(&public_key);
5208
    }
5209
5210
    return err;
5211
}
5212
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5213
#endif /* HAVE_ECC_DHE */
5214
5215
#ifdef USE_ECC_B_PARAM
5216
/* Checks if a point p lies on the curve with index curve_idx */
5217
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5218
6.59k
{
5219
6.59k
    int err = MP_OKAY;
5220
6.59k
    DECLARE_CURVE_SPECS(3);
5221
5222
6.59k
    if (p == NULL)
5223
0
        return BAD_FUNC_ARG;
5224
5225
    /* is the IDX valid ?  */
5226
6.59k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5227
0
       return ECC_BAD_ARG_E;
5228
0
    }
5229
5230
6.59k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5231
5232
6.59k
    ALLOC_CURVE_SPECS(3, err);
5233
6.59k
    if (err == MP_OKAY) {
5234
6.38k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5235
6.38k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5236
6.38k
                                ECC_CURVE_FIELD_BF);
5237
6.38k
    }
5238
5239
6.59k
    if (err == MP_OKAY) {
5240
6.35k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5241
6.35k
    }
5242
5243
6.59k
    wc_ecc_curve_free(curve);
5244
6.59k
    FREE_CURVE_SPECS();
5245
5246
6.59k
    RESTORE_VECTOR_REGISTERS();
5247
5248
6.59k
    return err;
5249
6.59k
}
5250
#endif /* USE_ECC_B_PARAM */
5251
5252
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5253
    !defined(WOLFSSL_CRYPTOCELL) && \
5254
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5255
      defined(WOLFSSL_IMXRT1170_CAAM))
5256
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5257
int wc_ecc_point_is_at_infinity(ecc_point* p)
5258
11.5k
{
5259
11.5k
    if (p == NULL)
5260
0
        return BAD_FUNC_ARG;
5261
11.5k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5262
3.68k
        return 1;
5263
5264
7.84k
    return 0;
5265
11.5k
}
5266
#endif
5267
5268
/* generate random and ensure its greater than 0 and less than order */
5269
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5270
46.8k
{
5271
46.8k
#ifndef WC_NO_RNG
5272
46.8k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5273
46.8k
    int err;
5274
46.8k
    byte buf[ECC_MAXSIZE_GEN];
5275
5276
46.8k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5277
46.8k
                                                                order == NULL) {
5278
0
        return BAD_FUNC_ARG;
5279
0
    }
5280
5281
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5282
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5283
46.8k
    size += 8;
5284
5285
    /* make up random string */
5286
46.8k
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5287
#ifdef WOLFSSL_CHECK_MEM_ZERO
5288
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5289
#endif
5290
5291
    /* load random buffer data into k */
5292
46.8k
    if (err == 0)
5293
46.5k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5294
5295
    /* the key should be smaller than the order of base point */
5296
46.8k
    if (err == MP_OKAY) {
5297
46.5k
        if (mp_cmp(k, order) != MP_LT) {
5298
46.2k
            err = mp_mod(k, order, k);
5299
46.2k
        }
5300
46.5k
    }
5301
5302
    /* quick sanity check to make sure we're not dealing with a 0 key */
5303
46.8k
    if (err == MP_OKAY) {
5304
46.4k
        if (mp_iszero(k) == MP_YES)
5305
255
          err = MP_ZERO_E;
5306
46.4k
    }
5307
5308
46.8k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5309
#ifdef WOLFSSL_CHECK_MEM_ZERO
5310
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5311
#endif
5312
5313
46.8k
    return err;
5314
#else
5315
    int err;
5316
    byte buf[ECC_MAXSIZE_GEN];
5317
    int bits;
5318
5319
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5320
            (k == NULL) || (order == NULL)) {
5321
        return BAD_FUNC_ARG;
5322
    }
5323
5324
    /* Get actual bit count of order. */
5325
    bits = mp_count_bits(order);
5326
    size = (bits + 7) >> 3;
5327
5328
    /* generate number in range of order through rejection sampling. */
5329
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5330
    do {
5331
        /* A.2.2 step 3: make up random string */
5332
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5333
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5334
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5335
    #endif
5336
        /* Generated multiple of 8 bits but now make it size of order. */
5337
        if ((bits & 0x7) > 0) {
5338
            buf[0] &= (1 << (bits & 0x7)) - 1;
5339
        }
5340
5341
        /* A.2.2 step 4: convert to integer. */
5342
        /* A.4.2 step 3: Convert the bit string to integer x. */
5343
        if (err == 0) {
5344
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5345
        }
5346
5347
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5348
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5349
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5350
            break;
5351
        }
5352
    }
5353
    while (err == MP_OKAY);
5354
5355
    ForceZero(buf, ECC_MAXSIZE_GEN);
5356
#ifdef WOLFSSL_CHECK_MEM_ZERO
5357
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5358
#endif
5359
5360
    return err;
5361
#endif
5362
#else
5363
    (void)rng;
5364
    (void)size;
5365
    (void)k;
5366
    (void)order;
5367
    return NOT_COMPILED_IN;
5368
#endif /* !WC_NO_RNG */
5369
46.8k
}
5370
5371
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5372
51.8k
{
5373
    /* make sure required key variables are reset */
5374
51.8k
    key->state = ECC_STATE_NONE;
5375
51.8k
}
5376
5377
5378
/* create the public ECC key from a private key
5379
 *
5380
 * key     an initialized private key to generate public part from
5381
 * curve   [in]curve for key, cannot be NULL
5382
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5383
 *         is cached in key instead.
5384
 *
5385
 * Note this function is local to the file because of the argument type
5386
 *      ecc_curve_spec. Having this argument allows for not having to load the
5387
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5388
 * For async the results are placed directly into pubOut, so this function
5389
 *      does not need to be called again
5390
 *
5391
 * returns MP_OKAY on success
5392
 */
5393
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5394
        ecc_point* pubOut, WC_RNG* rng)
5395
3.36k
{
5396
3.36k
    int err = MP_OKAY;
5397
3.36k
#ifdef HAVE_ECC_MAKE_PUB
5398
3.36k
    ecc_point* pub;
5399
3.36k
#endif /* HAVE_ECC_MAKE_PUB */
5400
5401
3.36k
    (void)rng;
5402
5403
3.36k
    if (key == NULL) {
5404
0
        return BAD_FUNC_ARG;
5405
0
    }
5406
5407
3.36k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5408
5409
3.36k
#ifdef HAVE_ECC_MAKE_PUB
5410
    /* if ecc_point passed in then use it as output for public key point */
5411
3.36k
    if (pubOut != NULL) {
5412
1.95k
        pub = pubOut;
5413
1.95k
    }
5414
1.41k
    else {
5415
        /* caching public key making it a ECC_PRIVATEKEY instead of
5416
           ECC_PRIVATEKEY_ONLY */
5417
1.41k
        pub = &key->pubkey;
5418
1.41k
        key->type = ECC_PRIVATEKEY_ONLY;
5419
1.41k
    }
5420
5421
3.36k
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5422
3.36k
            mp_isneg(ecc_get_k(key)) ||
5423
3.36k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5424
38
        err = ECC_PRIV_KEY_E;
5425
38
    }
5426
5427
3.36k
    if (err == MP_OKAY) {
5428
3.32k
    #ifndef ALT_ECC_SIZE
5429
3.32k
        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.32k
    }
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.36k
    { /* BEGIN: Software Crypto */
5457
3.36k
#ifdef WOLFSSL_HAVE_SP_ECC
5458
    /* Single-Precision Math (optimized for specific curves) */
5459
3.36k
    if (err != MP_OKAY) {
5460
38
    }
5461
3.32k
    else
5462
3.32k
#ifndef WOLFSSL_SP_NO_256
5463
3.32k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5464
897
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5465
897
    }
5466
2.43k
    else
5467
2.43k
#endif /* WOLFSSL_SP_NO_256 */
5468
2.43k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5469
2.43k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5470
547
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5471
547
    }
5472
1.88k
    else
5473
1.88k
#endif
5474
1.88k
#ifdef WOLFSSL_SP_384
5475
1.88k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5476
712
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5477
712
    }
5478
1.17k
    else
5479
1.17k
#endif
5480
1.17k
#ifdef WOLFSSL_SP_521
5481
1.17k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5482
1.17k
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5483
1.17k
    }
5484
0
    else
5485
0
#endif
5486
0
#endif /* WOLFSSL_HAVE_SP_ECC */
5487
5488
0
#if defined(WOLFSSL_SP_MATH)
5489
0
        err = WC_KEY_SIZE_E;
5490
#else
5491
    if (err == MP_OKAY) {
5492
        /* Multi-Precision Math: compute public curve */
5493
        mp_digit mp = 0;
5494
        ecc_point* base = NULL;
5495
    #ifdef WOLFSSL_NO_MALLOC
5496
        ecc_point  lcl_base;
5497
        base = &lcl_base;
5498
    #endif
5499
        err = wc_ecc_new_point_ex(&base, key->heap);
5500
5501
        /* read in the x/y for this key */
5502
        if (err == MP_OKAY)
5503
            err = mp_copy(curve->Gx, base->x);
5504
        if (err == MP_OKAY)
5505
            err = mp_copy(curve->Gy, base->y);
5506
        if (err == MP_OKAY)
5507
            err = mp_montgomery_setup(curve->prime, &mp);
5508
        if (err == MP_OKAY)
5509
            err = mp_set(base->z, 1);
5510
5511
        /* make the public key */
5512
        if (err == MP_OKAY) {
5513
            /* Map in a separate call as this should be constant time */
5514
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5515
                                 curve->prime, curve->order, rng, 0, key->heap);
5516
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5517
               err = MEMORY_E;
5518
            }
5519
        }
5520
        if (err == MP_OKAY) {
5521
            /* Use constant time map if compiled in */
5522
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5523
        }
5524
5525
        wc_ecc_del_point_ex(base, key->heap);
5526
    }
5527
#endif /* WOLFSSL_SP_MATH */
5528
3.36k
    } /* END: Software Crypto */
5529
5530
3.36k
    if (err != MP_OKAY
5531
    #ifdef WOLFSSL_ASYNC_CRYPT
5532
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5533
    #endif
5534
3.36k
    ) {
5535
        /* clean up if failed */
5536
80
    #ifndef ALT_ECC_SIZE
5537
80
        mp_clear(pub->x);
5538
80
        mp_clear(pub->y);
5539
80
        mp_clear(pub->z);
5540
80
    #endif
5541
80
    }
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.36k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5551
1.41k
        key->type = ECC_PRIVATEKEY;
5552
1.41k
    }
5553
5554
3.36k
    RESTORE_VECTOR_REGISTERS();
5555
5556
3.36k
    return err;
5557
3.36k
}
5558
5559
5560
/* create the public ECC key from a private key
5561
 *
5562
 * key     an initialized private key to generate public part from
5563
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5564
 *         is cached in key instead.
5565
 *
5566
 *
5567
 * returns MP_OKAY on success
5568
 */
5569
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5570
5.67k
{
5571
5.67k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5572
5573
5.67k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5574
5.67k
}
5575
5576
/* create the public ECC key from a private key - mask timing use random z
5577
 *
5578
 * key     an initialized private key to generate public part from
5579
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5580
 *         is cached in key instead.
5581
 *
5582
 *
5583
 * returns MP_OKAY on success
5584
 */
5585
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5586
3.41k
{
5587
3.41k
    int err = MP_OKAY;
5588
3.41k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5589
5590
3.41k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5591
5592
3.41k
    if (key == NULL) {
5593
0
        return BAD_FUNC_ARG;
5594
0
    }
5595
5596
    /* load curve info */
5597
3.41k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5598
3.41k
    if (err == MP_OKAY) {
5599
3.40k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5600
3.40k
    }
5601
3.41k
    if (err == MP_OKAY) {
5602
3.39k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5603
3.39k
    }
5604
5605
3.41k
    wc_ecc_curve_free(curve);
5606
3.41k
    FREE_CURVE_SPECS();
5607
5608
3.41k
    return err;
5609
3.41k
}
5610
5611
5612
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5613
        int curve_id, int flags)
5614
944
{
5615
944
    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
944
    if (key == NULL || rng == NULL) {
5631
0
        return BAD_FUNC_ARG;
5632
0
    }
5633
5634
    /* make sure required variables are reset */
5635
944
    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
944
    err = wc_ecc_set_curve(key, keysize, curve_id);
5655
944
    if (err != 0) {
5656
52
        return err;
5657
52
    }
5658
    #if FIPS_VERSION3_GE(6,0,0)
5659
    } /* end FIPS specific check */
5660
    #endif
5661
892
    key->flags = (byte)flags;
5662
5663
892
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5664
892
    #ifndef WOLF_CRYPTO_CB_FIND
5665
892
    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
892
#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
892
#ifdef WOLFSSL_HAVE_SP_ECC
5845
5846
892
#ifndef WOLFSSL_SP_NO_256
5847
892
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5848
249
    #ifndef WC_ECC_NONBLOCK
5849
249
        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
249
        if (err == MP_OKAY) {
5868
217
            key->type = ECC_PRIVATEKEY;
5869
217
        }
5870
249
    }
5871
643
    else
5872
643
#endif /* !WOLFSSL_SP_NO_256 */
5873
643
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5874
643
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5875
166
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
5876
166
        if (err == MP_OKAY) {
5877
132
            key->type = ECC_PRIVATEKEY;
5878
132
        }
5879
166
    }
5880
477
    else
5881
477
#endif
5882
477
#ifdef WOLFSSL_SP_384
5883
477
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5884
250
    #ifndef WC_ECC_NONBLOCK
5885
250
        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
250
        if (err == MP_OKAY) {
5904
220
            key->type = ECC_PRIVATEKEY;
5905
220
        }
5906
250
    }
5907
227
    else
5908
227
#endif /* WOLFSSL_SP_384 */
5909
227
#ifdef WOLFSSL_SP_521
5910
227
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5911
227
    #ifndef WC_ECC_NONBLOCK
5912
227
        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
227
        if (err == MP_OKAY) {
5931
190
            key->type = ECC_PRIVATEKEY;
5932
190
        }
5933
227
    }
5934
0
    else
5935
0
#endif /* WOLFSSL_SP_521 */
5936
0
#endif /* WOLFSSL_HAVE_SP_ECC */
5937
5938
0
   { /* software key gen */
5939
0
#if defined(WOLFSSL_SP_MATH)
5940
0
        err = WC_KEY_SIZE_E;
5941
#else
5942
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5943
5944
        /* setup the key variables */
5945
#ifndef ALT_ECC_SIZE
5946
        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
        if (err == MP_OKAY) {
5955
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5956
            if (err != MP_OKAY) {
5957
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5958
            }
5959
        }
5960
5961
        if (err == MP_OKAY) {
5962
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5963
            if (err != MP_OKAY) {
5964
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5965
            }
5966
        }
5967
5968
        /* generate k */
5969
        if (err == MP_OKAY) {
5970
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5971
            if (err != MP_OKAY) {
5972
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5973
            }
5974
        }
5975
5976
        /* generate public key from k */
5977
        if (err == MP_OKAY) {
5978
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5979
            if (err != MP_OKAY) {
5980
                WOLFSSL_MSG("ecc_make_pub_ex failed");
5981
            }
5982
        }
5983
5984
        if (err == MP_OKAY
5985
        #ifdef WOLFSSL_ASYNC_CRYPT
5986
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
5987
        #endif
5988
        ) {
5989
            key->type = ECC_PRIVATEKEY;
5990
        }
5991
        else {
5992
            /* cleanup these on failure case only */
5993
            mp_forcezero(key->k);
5994
        }
5995
5996
        /* cleanup allocations */
5997
        wc_ecc_curve_free(curve);
5998
        FREE_CURVE_SPECS();
5999
#endif /* WOLFSSL_SP_MATH */
6000
0
    }
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
892
#endif /* HAVE_ECC_MAKE_PUB */
6019
6020
892
    return err;
6021
892
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6022
892
}
6023
6024
6025
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6026
                        int flags)
6027
14.4k
{
6028
14.4k
    int err;
6029
6030
14.4k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6031
6032
14.4k
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6033
6034
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6035
    !defined(WOLFSSL_KCAPI_ECC)
6036
    if (err == MP_OKAY) {
6037
        err = _ecc_validate_public_key(key, 0, 0);
6038
    }
6039
    if (err == MP_OKAY
6040
#if defined(WOLF_CRYPTO_CB)
6041
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6042
        && key->devId == INVALID_DEVID
6043
#endif
6044
        ) {
6045
        err = _ecc_pairwise_consistency_test(key, rng);
6046
    }
6047
#endif
6048
6049
14.4k
    RESTORE_VECTOR_REGISTERS();
6050
6051
14.4k
    return err;
6052
14.4k
}
6053
6054
WOLFSSL_ABI
6055
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6056
14.4k
{
6057
14.4k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6058
14.4k
}
6059
6060
#ifdef ECC_DUMP_OID
6061
/* Optional dump of encoded OID for adding new curves */
6062
static int mOidDumpDone;
6063
static void wc_ecc_dump_oids(void)
6064
{
6065
    int x;
6066
6067
    if (mOidDumpDone) {
6068
        return;
6069
    }
6070
6071
    /* find matching OID sum (based on encoded value) */
6072
    for (x = 0; ecc_sets[x].size != 0; x++) {
6073
        int i;
6074
        byte* oid;
6075
        word32 oidSz, sum = 0;
6076
6077
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6078
6079
    #ifdef HAVE_OID_ENCODING
6080
        byte oidEnc[ECC_MAX_OID_LEN];
6081
6082
        oid = oidEnc;
6083
        oidSz = ECC_MAX_OID_LEN;
6084
6085
        printf("OID: ");
6086
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6087
            printf("%d.", ecc_sets[x].oid[i]);
6088
        }
6089
        printf("\n");
6090
6091
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6092
    #else
6093
        oid = (byte*)ecc_sets[x].oid;
6094
        oidSz = ecc_sets[x].oidSz;
6095
    #endif
6096
6097
        printf("OID Encoded: ");
6098
        for (i = 0; i < (int)oidSz; i++) {
6099
            printf("0x%02X,", oid[i]);
6100
        }
6101
        printf("\n");
6102
6103
        for (i = 0; i < (int)oidSz; i++) {
6104
            sum += oid[i];
6105
        }
6106
        printf("Sum: %u\n", sum);
6107
6108
        /* validate sum */
6109
        if (ecc_sets[x].oidSum != sum) {
6110
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6111
        }
6112
    }
6113
    mOidDumpDone = 1;
6114
}
6115
#endif /* ECC_DUMP_OID */
6116
6117
6118
WOLFSSL_ABI
6119
ecc_key* wc_ecc_key_new(void* heap)
6120
37.7k
{
6121
37.7k
    int devId = INVALID_DEVID;
6122
37.7k
    ecc_key* key;
6123
6124
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6125
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6126
    devId = WOLFSSL_CAAM_DEVID;
6127
#endif
6128
37.7k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6129
37.7k
    if (key) {
6130
33.6k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6131
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6132
0
            key = NULL;
6133
0
        }
6134
33.6k
    }
6135
6136
37.7k
    return key;
6137
37.7k
}
6138
6139
6140
WOLFSSL_ABI
6141
void wc_ecc_key_free(ecc_key* key)
6142
102k
{
6143
102k
    if (key) {
6144
33.6k
        void* heap = key->heap;
6145
6146
33.6k
        wc_ecc_free(key);
6147
33.6k
        ForceZero(key, sizeof(ecc_key));
6148
33.6k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6149
33.6k
        (void)heap;
6150
33.6k
    }
6151
102k
}
6152
6153
6154
/**
6155
 Make a new ECC key
6156
 rng          An active RNG state
6157
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6158
 key          [out] Destination of the newly created key
6159
 return       MP_OKAY if successful,
6160
 upon error all allocated memory will be freed
6161
 */
6162
WOLFSSL_ABI
6163
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6164
0
{
6165
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6166
0
}
6167
6168
/* Setup dynamic pointers if using normal math for proper freeing */
6169
WOLFSSL_ABI
6170
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6171
59.1k
{
6172
59.1k
    int ret      = 0;
6173
6174
59.1k
    if (key == NULL) {
6175
0
        return BAD_FUNC_ARG;
6176
0
    }
6177
6178
#ifdef ECC_DUMP_OID
6179
    wc_ecc_dump_oids();
6180
#endif
6181
6182
59.1k
    XMEMSET(key, 0, sizeof(ecc_key));
6183
59.1k
    key->state = ECC_STATE_NONE;
6184
6185
59.1k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6186
59.1k
    key->devId = devId;
6187
#else
6188
    (void)devId;
6189
#endif
6190
6191
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6192
    key->slot = ATECC_INVALID_SLOT;
6193
#else
6194
#if defined(WOLFSSL_KCAPI_ECC)
6195
    key->handle = NULL;
6196
#endif
6197
#ifdef ALT_ECC_SIZE
6198
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6199
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6200
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6201
    alt_fp_init(key->pubkey.x);
6202
    alt_fp_init(key->pubkey.y);
6203
    alt_fp_init(key->pubkey.z);
6204
    key->k = (mp_int*)key->ka;
6205
    alt_fp_init(key->k);
6206
#ifdef WOLFSSL_ECC_BLIND_K
6207
    key->kb = (mp_int*)key->kba;
6208
    key->ku = (mp_int*)key->kia;
6209
    alt_fp_init(key->kb);
6210
    alt_fp_init(key->ku);
6211
#endif
6212
#else
6213
59.1k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6214
59.1k
#ifndef WOLFSSL_ECC_BLIND_K
6215
59.1k
                                                                      NULL, NULL
6216
#else
6217
                                                                key->kb, key->ku
6218
#endif
6219
59.1k
                        );
6220
59.1k
    if (ret != MP_OKAY) {
6221
0
        return MEMORY_E;
6222
0
    }
6223
59.1k
#endif /* ALT_ECC_SIZE */
6224
#ifdef WOLFSSL_ECC_BLIND_K
6225
    mp_forcezero(key->kb);
6226
#endif
6227
59.1k
#endif /* WOLFSSL_ATECC508A */
6228
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6229
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6230
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6231
     defined(WOLFSSL_NO_MALLOC)
6232
    ret = mp_init(key->sign_k);
6233
    if (ret != MP_OKAY) {
6234
        return MEMORY_E;
6235
    }
6236
#endif
6237
6238
#ifdef WOLFSSL_HEAP_TEST
6239
    (void)heap;
6240
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6241
#else
6242
59.1k
    key->heap = heap;
6243
59.1k
#endif
6244
6245
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6246
    #ifdef WOLF_CRYPTO_CB
6247
    /* prefer crypto callback */
6248
    if (key->devId != INVALID_DEVID)
6249
    #endif
6250
    {
6251
        /* handle as async */
6252
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6253
                                                        key->heap, devId);
6254
    }
6255
    if (ret != 0)
6256
        return ret;
6257
#endif
6258
6259
#if defined(WOLFSSL_DSP)
6260
    key->handle = -1;
6261
#endif
6262
6263
#ifdef WOLFSSL_SE050
6264
    key->keyId = 0;
6265
    key->keyIdSet = 0;
6266
#endif
6267
6268
#ifdef WOLFSSL_CHECK_MEM_ZERO
6269
    mp_memzero_add("ECC k", key->k);
6270
#ifdef WOLFSSL_ECC_BLIND_K
6271
    mp_memzero_add("ECC kb", key->kb);
6272
    mp_memzero_add("ECC ku", key->ku);
6273
#endif
6274
#endif
6275
6276
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6277
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6278
6279
    if (wc_InitXsecure(&(key->xSec))) {
6280
        WOLFSSL_MSG("Can't initialize Xsecure");
6281
        return WC_HW_E;
6282
    }
6283
#endif
6284
6285
59.1k
    return ret;
6286
59.1k
}
6287
6288
WOLFSSL_ABI
6289
int wc_ecc_init(ecc_key* key)
6290
2.17k
{
6291
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6292
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6293
#else
6294
2.17k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6295
2.17k
#endif
6296
2.17k
}
6297
6298
#ifdef WOLF_PRIVATE_KEY_ID
6299
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6300
                   int devId)
6301
0
{
6302
0
    int ret = 0;
6303
#ifdef WOLFSSL_SE050
6304
    /* SE050 TLS users store a word32 at id, need to cast back */
6305
    word32* keyPtr = NULL;
6306
#endif
6307
6308
0
    if (key == NULL)
6309
0
        ret = BAD_FUNC_ARG;
6310
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6311
0
        ret = BUFFER_E;
6312
0
    if (ret == 0)
6313
0
        ret = wc_ecc_init_ex(key, heap, devId);
6314
0
    if (ret == 0 && id != NULL && len != 0) {
6315
0
        XMEMCPY(key->id, id, (size_t)len);
6316
0
        key->idLen = len;
6317
    #ifdef WOLFSSL_SE050
6318
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6319
        if (len == (int)sizeof(word32)) {
6320
            keyPtr = (word32*)key->id;
6321
            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
6322
        }
6323
    #endif
6324
0
    }
6325
6326
0
    return ret;
6327
0
}
6328
6329
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6330
0
{
6331
0
    int ret = 0;
6332
0
    int labelLen = 0;
6333
6334
0
    if (key == NULL || label == NULL)
6335
0
        ret = BAD_FUNC_ARG;
6336
0
    if (ret == 0) {
6337
0
        labelLen = (int)XSTRLEN(label);
6338
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6339
0
            ret = BUFFER_E;
6340
0
    }
6341
0
    if (ret == 0)
6342
0
        ret = wc_ecc_init_ex(key, heap, devId);
6343
0
    if (ret == 0) {
6344
0
        XMEMCPY(key->label, label, (size_t)labelLen);
6345
0
        key->labelLen = labelLen;
6346
0
    }
6347
6348
0
    return ret;
6349
0
}
6350
#endif /* WOLF_PRIVATE_KEY_ID */
6351
6352
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6353
607
{
6354
607
    if (key == NULL) {
6355
0
        return BAD_FUNC_ARG;
6356
0
    }
6357
607
    key->flags |= flags;
6358
607
    return 0;
6359
607
}
6360
6361
6362
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6363
{
6364
    int err = MP_OKAY;
6365
    int orderBits;
6366
    DECLARE_CURVE_SPECS(1);
6367
6368
    ALLOC_CURVE_SPECS(1, err);
6369
    if (err == MP_OKAY) {
6370
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6371
    }
6372
6373
    if (err != 0) {
6374
       FREE_CURVE_SPECS();
6375
       return err;
6376
    }
6377
    orderBits = mp_count_bits(curve->order);
6378
6379
    wc_ecc_curve_free(curve);
6380
    FREE_CURVE_SPECS();
6381
    return orderBits;
6382
}
6383
6384
#ifdef HAVE_ECC_SIGN
6385
6386
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6387
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6388
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6389
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6390
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6391
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6392
    ecc_key* key)
6393
{
6394
    int err;
6395
#ifdef PLUTON_CRYPTO_ECC
6396
    if (key->devId != INVALID_DEVID) /* use hardware */
6397
#endif
6398
    {
6399
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6400
        !defined(WOLFSSL_ATECC608A)
6401
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6402
        word32 raw_sig_size = *outlen;
6403
        word32 msgLenInBytes = inlen;
6404
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6405
    #endif
6406
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6407
#ifdef WOLFSSL_SMALL_STACK
6408
        byte* K = NULL;
6409
        byte* incopy = NULL;
6410
#else
6411
        byte K[MAX_ECC_BYTES] = {0};
6412
        byte incopy[MAX_ECC_BYTES] = {0};
6413
#endif
6414
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6415
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6416
        word32 Ksize;
6417
#endif
6418
#endif
6419
        word32 keysize = (word32)key->dp->size;
6420
    #ifdef PLUTON_CRYPTO_ECC
6421
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6422
    #endif
6423
6424
    #ifndef WOLFSSL_KCAPI_ECC
6425
        /* Check args */
6426
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6427
            return ECC_BAD_ARG_E;
6428
        }
6429
    #endif
6430
6431
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6432
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6433
        err = atmel_ecc_sign(key->slot, in, out);
6434
        if (err != 0) {
6435
           return err;
6436
        }
6437
    #elif defined(PLUTON_CRYPTO_ECC)
6438
        {
6439
            /* if the input is larger than curve order, we must truncate */
6440
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6441
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6442
            }
6443
6444
            /* perform ECC sign */
6445
            word32 raw_sig_size = *outlen;
6446
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6447
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6448
               return BAD_COND_E;
6449
            }
6450
        }
6451
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6452
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6453
        if (err != 0) {
6454
               return WC_HW_E;
6455
        }
6456
    #elif defined(WOLFSSL_CRYPTOCELL)
6457
        /* truncate if hash is longer than key size */
6458
        if (msgLenInBytes > keysize) {
6459
            msgLenInBytes = keysize;
6460
        }
6461
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6462
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6463
            (void)cc310_hashModeECC(keysize);
6464
            /* Ignoring returned value */
6465
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6466
6467
        }
6468
6469
        /* create signature from an input buffer using a private key*/
6470
        err = CRYS_ECDSA_Sign(&wc_rndState,
6471
                               wc_rndGenVectFunc,
6472
                               &sigCtxTemp,
6473
                               &key->ctx.privKey,
6474
                               hash_mode,
6475
                               (byte*)in,
6476
                               msgLenInBytes,
6477
                               out,
6478
                               (uint32_t*)&raw_sig_size);
6479
6480
        if (err != SA_SILIB_RET_OK){
6481
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6482
            return err;
6483
        }
6484
    #elif defined(WOLFSSL_KCAPI_ECC)
6485
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6486
        if (err != MP_OKAY) {
6487
            return err;
6488
        }
6489
        (void)rng;
6490
    #elif defined(WOLFSSL_SE050)
6491
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6492
        if (err != MP_OKAY) {
6493
            return err;
6494
        }
6495
        (void)rng;
6496
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6497
6498
#ifdef WOLFSSL_SMALL_STACK
6499
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6500
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6501
        if (K == NULL || incopy == NULL) {
6502
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6503
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6504
            return MEMORY_E;
6505
        }
6506
#else
6507
        if (inlen > sizeof(incopy))
6508
            return ECC_BAD_ARG_E;
6509
#endif
6510
6511
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6512
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6513
        err = deterministic_sign_helper(in, inlen, key);
6514
        if (err)
6515
            return err;
6516
        Ksize = mp_unsigned_bin_size(key->sign_k);
6517
        if (Ksize > keysize) {
6518
            err = BUFFER_E;
6519
            goto error_out;
6520
        }
6521
        err = mp_to_unsigned_bin(key->sign_k, K);
6522
        if (err)
6523
            goto error_out;
6524
        mp_reverse(K, Ksize);
6525
#else
6526
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6527
        if (err)
6528
            goto error_out;
6529
        /* Make sure that K is max. 521 bits */
6530
        if (keysize == 66)
6531
            K[65] &= 0x1;
6532
#endif
6533
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6534
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6535
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6536
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6537
6538
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6539
6540
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6541
                                           xil_curve_type[key->dp->id],
6542
                                           XIL_CAST_U64(incopy), keysize,
6543
                                           XIL_CAST_U64(key->privKey),
6544
                                           XIL_CAST_U64(K),
6545
                                           XIL_CAST_U64(out));
6546
        if (err) {
6547
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6548
            err = WC_HW_E;
6549
        }
6550
6551
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6552
        mp_reverse(&out[0], keysize);
6553
        mp_reverse(&out[keysize], keysize);
6554
6555
error_out:
6556
        ForceZero(K, MAX_ECC_BYTES);
6557
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6558
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6559
        if (err) {
6560
            ForceZero(out, keysize * 2);
6561
            return err;
6562
        }
6563
    #endif /* HW-specific #if-#elif chain */
6564
6565
    #ifndef WOLFSSL_SE050
6566
        /* Load R and S, SE050 does this in port layer */
6567
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6568
        if (err != MP_OKAY) {
6569
            return err;
6570
        }
6571
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6572
        if (err != MP_OKAY) {
6573
            return err;
6574
        }
6575
    #endif
6576
6577
        /* Check for zeros */
6578
        if (mp_iszero(r) || mp_iszero(s)) {
6579
            return MP_ZERO_E;
6580
        }
6581
    }
6582
#ifdef PLUTON_CRYPTO_ECC
6583
    else {
6584
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6585
    }
6586
#endif
6587
    (void)rng;
6588
6589
    return err;
6590
}
6591
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6592
6593
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6594
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6595
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6596
{
6597
    int err;
6598
    mp_int *r = NULL, *s = NULL;
6599
6600
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6601
                                                                rng == NULL) {
6602
        return ECC_BAD_ARG_E;
6603
    }
6604
6605
    err = wc_ecc_alloc_async(key);
6606
    if (err != 0) {
6607
        return err;
6608
    }
6609
    r = key->r;
6610
    s = key->s;
6611
6612
    switch (key->state) {
6613
        case ECC_STATE_NONE:
6614
        case ECC_STATE_SIGN_DO:
6615
            key->state = ECC_STATE_SIGN_DO;
6616
6617
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6618
                break;
6619
            }
6620
6621
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6622
            if (err < 0) {
6623
                break;
6624
            }
6625
6626
            FALL_THROUGH;
6627
6628
        case ECC_STATE_SIGN_ENCODE:
6629
            key->state = ECC_STATE_SIGN_ENCODE;
6630
6631
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6632
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6633
                    DECLARE_CURVE_SPECS(1);
6634
                    ALLOC_CURVE_SPECS(1, err);
6635
                    if (err != MP_OKAY) {
6636
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6637
                        break;
6638
                    }
6639
6640
                    /* get curve order */
6641
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6642
                #endif
6643
6644
                #ifdef HAVE_CAVIUM_V
6645
                    /* Nitrox requires r and s in sep buffer, so split it */
6646
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6647
                #endif
6648
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6649
                    /* only do this if not software, since it overwrites result */
6650
                    wc_bigint_to_mp(&r->raw, r);
6651
                    wc_bigint_to_mp(&s->raw, s);
6652
6653
                /* if using a curve with cofactor != 1 then reduce by mod order */
6654
                #ifdef HAVE_ECC_CDH
6655
                    /* if r is not less than order than reduce */
6656
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6657
                        err = mp_mod(r, curve->order, r);
6658
                    }
6659
                    wc_ecc_curve_free(curve);
6660
                    FREE_CURVE_SPECS();
6661
                #endif
6662
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6663
            }
6664
6665
            /* encoded with DSA header */
6666
            if (err == 0) {
6667
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6668
            }
6669
6670
            /* done with R/S */
6671
            mp_clear(r);
6672
            mp_clear(s);
6673
            break;
6674
6675
        default:
6676
            err = BAD_STATE_E;
6677
            break;
6678
    }
6679
6680
    /* if async pending then return and skip done cleanup below */
6681
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6682
        key->state++;
6683
        return err;
6684
    }
6685
6686
    /* cleanup */
6687
    wc_ecc_free_async(key);
6688
    key->state = ECC_STATE_NONE;
6689
6690
    return err;
6691
}
6692
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6693
6694
/**
6695
 Sign a message digest
6696
 in        The message digest to sign
6697
 inlen     The length of the digest
6698
 out       [out] The destination for the signature
6699
 outlen    [in/out] The max size and resulting size of the signature
6700
 key       A private ECC key
6701
 return    MP_OKAY if successful
6702
 */
6703
WOLFSSL_ABI
6704
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6705
                     WC_RNG* rng, ecc_key* key)
6706
3.80k
{
6707
3.80k
    int err;
6708
3.80k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6709
3.80k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6710
3.80k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6711
3.80k
#endif
6712
#ifdef NO_ASN
6713
    word32 keySz;
6714
#endif
6715
6716
3.80k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6717
179
        return ECC_BAD_ARG_E;
6718
179
    }
6719
3.63k
    if (inlen > WC_MAX_DIGEST_SIZE) {
6720
128
        return BAD_LENGTH_E;
6721
128
    }
6722
6723
3.50k
#ifdef WOLF_CRYPTO_CB
6724
3.50k
    #ifndef WOLF_CRYPTO_CB_FIND
6725
3.50k
    if (key->devId != INVALID_DEVID)
6726
0
    #endif
6727
0
    {
6728
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
6729
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6730
0
            return err;
6731
        /* fall-through when unavailable */
6732
0
    }
6733
3.50k
#endif
6734
6735
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6736
    (void)rng;
6737
    (void)inlen;
6738
    (void)s;
6739
    (void)r;
6740
    (void)err;
6741
    return NO_VALID_DEVID;
6742
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6743
3.50k
    if (rng == NULL) {
6744
0
        WOLFSSL_MSG("ECC sign RNG missing");
6745
0
        return ECC_BAD_ARG_E;
6746
0
    }
6747
6748
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6749
    /* handle async cases */
6750
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
6751
#else
6752
6753
3.50k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6754
3.50k
    #ifdef MP_INT_SIZE_CHECK_NULL
6755
3.50k
    if (r == NULL)
6756
5
        return MEMORY_E;
6757
3.49k
    #endif
6758
3.49k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6759
3.49k
    #ifdef MP_INT_SIZE_CHECK_NULL
6760
3.49k
    if (s == NULL) {
6761
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6762
5
        return MEMORY_E;
6763
5
    }
6764
3.49k
    #endif
6765
6766
3.49k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6767
3.49k
    if (err != 0) {
6768
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6769
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6770
0
        return err;
6771
0
    }
6772
3.49k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6773
3.49k
    if (err != 0) {
6774
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6775
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6776
0
        return err;
6777
0
    }
6778
6779
/* hardware crypto */
6780
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6781
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6782
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6783
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6784
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
6785
#else
6786
3.49k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6787
3.49k
#endif
6788
3.49k
    if (err < 0) {
6789
121
        mp_clear(r);
6790
121
        mp_clear(s);
6791
121
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6792
121
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6793
121
        return err;
6794
121
    }
6795
6796
3.37k
#ifndef NO_ASN
6797
    /* encoded with DSA header */
6798
3.37k
    err = StoreECC_DSA_Sig(out, outlen, r, s);
6799
#else
6800
    /* No support for DSA ASN.1 header.
6801
     * Signature will be r+s directly. */
6802
    keySz = 0;
6803
    if (key->dp != NULL) {
6804
        keySz = (word32)key->dp->size;
6805
    }
6806
    if (keySz <= 0) {
6807
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
6808
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
6809
    }
6810
    *outlen = keySz * 2;
6811
6812
    /* Export signature into r,s */
6813
    mp_to_unsigned_bin_len(r, out, keySz);
6814
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
6815
#endif /* !NO_ASN */
6816
6817
    /* cleanup */
6818
3.37k
    mp_clear(r);
6819
3.37k
    mp_clear(s);
6820
6821
3.37k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6822
3.37k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6823
3.37k
#endif /* WOLFSSL_ASYNC_CRYPT */
6824
3.37k
    return err;
6825
3.49k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6826
3.49k
}
6827
6828
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6829
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6830
/* returns MP_OKAY on success */
6831
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
6832
{
6833
    int err = MP_OKAY;
6834
    DECLARE_CURVE_SPECS(1);
6835
    ALLOC_CURVE_SPECS(1, err);
6836
6837
    /* get curve order */
6838
    if (err == MP_OKAY) {
6839
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6840
    }
6841
6842
    if (err == MP_OKAY) {
6843
    #ifndef WOLFSSL_NO_MALLOC
6844
        /* if key->sign_k is NULL then create a buffer for the mp_int
6845
         * if not NULL then assume the user correctly set deterministic flag and
6846
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
6847
        if (key->sign_k == NULL) {
6848
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6849
                                                            DYNAMIC_TYPE_ECC);
6850
            if (key->sign_k != NULL) {
6851
                err = mp_init(key->sign_k);
6852
                if (err != MP_OKAY) {
6853
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6854
                    key->sign_k = NULL;
6855
                }
6856
            }
6857
        }
6858
        if (key->sign_k != NULL) {
6859
            if (wc_ecc_gen_deterministic_k(in, inlen,
6860
                        key->hashType, ecc_get_k(key), key->sign_k,
6861
                        curve->order, key->heap) != 0) {
6862
                mp_free(key->sign_k);
6863
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6864
                key->sign_k = NULL;
6865
                err = ECC_PRIV_KEY_E;
6866
            }
6867
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6868
            else {
6869
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
6870
            }
6871
        #endif
6872
        }
6873
        else {
6874
            err = MEMORY_E;
6875
        }
6876
    #else
6877
        key->sign_k_set = 0;
6878
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
6879
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
6880
            err = ECC_PRIV_KEY_E;
6881
        }
6882
        else {
6883
            key->sign_k_set = 1;
6884
        }
6885
    #endif
6886
    }
6887
6888
    wc_ecc_curve_free(curve);
6889
    FREE_CURVE_SPECS();
6890
    return err;
6891
}
6892
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
6893
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
6894
6895
#if defined(WOLFSSL_STM32_PKA)
6896
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6897
                     ecc_key* key, mp_int *r, mp_int *s)
6898
{
6899
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6900
}
6901
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6902
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
6903
#ifndef WOLFSSL_SP_MATH
6904
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
6905
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
6906
                            mp_int* s)
6907
{
6908
    int err = MP_OKAY;
6909
    int loop_check = 0;
6910
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6911
6912
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6913
#ifdef MP_INT_SIZE_CHECK_NULL
6914
    if (b == NULL)
6915
        err = MEMORY_E;
6916
#endif
6917
6918
    if (err == MP_OKAY) {
6919
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6920
    }
6921
6922
#ifdef WOLFSSL_CUSTOM_CURVES
6923
    /* if custom curve, apply params to pubkey */
6924
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6925
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6926
    }
6927
#endif
6928
6929
    if (err == MP_OKAY) {
6930
        /* Generate blinding value - non-zero value. */
6931
        do {
6932
            if (++loop_check > 64) {
6933
                 err = RNG_FAILURE_E;
6934
                 break;
6935
            }
6936
6937
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6938
        }
6939
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6940
        loop_check = 0;
6941
    }
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
    for (; err == MP_OKAY;) {
6949
        if (++loop_check > 64) {
6950
             err = RNG_FAILURE_E;
6951
             break;
6952
        }
6953
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6954
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6955
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6956
#ifndef WOLFSSL_NO_MALLOC
6957
        if (key->sign_k != NULL)
6958
#else
6959
        if (key->sign_k_set)
6960
#endif
6961
        {
6962
            if (loop_check > 1) {
6963
               err = RNG_FAILURE_E;
6964
               break;
6965
            }
6966
6967
            /* use provided sign_k */
6968
            err = mp_copy(key->sign_k, pubkey->k);
6969
            if (err != MP_OKAY) break;
6970
6971
            /* free sign_k, so only used once */
6972
            mp_forcezero(key->sign_k);
6973
#ifndef WOLFSSL_NO_MALLOC
6974
            mp_free(key->sign_k);
6975
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6976
            key->sign_k = NULL;
6977
#else
6978
            key->sign_k_set = 0;
6979
#endif
6980
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6981
            loop_check = 64;
6982
    #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
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6994
        }
6995
        else
6996
#endif
6997
        {
6998
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6999
                    WC_ECC_FLAG_NONE);
7000
        }
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
        if (err != MP_OKAY) break;
7011
7012
        /* find r = x1 mod n */
7013
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7014
        if (err != MP_OKAY) break;
7015
7016
        if (mp_iszero(r) == MP_NO) {
7017
            mp_int* kp = ecc_get_k(pubkey);
7018
            mp_int* ep = kp;
7019
            mp_int* x  = ecc_get_k(key);
7020
7021
            /* Blind after getting. */
7022
            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
            err = mp_mulmod(kp, b, curve->order, kp);
7029
            if (err != MP_OKAY) break;
7030
7031
            /* k' = 1/k.b
7032
                  = 1/k' */
7033
            err = mp_invmod(kp, curve->order, kp);
7034
            if (err != MP_OKAY) break;
7035
7036
            /* s = x.r */
7037
            err = mp_mulmod(x, r, curve->order, s);
7038
            if (err != MP_OKAY) break;
7039
7040
            /* s = x.r/k.b
7041
                 = k'.s */
7042
            err = mp_mulmod(kp, s, curve->order, s);
7043
            if (err != MP_OKAY) break;
7044
7045
            /* e' = e/k.b
7046
                  = e.k' */
7047
            err = mp_mulmod(kp, e, curve->order, ep);
7048
            if (err != MP_OKAY) break;
7049
7050
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7051
                 = e' + s */
7052
            err = mp_addmod_ct(ep, s, curve->order, s);
7053
            if (err != MP_OKAY) break;
7054
7055
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7056
                 = b.s */
7057
            err = mp_mulmod(s, b, curve->order, s);
7058
            if (err != MP_OKAY) break;
7059
7060
            if (mp_iszero(s) == MP_NO) {
7061
                /* sign successful */
7062
                break;
7063
            }
7064
         }
7065
     #ifndef ALT_ECC_SIZE
7066
         mp_clear(pubkey->pubkey.x);
7067
         mp_clear(pubkey->pubkey.y);
7068
         mp_clear(pubkey->pubkey.z);
7069
     #endif
7070
         mp_forcezero(pubkey->k);
7071
    }
7072
    mp_forcezero(b);
7073
    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
    return err;
7079
}
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
1.50k
{
7086
1.50k
    if (key->idx != ECC_CUSTOM_IDX) {
7087
1.50k
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7088
1.50k
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7089
1.50k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7090
1.50k
        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
1.50k
    #ifndef WOLFSSL_SP_NO_256
7100
1.50k
        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
335
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7118
335
            {
7119
335
                int ret;
7120
335
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7121
335
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7122
335
                                      sign_k, key->heap);
7123
335
                RESTORE_VECTOR_REGISTERS();
7124
335
                return ret;
7125
335
            }
7126
335
        #endif
7127
335
        }
7128
1.16k
    #endif
7129
1.16k
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7130
1.16k
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7131
287
            int ret;
7132
287
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
7133
287
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7134
287
                                      sign_k, key->heap);
7135
287
            RESTORE_VECTOR_REGISTERS();
7136
287
            return ret;
7137
287
        }
7138
881
    #endif
7139
881
    #ifdef WOLFSSL_SP_384
7140
881
        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
323
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7158
323
            {
7159
323
                int ret;
7160
323
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7161
323
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7162
323
                                      sign_k, key->heap);
7163
323
                RESTORE_VECTOR_REGISTERS();
7164
323
                return ret;
7165
323
            }
7166
323
        #endif
7167
323
        }
7168
558
    #endif
7169
558
    #ifdef WOLFSSL_SP_521
7170
558
        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
558
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7188
558
            {
7189
558
                int ret;
7190
558
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7191
558
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7192
558
                                      sign_k, key->heap);
7193
558
                RESTORE_VECTOR_REGISTERS();
7194
558
                return ret;
7195
558
            }
7196
558
        #endif
7197
558
        }
7198
0
    #endif
7199
0
        (void)sign_k;
7200
0
    }
7201
7202
    /* SP doesn't support curve. */
7203
0
    return WC_KEY_SIZE_E;
7204
1.50k
}
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.50k
{
7219
1.50k
   int    err = 0;
7220
#if !defined(WOLFSSL_SP_MATH)
7221
   mp_int* e;
7222
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7223
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7224
#endif
7225
7226
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7227
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7228
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7229
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7230
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7231
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7232
#else
7233
   DECLARE_CURVE_SPECS(1);
7234
#endif
7235
#endif /* !WOLFSSL_SP_MATH */
7236
7237
1.50k
   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.50k
   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.50k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7248
0
      return ECC_BAD_ARG_E;
7249
0
   }
7250
7251
1.50k
#if defined(WOLFSSL_SP_MATH)
7252
1.50k
    if (key->idx == ECC_CUSTOM_IDX || (1
7253
1.50k
    #ifndef WOLFSSL_SP_NO_256
7254
1.50k
         && ecc_sets[key->idx].id != ECC_SECP256R1
7255
1.16k
    #endif
7256
1.16k
    #ifdef WOLFSSL_SP_SM2
7257
1.16k
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7258
881
    #endif
7259
881
    #ifdef WOLFSSL_SP_384
7260
881
         && ecc_sets[key->idx].id != ECC_SECP384R1
7261
558
    #endif
7262
558
    #ifdef WOLFSSL_SP_521
7263
558
         && ecc_sets[key->idx].id != ECC_SECP521R1
7264
1.50k
    #endif
7265
1.50k
        )) {
7266
0
        return WC_KEY_SIZE_E;
7267
0
    }
7268
1.50k
#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
1.50k
#if defined(WOLFSSL_HAVE_SP_ECC)
7299
1.50k
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7300
1.50k
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7301
1.50k
       return err;
7302
1.50k
   }
7303
#else
7304
   (void)inlen;
7305
#endif
7306
7307
#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
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7317
#ifdef MP_INT_SIZE_CHECK_NULL
7318
   if (e_lcl == NULL) {
7319
      return MEMORY_E;
7320
   }
7321
#endif
7322
   e = e_lcl;
7323
#endif
7324
7325
   /* get the hash and load it as a bignum into 'e' */
7326
   /* init the bignums */
7327
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7328
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7329
      return err;
7330
   }
7331
7332
   /* load curve info */
7333
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7334
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7335
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7336
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7337
    if (err == MP_OKAY)
7338
        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
   if (err == MP_OKAY) {
7358
       /* we may need to truncate if hash is longer than key size */
7359
       word32 orderBits = (word32)mp_count_bits(curve->order);
7360
7361
       /* truncate down to byte size, may be all that's needed */
7362
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7363
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7364
       err = mp_read_unsigned_bin(e, in, inlen);
7365
7366
       /* may still need bit truncation too */
7367
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7368
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7369
   }
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
   if (err == MP_OKAY) {
7449
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7450
7451
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7452
           err=MEMORY_E);
7453
       if (WC_VAR_OK(pubkey))
7454
       {
7455
       /* don't use async for key, since we don't support async return here */
7456
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7457
           if (err == MP_OKAY) {
7458
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7459
              wc_ecc_free(pubkey);
7460
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7461
           }
7462
       }
7463
   }
7464
7465
   mp_clear(e);
7466
   wc_ecc_curve_free(curve);
7467
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7468
   FREE_CURVE_SPECS();
7469
#endif /* !WOLFSSL_SP_MATH */
7470
7471
0
   return err;
7472
1.50k
}
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
690
{
7805
690
    int ret = MP_OKAY;
7806
690
    DECLARE_CURVE_SPECS(1);
7807
7808
690
    if (k == NULL || klen == 0 || key == NULL) {
7809
23
        return BAD_FUNC_ARG;
7810
23
    }
7811
7812
667
    ALLOC_CURVE_SPECS(1, ret);
7813
667
    if (ret == MP_OKAY) {
7814
657
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7815
657
    }
7816
7817
667
    if (ret != 0) {
7818
13
        FREE_CURVE_SPECS();
7819
13
        return ret;
7820
13
    }
7821
7822
654
#ifndef WOLFSSL_NO_MALLOC
7823
654
    if (key->sign_k == NULL) {
7824
654
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7825
654
                                                            DYNAMIC_TYPE_ECC);
7826
654
        if (key->sign_k) {
7827
644
            ret = mp_init(key->sign_k);
7828
644
        }
7829
10
        else {
7830
10
            ret = MEMORY_E;
7831
10
        }
7832
654
    }
7833
654
#endif
7834
7835
654
    if (ret == 0) {
7836
644
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7837
644
    }
7838
654
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7839
45
        ret = MP_VAL;
7840
45
    }
7841
#ifdef WOLFSSL_NO_MALLOC
7842
    if (ret == 0) {
7843
        key->sign_k_set = 1;
7844
    }
7845
#endif
7846
7847
654
    wc_ecc_curve_free(curve);
7848
654
    FREE_CURVE_SPECS();
7849
654
    return ret;
7850
667
}
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
{
7859
#ifndef WOLFSSL_ECC_CURVE_STATIC
7860
    if (curve->prime != NULL)
7861
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7862
    if (curve->Af != NULL)
7863
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7864
    if (curve->Bf != NULL)
7865
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7866
    if (curve->order != NULL)
7867
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7868
    if (curve->Gx != NULL)
7869
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7870
    if (curve->Gy != NULL)
7871
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7872
#endif
7873
7874
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7875
7876
    (void)heap;
7877
}
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
9.00k
{
7887
9.00k
    if (key == NULL) {
7888
3
        return 0;
7889
3
    }
7890
7891
9.00k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7892
9.00k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7893
9.00k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7894
9.00k
#ifndef WOLFSSL_NO_MALLOC
7895
9.00k
    if (key->sign_k != NULL)
7896
346
#endif
7897
346
    {
7898
346
        mp_forcezero(key->sign_k);
7899
346
        mp_free(key->sign_k);
7900
346
#ifndef WOLFSSL_NO_MALLOC
7901
346
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7902
346
#endif
7903
346
    }
7904
9.00k
#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
9.00k
    mp_clear(key->pubkey.x);
7948
9.00k
    mp_clear(key->pubkey.y);
7949
9.00k
    mp_clear(key->pubkey.z);
7950
7951
#ifdef ALT_ECC_SIZE
7952
    if (key->k)
7953
#endif
7954
9.00k
        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
#ifdef WOLFSSL_CUSTOM_CURVES
7967
    if (key->deallocSet && key->dp != NULL)
7968
        wc_ecc_free_curve(key->dp, key->heap);
7969
#endif
7970
7971
#ifdef WOLFSSL_CHECK_MEM_ZERO
7972
    wc_MemZero_Check(key, sizeof(ecc_key));
7973
#endif
7974
7975
9.00k
    return 0;
7976
9.00k
}
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
{
8008
    int err;
8009
8010
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8011
        /* A is infinity. */
8012
        err = wc_ecc_copy_point(B, R);
8013
    }
8014
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8015
        /* B is infinity. */
8016
        err = wc_ecc_copy_point(A, R);
8017
    }
8018
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8019
        /* x ordinattes the same. */
8020
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8021
            /* A = B */
8022
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8023
        }
8024
        else {
8025
            /* A = -B */
8026
            err = mp_set(R->x, 0);
8027
            if (err == MP_OKAY)
8028
                err = mp_set(R->y, 0);
8029
            if (err == MP_OKAY)
8030
                err = mp_set(R->z, 1);
8031
            if ((err == MP_OKAY) && (infinity != NULL))
8032
                *infinity = 1;
8033
        }
8034
    }
8035
    else {
8036
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8037
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8038
            /* When all zero then should have done a double */
8039
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8040
                if (mp_iszero(B->z)) {
8041
                    err = wc_ecc_copy_point(B, R);
8042
                    if (err == MP_OKAY) {
8043
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8044
                    }
8045
                    if (err == MP_OKAY) {
8046
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8047
                    }
8048
                }
8049
                else {
8050
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8051
                }
8052
            }
8053
            /* When only Z zero then result is infinity */
8054
            else {
8055
                err = mp_set(R->x, 0);
8056
                if (err == MP_OKAY)
8057
                    err = mp_set(R->y, 0);
8058
                if (err == MP_OKAY)
8059
                    err = mp_set(R->z, 1);
8060
                if ((err == MP_OKAY) && (infinity != NULL))
8061
                    *infinity = 1;
8062
            }
8063
        }
8064
    }
8065
8066
    return err;
8067
}
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
{
8077
    int err;
8078
8079
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8080
        /* P is infinity. */
8081
        err = wc_ecc_copy_point(P, R);
8082
    }
8083
    else {
8084
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8085
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8086
           err = mp_set(R->x, 0);
8087
           if (err == MP_OKAY)
8088
               err = mp_set(R->y, 0);
8089
           if (err == MP_OKAY)
8090
               err = mp_set(R->z, 1);
8091
        }
8092
    }
8093
8094
    return err;
8095
}
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
{
8110
    int err = MP_OKAY;
8111
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8112
8113
    (void)heap;
8114
8115
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8116
#ifdef MP_INT_SIZE_CHECK_NULL
8117
    if (mu == NULL)
8118
       err = MEMORY_E;
8119
#endif
8120
    if (err == MP_OKAY) {
8121
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8122
    }
8123
    if (err == MP_OKAY) {
8124
        err = mp_montgomery_calc_normalization(mu, modulus);
8125
8126
        if (err == MP_OKAY) {
8127
            /* copy ones ... */
8128
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8129
        }
8130
8131
        if (err == MP_OKAY)
8132
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8133
        if (err == MP_OKAY)
8134
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8135
8136
        if (err == MP_OKAY)
8137
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8138
        if (err == MP_OKAY)
8139
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8140
        if (err == MP_OKAY)
8141
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8142
8143
        /* done with mu */
8144
        mp_clear(mu);
8145
    }
8146
8147
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8148
8149
    return err;
8150
}
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
{
8174
#ifdef WOLFSSL_SMALL_STACK_CACHE
8175
  ecc_key        *key = NULL;
8176
#endif
8177
#ifdef WOLFSSL_SMALL_STACK
8178
  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
  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
  unsigned char* tA = NULL;
8191
  unsigned char* tB = NULL;
8192
#endif
8193
  int            err = MP_OKAY, first, x, y;
8194
  mp_digit       mp = 0;
8195
8196
  /* argchks */
8197
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8198
                                                         modulus == NULL) {
8199
     return ECC_BAD_ARG_E;
8200
  }
8201
8202
#ifndef WOLFSSL_NO_MALLOC
8203
  /* allocate memory */
8204
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8205
  if (tA == NULL) {
8206
     return MP_MEM;
8207
  }
8208
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8209
  if (tB == NULL) {
8210
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8211
     return MP_MEM;
8212
  }
8213
#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
#ifdef WOLFSSL_SMALL_STACK
8224
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8225
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8226
  if (precomp == NULL) {
8227
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8228
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8229
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8230
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8231
  #endif
8232
     return MP_MEM;
8233
  }
8234
#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
  XMEMSET(tA, 0, ECC_BUFSIZE);
8267
  XMEMSET(tB, 0, ECC_BUFSIZE);
8268
#ifndef WOLFSSL_SMALL_STACK
8269
  XMEMSET(precomp, 0, sizeof(precomp));
8270
#else
8271
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8272
#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
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8280
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8281
  len  = MAX(lenA, lenB);
8282
8283
  /* sanity check */
8284
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8285
    err = BAD_FUNC_ARG;
8286
  }
8287
8288
  if (err == MP_OKAY) {
8289
    /* extract and justify kA */
8290
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8291
8292
    /* extract and justify kB */
8293
    if (err == MP_OKAY)
8294
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8295
8296
    /* allocate the table */
8297
    if (err == MP_OKAY) {
8298
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8299
        #ifdef WOLFSSL_NO_MALLOC
8300
            precomp[x] = &lcl_precomp[x];
8301
        #endif
8302
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8303
            if (err != MP_OKAY)
8304
                break;
8305
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8306
            precomp[x]->key = key;
8307
        #endif
8308
        }
8309
    }
8310
  }
8311
8312
  if (err == MP_OKAY)
8313
    /* init montgomery reduction */
8314
    err = mp_montgomery_setup(modulus, &mp);
8315
8316
  if (err == MP_OKAY) {
8317
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8318
  }
8319
8320
  if (err == MP_OKAY) {
8321
    /* precomp [i,0](A + B) table */
8322
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8323
  }
8324
  if (err == MP_OKAY) {
8325
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8326
                                                          a, modulus, mp, NULL);
8327
  }
8328
8329
  if (err == MP_OKAY) {
8330
    /* precomp [0,i](A + B) table */
8331
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8332
  }
8333
  if (err == MP_OKAY) {
8334
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8335
                                                             modulus, mp, NULL);
8336
  }
8337
8338
  if (err == MP_OKAY) {
8339
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8340
    for (x = 1; x < 4; x++) {
8341
      for (y = 1; y < 4; y++) {
8342
        if (err == MP_OKAY) {
8343
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8344
                                                  precomp[x+(y<<2)], a, modulus,
8345
                                                  mp, NULL);
8346
        }
8347
      }
8348
    }
8349
  }
8350
8351
  if (err == MP_OKAY) {
8352
    nibble  = 3;
8353
    first   = 1;
8354
    bitbufA = tA[0];
8355
    bitbufB = tB[0];
8356
8357
    /* for every byte of the multiplicands */
8358
    for (x = 0; x < (int)len || nibble != 3; ) {
8359
        /* grab a nibble */
8360
        if (++nibble == 4) {
8361
            if (x == (int)len) break;
8362
            bitbufA = tA[x];
8363
            bitbufB = tB[x];
8364
            nibble  = 0;
8365
            x++;
8366
        }
8367
8368
        /* extract two bits from both, shift/update */
8369
        nA = (bitbufA >> 6) & 0x03;
8370
        nB = (bitbufB >> 6) & 0x03;
8371
        bitbufA = (bitbufA << 2) & 0xFF;
8372
        bitbufB = (bitbufB << 2) & 0xFF;
8373
8374
        /* if both zero, if first, continue */
8375
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8376
            continue;
8377
        }
8378
8379
        /* double twice, only if this isn't the first */
8380
        if (first == 0) {
8381
            /* double twice */
8382
            if (err == MP_OKAY)
8383
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8384
            if (err == MP_OKAY)
8385
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8386
            else
8387
                break;
8388
        }
8389
8390
        /* if not both zero */
8391
        if ((nA != 0) || (nB != 0)) {
8392
            unsigned int i = nA + (nB<<2);
8393
            if (first == 1) {
8394
                /* if first, copy from table */
8395
                first = 0;
8396
                if (err == MP_OKAY)
8397
                    err = mp_copy(precomp[i]->x, C->x);
8398
8399
                if (err == MP_OKAY)
8400
                    err = mp_copy(precomp[i]->y, C->y);
8401
8402
                if (err == MP_OKAY)
8403
                    err = mp_copy(precomp[i]->z, C->z);
8404
                else
8405
                    break;
8406
            } else {
8407
                /* if not first, add from table */
8408
                if (err == MP_OKAY)
8409
                    err = ecc_projective_add_point_safe(C, precomp[i],
8410
                                                        C, a, modulus, mp,
8411
                                                        &first);
8412
                if (err != MP_OKAY)
8413
                    break;
8414
            }
8415
        }
8416
    }
8417
  }
8418
8419
  /* reduce to affine */
8420
  if (err == MP_OKAY)
8421
    err = ecc_map(C, modulus, mp);
8422
8423
  /* clean up */
8424
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8425
     wc_ecc_del_point_ex(precomp[x], heap);
8426
  }
8427
8428
  ForceZero(tA, ECC_BUFSIZE);
8429
  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
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8442
#ifndef WOLFSSL_NO_MALLOC
8443
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8444
  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
  return err;
8450
}
8451
8452
#endif /* ECC_SHAMIR */
8453
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
8454
        * !WOLFSSL_CRYPTOCEL */
8455
8456
8457
#ifdef HAVE_ECC_VERIFY
8458
/* verify
8459
 *
8460
 * w  = s^-1 mod n
8461
 * u1 = xw
8462
 * u2 = rw
8463
 * X = u1*G + u2*Q
8464
 * v = X_x1 mod n
8465
 * accept if v == r
8466
 */
8467
8468
/**
8469
 Verify an ECC signature
8470
 sig         The signature to verify
8471
 siglen      The length of the signature (octets)
8472
 hash        The hash (message digest) that was signed
8473
 hashlen     The length of the hash (octets)
8474
 res         Result of signature, 1==valid, 0==invalid
8475
 key         The corresponding public ECC key
8476
 return      MP_OKAY if successful (even if the signature is not valid)
8477
             Caller should check the *res value to determine if the signature
8478
             is valid or invalid. Other negative values are returned on error.
8479
 */
8480
WOLFSSL_ABI
8481
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
8482
                       word32 hashlen, int* res, ecc_key* key)
8483
5.86k
{
8484
5.86k
    int err;
8485
8486
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8487
    mp_int *r = NULL, *s = NULL;
8488
#else
8489
5.86k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8490
5.86k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8491
5.86k
#endif
8492
#ifdef WOLFSSL_ASYNC_CRYPT
8493
    int isPrivateKeyOnly = 0;
8494
#endif
8495
#ifdef NO_ASN
8496
    word32 keySz;
8497
#endif
8498
8499
5.86k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8500
55
        return ECC_BAD_ARG_E;
8501
55
    }
8502
5.81k
    if (hashlen > WC_MAX_DIGEST_SIZE) {
8503
77
        return BAD_LENGTH_E;
8504
77
    }
8505
8506
5.73k
#ifdef WOLF_CRYPTO_CB
8507
5.73k
    #ifndef WOLF_CRYPTO_CB_FIND
8508
5.73k
    if (key->devId != INVALID_DEVID)
8509
0
    #endif
8510
0
    {
8511
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
8512
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8513
0
            return err;
8514
        /* fall-through when unavailable */
8515
0
    }
8516
5.73k
#endif
8517
8518
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
8519
    (void)siglen;
8520
    (void)hashlen;
8521
    (void)s;
8522
    (void)r;
8523
    (void)err;
8524
    return NO_VALID_DEVID;
8525
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
8526
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8527
    err = wc_ecc_alloc_async(key);
8528
    if (err != 0)
8529
        return err;
8530
    r = key->r;
8531
    s = key->s;
8532
#else
8533
5.73k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8534
5.73k
        DYNAMIC_TYPE_ECC);
8535
5.73k
    #ifdef MP_INT_SIZE_CHECK_NULL
8536
5.73k
    if (r == NULL)
8537
12
        return MEMORY_E;
8538
5.72k
    #endif
8539
5.72k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8540
5.72k
        DYNAMIC_TYPE_ECC);
8541
5.72k
    #ifdef MP_INT_SIZE_CHECK_NULL
8542
5.72k
    if (s == NULL) {
8543
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8544
5
        return MEMORY_E;
8545
5
    }
8546
5.71k
    #endif
8547
5.71k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8548
5.71k
    if (err != 0) {
8549
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8550
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8551
0
        return err;
8552
0
    }
8553
5.71k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8554
5.71k
    if (err != 0) {
8555
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8556
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8557
0
        return err;
8558
0
    }
8559
5.71k
#endif /* WOLFSSL_ASYNC_CRYPT */
8560
8561
5.71k
    switch (key->state) {
8562
5.71k
        case ECC_STATE_NONE:
8563
5.71k
        case ECC_STATE_VERIFY_DECODE:
8564
5.71k
            key->state = ECC_STATE_VERIFY_DECODE;
8565
8566
            /* default to invalid signature */
8567
5.71k
            *res = 0;
8568
8569
5.71k
    #ifndef NO_ASN
8570
            /* Decode ASN.1 ECDSA signature. */
8571
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8572
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
8573
             * If either of those don't allocate correctly, none of
8574
             * the rest of this function will execute, and everything
8575
             * gets cleaned up at the end. */
8576
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
8577
        #else
8578
            /* r and s are initialized. */
8579
5.71k
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8580
5.71k
        #endif
8581
5.71k
            if (err < 0) {
8582
62
                break;
8583
62
            }
8584
    #else
8585
            /* No support for DSA ASN.1 header.
8586
             * Signature must be r+s directly. */
8587
            keySz = 0;
8588
            if (key->dp != NULL) {
8589
                keySz = (word32)key->dp->size;
8590
            }
8591
            if (siglen != keySz * 2) {
8592
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
8593
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
8594
            }
8595
8596
            /* Import signature into r,s */
8597
            mp_init(r);
8598
            mp_init(s);
8599
            mp_read_unsigned_bin(r, sig, keySz);
8600
            mp_read_unsigned_bin(s, sig + keySz, keySz);
8601
    #endif /* !NO_ASN */
8602
5.65k
            FALL_THROUGH;
8603
8604
5.65k
        case ECC_STATE_VERIFY_DO:
8605
5.65k
            key->state = ECC_STATE_VERIFY_DO;
8606
        #ifdef WOLFSSL_ASYNC_CRYPT
8607
            if (key->type == ECC_PRIVATEKEY_ONLY) {
8608
                isPrivateKeyOnly = 1;
8609
            }
8610
        #endif
8611
5.65k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8612
8613
5.65k
        #ifndef WOLFSSL_ASYNC_CRYPT
8614
            /* done with R/S */
8615
5.65k
            mp_clear(r);
8616
5.65k
            mp_clear(s);
8617
5.65k
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8618
5.65k
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8619
5.65k
        #ifdef MP_INT_SIZE_CHECK_NULL
8620
5.65k
            r = NULL;
8621
5.65k
            s = NULL;
8622
5.65k
        #endif
8623
5.65k
        #endif
8624
8625
5.65k
            if (err < 0) {
8626
211
                break;
8627
211
            }
8628
5.44k
            FALL_THROUGH;
8629
8630
5.44k
        case ECC_STATE_VERIFY_RES:
8631
5.44k
            key->state = ECC_STATE_VERIFY_RES;
8632
5.44k
            err = 0;
8633
5.44k
            break;
8634
8635
0
        default:
8636
0
            err = BAD_STATE_E;
8637
5.71k
    }
8638
8639
#ifdef WOLFSSL_ASYNC_CRYPT
8640
    /* if async pending then return and skip done cleanup below */
8641
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8642
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
8643
            key->state++;
8644
        return err;
8645
    }
8646
#endif
8647
8648
    /* cleanup */
8649
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8650
    wc_ecc_free_async(key);
8651
#else
8652
5.71k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8653
5.71k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8654
5.71k
#endif
8655
8656
    /* make sure required variables are reset */
8657
5.71k
    wc_ecc_reset(key);
8658
5.71k
    return err;
8659
5.71k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8660
5.71k
}
8661
8662
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
8663
8664
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
8665
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8666
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
8667
2.92k
{
8668
2.92k
    int err = MP_OKAY;
8669
2.92k
    DECLARE_CURVE_SPECS(1);
8670
8671
2.92k
    ALLOC_CURVE_SPECS(1, err);
8672
2.92k
    if (err == MP_OKAY) {
8673
2.92k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8674
2.92k
    }
8675
2.92k
    if (err != 0) {
8676
4
        FREE_CURVE_SPECS();
8677
4
        return err;
8678
4
    }
8679
8680
2.92k
    if (mp_iszero(r) || mp_iszero(s)) {
8681
0
        err = MP_ZERO_E;
8682
0
    }
8683
2.92k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8684
7
        err = MP_VAL;
8685
7
    }
8686
2.92k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8687
10
        err = MP_VAL;
8688
10
    }
8689
8690
2.92k
    wc_ecc_curve_free(curve);
8691
2.92k
    FREE_CURVE_SPECS();
8692
2.92k
    return err;
8693
2.92k
}
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
2.90k
{
8700
2.90k
    (void)r;
8701
2.90k
    (void)s;
8702
2.90k
    (void)hash;
8703
2.90k
    (void)hashlen;
8704
2.90k
    (void)res;
8705
2.90k
    (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
2.90k
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
8719
2.90k
    if (key->idx == ECC_CUSTOM_IDX || (1
8720
2.90k
    #ifndef WOLFSSL_SP_NO_256
8721
2.90k
         && ecc_sets[key->idx].id != ECC_SECP256R1
8722
2.23k
    #endif
8723
2.23k
    #ifdef WOLFSSL_SP_SM2
8724
2.23k
         && ecc_sets[key->idx].id != ECC_SM2P256V1
8725
1.71k
    #endif
8726
1.71k
    #ifdef WOLFSSL_SP_384
8727
1.71k
         && ecc_sets[key->idx].id != ECC_SECP384R1
8728
1.07k
    #endif
8729
1.07k
    #ifdef WOLFSSL_SP_521
8730
1.07k
         && ecc_sets[key->idx].id != ECC_SECP521R1
8731
2.90k
    #endif
8732
2.90k
        )) {
8733
0
        return WC_KEY_SIZE_E;
8734
0
    }
8735
2.90k
#endif
8736
8737
2.90k
#if defined(WOLFSSL_HAVE_SP_ECC)
8738
2.90k
    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
2.90k
    #ifndef WOLFSSL_SP_NO_256
8747
2.90k
        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
668
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8764
668
            {
8765
668
                int ret;
8766
668
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8767
668
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
8768
668
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8769
668
                RESTORE_VECTOR_REGISTERS();
8770
668
                return ret;
8771
668
            }
8772
668
        #endif
8773
668
        }
8774
2.23k
    #endif
8775
2.23k
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
8776
2.23k
        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
518
            #if !defined(FP_ECC_CONTROL)
8785
518
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
8786
518
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8787
518
            #endif
8788
518
        }
8789
1.71k
    #endif
8790
1.71k
    #ifdef WOLFSSL_SP_384
8791
1.71k
        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
643
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8808
643
            {
8809
643
                int ret;
8810
643
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8811
643
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
8812
643
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8813
643
                RESTORE_VECTOR_REGISTERS();
8814
643
                return ret;
8815
643
            }
8816
643
        #endif
8817
643
        }
8818
1.07k
    #endif
8819
1.07k
    #ifdef WOLFSSL_SP_521
8820
1.07k
        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
1.07k
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8837
1.07k
            {
8838
1.07k
                int ret;
8839
1.07k
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8840
1.07k
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
8841
1.07k
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8842
1.07k
                RESTORE_VECTOR_REGISTERS();
8843
1.07k
                return ret;
8844
1.07k
            }
8845
1.07k
        #endif
8846
1.07k
        }
8847
1.07k
    #endif
8848
1.07k
    }
8849
0
#endif
8850
8851
0
    return NOT_COMPILED_IN;
8852
2.90k
}
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
{
8858
   int        err;
8859
   ecc_point* mG = NULL;
8860
   ecc_point* mQ = NULL;
8861
#ifdef WOLFSSL_NO_MALLOC
8862
   ecc_point  lcl_mG;
8863
   ecc_point  lcl_mQ;
8864
#endif
8865
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8866
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8867
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8868
#endif
8869
   mp_int*    e;
8870
   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
   mp_int*    u1 = NULL;     /* Will be e. */
8876
   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
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8887
#ifdef MP_INT_SIZE_CHECK_NULL
8888
   if (e_lcl == NULL) {
8889
       return MEMORY_E;
8890
   }
8891
#endif
8892
   e = e_lcl;
8893
8894
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8895
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8896
   if (err != MP_OKAY) {
8897
#ifdef WOLFSSL_SMALL_STACK
8898
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8899
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8900
   #endif
8901
#endif
8902
      return MEMORY_E;
8903
   }
8904
8905
   /* read hash */
8906
   if (err == MP_OKAY) {
8907
       /* we may need to truncate if hash is longer than key size */
8908
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
8909
8910
       /* truncate down to byte size, may be all that's needed */
8911
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8912
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8913
       err = mp_read_unsigned_bin(e, hash, hashlen);
8914
8915
       /* may still need bit truncation too */
8916
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8917
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8918
   }
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
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8957
#ifdef MP_INT_SIZE_CHECK_NULL
8958
   if (w == NULL) {
8959
       err = MEMORY_E;
8960
   }
8961
#endif
8962
8963
   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
       u1 = e;
8976
       u2 = w;
8977
#endif
8978
       v = w;
8979
   }
8980
   if (err == MP_OKAY) {
8981
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8982
   }
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
   if (err == MP_OKAY) {
8994
   #ifdef WOLFSSL_NO_MALLOC
8995
       mG = &lcl_mG;
8996
   #endif
8997
       err = wc_ecc_new_point_ex(&mG, key->heap);
8998
   }
8999
   if (err == MP_OKAY) {
9000
   #ifdef WOLFSSL_NO_MALLOC
9001
       mQ = &lcl_mQ;
9002
   #endif
9003
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9004
   }
9005
9006
   /*  w  = s^-1 mod n */
9007
   if (err == MP_OKAY)
9008
       err = mp_invmod(s, curve->order, w);
9009
9010
   /* u1 = ew */
9011
   if (err == MP_OKAY)
9012
       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
   if (err == MP_OKAY)
9022
       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
   if (err == MP_OKAY)
9032
       err = mp_copy(curve->Gx, mG->x);
9033
   if (err == MP_OKAY)
9034
       err = mp_copy(curve->Gy, mG->y);
9035
   if (err == MP_OKAY)
9036
       err = mp_set(mG->z, 1);
9037
9038
   if (err == MP_OKAY)
9039
       err = mp_copy(key->pubkey.x, mQ->x);
9040
   if (err == MP_OKAY)
9041
       err = mp_copy(key->pubkey.y, mQ->y);
9042
   if (err == MP_OKAY)
9043
       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
    if (err == MP_OKAY) {
9120
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9121
                                                                     key->heap);
9122
    }
9123
#endif /* ECC_SHAMIR */
9124
#endif /* FREESCALE_LTC_ECC */
9125
9126
   /* v = X_x1 mod n */
9127
   if (err == MP_OKAY)
9128
       err = mp_mod(mG->x, curve->order, v);
9129
9130
   /* does v == r */
9131
   if (err == MP_OKAY) {
9132
       if (mp_cmp(v, r) == MP_EQ)
9133
           *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
   }
9140
9141
   /* cleanup */
9142
   wc_ecc_del_point_ex(mG, key->heap);
9143
   wc_ecc_del_point_ex(mQ, key->heap);
9144
9145
   mp_clear(e);
9146
   mp_clear(w);
9147
   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
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9157
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9158
#endif
9159
9160
   return err;
9161
}
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
2.92k
{
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
2.92k
   int           err;
9186
2.92k
   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
2.92k
   int curveLoaded = 0;
9204
2.92k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9205
2.92k
#endif
9206
9207
2.92k
   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
2.92k
   *res = 0;
9212
9213
   /* is the IDX valid ?  */
9214
2.92k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9215
0
      return ECC_BAD_ARG_E;
9216
0
   }
9217
9218
2.92k
   err = wc_ecc_check_r_s_range(key, r, s);
9219
2.92k
   if (err != MP_OKAY) {
9220
21
      return err;
9221
21
   }
9222
9223
2.90k
   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
2.90k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9338
1.37k
      WOLFSSL_MSG("Verify called with private key, generating public part");
9339
1.37k
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9340
1.37k
      if (err != MP_OKAY) {
9341
1
          return err;
9342
1
      }
9343
1.37k
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9344
1.37k
      if (err != MP_OKAY) {
9345
0
          FREE_CURVE_SPECS();
9346
0
          return err;
9347
0
      }
9348
1.37k
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9349
1.37k
      if (err != MP_OKAY) {
9350
5
           WOLFSSL_MSG("Unable to extract public key");
9351
5
           wc_ecc_curve_free(curve);
9352
5
           FREE_CURVE_SPECS();
9353
5
           return err;
9354
5
      }
9355
1.37k
      curveLoaded = 1;
9356
1.37k
  }
9357
9358
2.90k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9359
2.90k
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
9360
2.90k
      if (curveLoaded) {
9361
1.37k
           wc_ecc_curve_free(curve);
9362
1.37k
           FREE_CURVE_SPECS();
9363
1.37k
      }
9364
2.90k
      return err;
9365
2.90k
  }
9366
9367
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9368
   if (!curveLoaded) {
9369
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9370
       if (err != 0) {
9371
          return err;
9372
       }
9373
       /* read in the specs for this curve */
9374
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9375
       if (err != 0) {
9376
          FREE_CURVE_SPECS();
9377
          return err;
9378
       }
9379
   }
9380
9381
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9382
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9383
9384
0
   (void)curveLoaded;
9385
0
   wc_ecc_curve_free(curve);
9386
0
   FREE_CURVE_SPECS();
9387
0
#endif /* HAVE_ECC_VERIFY_HELPER */
9388
9389
0
   (void)keySz;
9390
0
   (void)hashlen;
9391
9392
0
   return err;
9393
2.90k
#endif /* WOLFSSL_STM32_PKA */
9394
2.90k
}
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
21
{
9405
21
    int err = 0;
9406
21
#ifdef HAVE_COMP_KEY
9407
21
    int compressed = 0;
9408
21
#endif
9409
21
    int keysize;
9410
21
    byte pointType;
9411
9412
#ifndef HAVE_COMP_KEY
9413
    (void)shortKeySize;
9414
#endif
9415
9416
21
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9417
21
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9418
0
        return ECC_BAD_ARG_E;
9419
9420
    /* must be odd */
9421
21
    if ((inLen & 1) == 0) {
9422
0
        return ECC_BAD_ARG_E;
9423
0
    }
9424
9425
    /* clear if previously allocated */
9426
21
    mp_clear(point->x);
9427
21
    mp_clear(point->y);
9428
21
    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
21
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9440
21
#endif
9441
21
    if (err != MP_OKAY)
9442
0
        return MEMORY_E;
9443
9444
21
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9445
9446
    /* check for point type (4, 2, or 3) */
9447
21
    pointType = in[0];
9448
21
    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
21
    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
21
    inLen -= 1;
9463
21
    in += 1;
9464
9465
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9466
     * is true */
9467
21
#ifdef HAVE_COMP_KEY
9468
21
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9469
#else
9470
    keysize = (int)(inLen>>1);
9471
#endif
9472
9473
    /* read data */
9474
21
    if (err == MP_OKAY)
9475
21
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9476
9477
21
#ifdef HAVE_COMP_KEY
9478
21
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9479
0
    #if defined(WOLFSSL_HAVE_SP_ECC)
9480
0
        #ifndef WOLFSSL_SP_NO_256
9481
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9482
0
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
9483
0
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
9484
0
        }
9485
0
        else
9486
0
        #endif
9487
0
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9488
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9489
0
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
9490
0
            sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
9491
0
        }
9492
0
        else
9493
0
        #endif
9494
0
        #ifdef WOLFSSL_SP_384
9495
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9496
0
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
9497
0
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
9498
0
        }
9499
0
        else
9500
0
        #endif
9501
0
        #ifdef WOLFSSL_SP_521
9502
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9503
0
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
9504
0
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
9505
0
        }
9506
0
        else
9507
0
        #endif
9508
0
    #endif
9509
    #if !defined(WOLFSSL_SP_MATH)
9510
        {
9511
            int did_init = 0;
9512
        #ifdef WOLFSSL_SMALL_STACK
9513
            mp_int* t1 = NULL;
9514
            mp_int* t2 = NULL;
9515
        #else
9516
            mp_int t1[1], t2[1];
9517
        #endif
9518
            DECLARE_CURVE_SPECS(3);
9519
9520
            ALLOC_CURVE_SPECS(3, err);
9521
9522
        #ifdef WOLFSSL_SMALL_STACK
9523
            if (err == MP_OKAY) {
9524
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9525
                                      DYNAMIC_TYPE_BIGINT);
9526
                if (t1 == NULL) {
9527
                    err = MEMORY_E;
9528
                }
9529
            }
9530
            if (err == MP_OKAY) {
9531
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9532
                                      DYNAMIC_TYPE_BIGINT);
9533
                if (t2 == NULL) {
9534
                    err = MEMORY_E;
9535
                }
9536
            }
9537
        #endif
9538
9539
            if (err == MP_OKAY) {
9540
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9541
                    err = MEMORY_E;
9542
                else
9543
                    did_init = 1;
9544
            }
9545
9546
            /* load curve info */
9547
            if (err == MP_OKAY)
9548
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9549
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9550
                        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
            if (err == MP_OKAY)
9565
                err = mp_sqr(point->x, t1);
9566
            if (err == MP_OKAY)
9567
                err = mp_mulmod(t1, point->x, curve->prime, t1);
9568
9569
            /* compute x^3 + a*x */
9570
            if (err == MP_OKAY)
9571
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
9572
            if (err == MP_OKAY)
9573
                err = mp_add(t1, t2, t1);
9574
9575
            /* compute x^3 + a*x + b */
9576
            if (err == MP_OKAY)
9577
                err = mp_add(t1, curve->Bf, t1);
9578
9579
            /* compute sqrt(x^3 + a*x + b) */
9580
            if (err == MP_OKAY)
9581
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
9582
9583
            /* adjust y */
9584
            if (err == MP_OKAY) {
9585
                if ((mp_isodd(t2) == MP_YES &&
9586
                                            pointType == ECC_POINT_COMP_ODD) ||
9587
                    (mp_isodd(t2) == MP_NO &&
9588
                                            pointType == ECC_POINT_COMP_EVEN)) {
9589
                    err = mp_mod(t2, curve->prime, point->y);
9590
                }
9591
                else {
9592
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
9593
                }
9594
            }
9595
9596
            if (did_init) {
9597
                mp_clear(t2);
9598
                mp_clear(t1);
9599
            }
9600
9601
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
9602
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
9603
9604
            wc_ecc_curve_free(curve);
9605
            FREE_CURVE_SPECS();
9606
        }
9607
    #else
9608
0
        {
9609
0
            err = WC_KEY_SIZE_E;
9610
0
        }
9611
0
    #endif
9612
0
    }
9613
21
#endif
9614
9615
21
    if (err == MP_OKAY) {
9616
21
#ifdef HAVE_COMP_KEY
9617
21
        if (compressed == 0)
9618
21
#endif
9619
21
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9620
21
    }
9621
21
    if (err == MP_OKAY)
9622
21
        err = mp_set(point->z, 1);
9623
9624
21
    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
21
    RESTORE_VECTOR_REGISTERS();
9631
9632
21
    return err;
9633
21
}
9634
9635
/* function for backwards compatibility with previous implementations */
9636
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
9637
                            ecc_point* point)
9638
124
{
9639
124
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9640
124
}
9641
#endif /* HAVE_ECC_KEY_IMPORT */
9642
9643
#ifdef HAVE_ECC_KEY_EXPORT
9644
/* export point to der */
9645
9646
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
9647
                               word32* outLen, int compressed)
9648
0
{
9649
0
    if (compressed == 0)
9650
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
9651
0
#ifdef HAVE_COMP_KEY
9652
0
    else
9653
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
9654
#else
9655
    return NOT_COMPILED_IN;
9656
#endif
9657
0
}
9658
9659
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
9660
                            word32* outLen)
9661
348
{
9662
348
    int    ret = MP_OKAY;
9663
348
    word32 numlen;
9664
348
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9665
9666
348
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9667
0
        return ECC_BAD_ARG_E;
9668
9669
348
    numlen = (word32)ecc_sets[curve_idx].size;
9670
9671
    /* return length needed only */
9672
348
    if (point != NULL && out == NULL && outLen != NULL) {
9673
28
        *outLen = 1 + 2*numlen;
9674
28
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9675
28
    }
9676
9677
320
    if (point == NULL || out == NULL || outLen == NULL)
9678
0
        return ECC_BAD_ARG_E;
9679
9680
320
    if (*outLen < (1 + 2*numlen)) {
9681
17
        *outLen = 1 + 2*numlen;
9682
17
        return BUFFER_E;
9683
17
    }
9684
9685
    /* Sanity check the ordinates' sizes. */
9686
303
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9687
272
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9688
83
        return ECC_BAD_ARG_E;
9689
83
    }
9690
9691
    /* store byte point type */
9692
220
    out[0] = ECC_POINT_UNCOMP;
9693
9694
220
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9695
220
        return MEMORY_E);
9696
9697
    /* pad and store x */
9698
140
    XMEMSET(buf, 0, ECC_BUFSIZE);
9699
140
    ret = mp_to_unsigned_bin(point->x, buf +
9700
140
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9701
140
    if (ret != MP_OKAY)
9702
8
        goto done;
9703
132
    XMEMCPY(out+1, buf, numlen);
9704
9705
    /* pad and store y */
9706
132
    XMEMSET(buf, 0, ECC_BUFSIZE);
9707
132
    ret = mp_to_unsigned_bin(point->y, buf +
9708
132
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9709
132
    if (ret != MP_OKAY)
9710
8
        goto done;
9711
124
    XMEMCPY(out+1+numlen, buf, numlen);
9712
9713
124
    *outLen = 1 + 2*numlen;
9714
9715
140
done:
9716
140
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9717
9718
140
    return ret;
9719
124
}
9720
9721
9722
/* export point to der */
9723
#ifdef HAVE_COMP_KEY
9724
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
9725
                                       byte* out, word32* outLen)
9726
0
{
9727
0
    int    ret = MP_OKAY;
9728
0
    word32 numlen;
9729
0
    word32 output_len;
9730
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9731
9732
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9733
0
        return ECC_BAD_ARG_E;
9734
9735
0
    numlen = (word32)ecc_sets[curve_idx].size;
9736
0
    output_len = 1 + numlen; /* y point type + x */
9737
9738
    /* return length needed only */
9739
0
    if (point != NULL && out == NULL && outLen != NULL) {
9740
0
        *outLen = output_len;
9741
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9742
0
    }
9743
9744
0
    if (point == NULL || out == NULL || outLen == NULL)
9745
0
        return ECC_BAD_ARG_E;
9746
9747
9748
0
    if (*outLen < output_len) {
9749
0
        *outLen = output_len;
9750
0
        return BUFFER_E;
9751
0
    }
9752
9753
    /* Sanity check the ordinate's size. */
9754
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
9755
0
        return ECC_BAD_ARG_E;
9756
0
    }
9757
9758
    /* store byte point type */
9759
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
9760
0
                                            ECC_POINT_COMP_EVEN;
9761
9762
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9763
0
        return MEMORY_E);
9764
9765
    /* pad and store x */
9766
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9767
0
    ret = mp_to_unsigned_bin(point->x, buf +
9768
0
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
9769
0
    if (ret != MP_OKAY)
9770
0
        goto done;
9771
0
    XMEMCPY(out+1, buf, numlen);
9772
9773
0
    *outLen = output_len;
9774
9775
0
done:
9776
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9777
9778
0
    return ret;
9779
0
}
9780
#endif /* HAVE_COMP_KEY */
9781
9782
/* export public ECC key in ANSI X9.63 format */
9783
WOLFSSL_ABI
9784
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
9785
12.7k
{
9786
12.7k
   int    ret = MP_OKAY;
9787
12.7k
   word32 numlen;
9788
12.7k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9789
12.7k
   word32 pubxlen, pubylen;
9790
9791
   /* return length needed only */
9792
12.7k
   if (key != NULL && out == NULL && outLen != NULL) {
9793
      /* if key hasn't been setup assume max bytes for size estimation */
9794
1.91k
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9795
1.91k
      *outLen = 1 + 2 * numlen;
9796
1.91k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9797
1.91k
   }
9798
9799
10.7k
   if (key == NULL || out == NULL || outLen == NULL)
9800
0
      return ECC_BAD_ARG_E;
9801
9802
10.7k
   if (key->type == ECC_PRIVATEKEY_ONLY)
9803
158
       return ECC_PRIVATEONLY_E;
9804
9805
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
9806
    /* check if public key in secure memory */
9807
    if (key->securePubKey > 0) {
9808
        int keySz = wc_ecc_size(key);
9809
9810
        /* store byte point type */
9811
        out[0] = ECC_POINT_UNCOMP;
9812
9813
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
9814
            return WC_HW_E;
9815
9816
        *outLen = 1 + 2*keySz;
9817
        return MP_OKAY;
9818
    }
9819
#endif
9820
9821
10.6k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9822
1.28k
       return ECC_BAD_ARG_E;
9823
1.28k
   }
9824
9825
9.35k
   numlen = (word32)key->dp->size;
9826
9827
    /* verify room in out buffer */
9828
9.35k
   if (*outLen < (1 + 2*numlen)) {
9829
0
      *outLen = 1 + 2*numlen;
9830
0
      return BUFFER_E;
9831
0
   }
9832
9833
   /* verify public key length is less than key size */
9834
9.35k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9835
9.35k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9836
9.35k
   if ((pubxlen > numlen) || (pubylen > numlen)) {
9837
0
      WOLFSSL_MSG("Public key x/y invalid!");
9838
0
      return BUFFER_E;
9839
0
   }
9840
9841
   /* store byte point type */
9842
9.35k
   out[0] = ECC_POINT_UNCOMP;
9843
9844
9.35k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9845
9.35k
       return MEMORY_E);
9846
9847
   /* pad and store x */
9848
9.28k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9849
9.28k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9850
9.28k
   if (ret != MP_OKAY)
9851
7
      goto done;
9852
9.27k
   XMEMCPY(out+1, buf, numlen);
9853
9854
   /* pad and store y */
9855
9.27k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9856
9.27k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9857
9.27k
   if (ret != MP_OKAY)
9858
10
      goto done;
9859
9.26k
   XMEMCPY(out+1+numlen, buf, numlen);
9860
9861
9.26k
   *outLen = 1 + 2*numlen;
9862
9863
9.28k
done:
9864
9.28k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9865
9866
9.28k
   return ret;
9867
9.26k
}
9868
9869
9870
/* export public ECC key in ANSI X9.63 format, extended with
9871
 * compression option */
9872
WOLFSSL_ABI
9873
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
9874
                          int compressed)
9875
7.56k
{
9876
7.56k
    if (compressed == 0)
9877
4.03k
        return wc_ecc_export_x963(key, out, outLen);
9878
3.52k
#ifdef HAVE_COMP_KEY
9879
3.52k
    else
9880
3.52k
        return wc_ecc_export_x963_compressed(key, out, outLen);
9881
#else
9882
    return NOT_COMPILED_IN;
9883
#endif
9884
7.56k
}
9885
#endif /* HAVE_ECC_KEY_EXPORT */
9886
9887
9888
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
9889
9890
/* is ecc point on curve described by dp ? */
9891
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
9892
2.70k
{
9893
#if !defined(WOLFSSL_SP_MATH)
9894
   int err;
9895
#ifdef WOLFSSL_SMALL_STACK
9896
   mp_int* t1;
9897
   mp_int* t2;
9898
#else
9899
   mp_int  t1[1], t2[1];
9900
#endif
9901
9902
#ifdef WOLFSSL_SMALL_STACK
9903
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9904
   if (t1 == NULL)
9905
       return MEMORY_E;
9906
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9907
   if (t2 == NULL) {
9908
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9909
       return MEMORY_E;
9910
   }
9911
#endif
9912
9913
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
9914
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9915
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9916
      return err;
9917
   }
9918
9919
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9920
9921
   /* compute y^2 */
9922
   if (err == MP_OKAY)
9923
       err = mp_sqr(ecp->y, t1);
9924
9925
   /* compute x^3 */
9926
   if (err == MP_OKAY)
9927
       err = mp_sqr(ecp->x, t2);
9928
   if (err == MP_OKAY)
9929
       err = mp_mod(t2, prime, t2);
9930
   if (err == MP_OKAY)
9931
       err = mp_mul(ecp->x, t2, t2);
9932
9933
   /* compute y^2 - x^3 */
9934
   if (err == MP_OKAY)
9935
       err = mp_submod(t1, t2, prime, t1);
9936
9937
   /* Determine if curve "a" should be used in calc */
9938
#ifdef WOLFSSL_CUSTOM_CURVES
9939
   if (err == MP_OKAY) {
9940
      /* Use a and prime to determine if a == 3 */
9941
      err = mp_set(t2, 0);
9942
      if (err == MP_OKAY)
9943
          err = mp_submod(prime, a, prime, t2);
9944
   }
9945
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
9946
      /* compute y^2 - x^3 + a*x */
9947
      if (err == MP_OKAY)
9948
          err = mp_mulmod(t2, ecp->x, prime, t2);
9949
      if (err == MP_OKAY)
9950
          err = mp_addmod(t1, t2, prime, t1);
9951
   }
9952
   else
9953
#endif /* WOLFSSL_CUSTOM_CURVES */
9954
   {
9955
      /* assumes "a" == 3 */
9956
      (void)a;
9957
9958
      /* compute y^2 - x^3 + 3x */
9959
      if (err == MP_OKAY)
9960
          err = mp_add(t1, ecp->x, t1);
9961
      if (err == MP_OKAY)
9962
          err = mp_add(t1, ecp->x, t1);
9963
      if (err == MP_OKAY)
9964
          err = mp_add(t1, ecp->x, t1);
9965
      if (err == MP_OKAY)
9966
          err = mp_mod(t1, prime, t1);
9967
  }
9968
9969
   /* adjust range (0, prime) */
9970
   while (err == MP_OKAY && mp_isneg(t1)) {
9971
      err = mp_add(t1, prime, t1);
9972
   }
9973
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
9974
      err = mp_sub(t1, prime, t1);
9975
   }
9976
9977
   /* compare to b */
9978
   if (err == MP_OKAY) {
9979
       if (mp_cmp(t1, b) != MP_EQ) {
9980
          err = IS_POINT_E;
9981
       } else {
9982
          err = MP_OKAY;
9983
       }
9984
   }
9985
9986
   mp_clear(t1);
9987
   mp_clear(t2);
9988
9989
   RESTORE_VECTOR_REGISTERS();
9990
9991
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9992
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9993
9994
   return err;
9995
#else
9996
2.70k
   (void)a;
9997
2.70k
   (void)b;
9998
9999
2.70k
#ifdef WOLFSSL_HAVE_SP_ECC
10000
2.70k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10001
2.70k
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10002
572
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10003
572
   }
10004
2.13k
#endif
10005
2.13k
#ifndef WOLFSSL_SP_NO_256
10006
2.13k
   if (mp_count_bits(prime) == 256) {
10007
702
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10008
702
   }
10009
1.43k
#endif
10010
1.43k
#ifdef WOLFSSL_SP_384
10011
1.43k
   if (mp_count_bits(prime) == 384) {
10012
687
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10013
687
   }
10014
747
#endif
10015
747
#ifdef WOLFSSL_SP_521
10016
747
   if (mp_count_bits(prime) == 521) {
10017
747
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10018
747
   }
10019
0
#endif
10020
#else
10021
   (void)ecp;
10022
   (void)prime;
10023
#endif
10024
0
   return WC_KEY_SIZE_E;
10025
747
#endif
10026
747
}
10027
10028
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10029
5.22k
{
10030
5.22k
    int err = MP_OKAY;
10031
10032
    /* Validate parameters. */
10033
5.22k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10034
0
        err = BAD_FUNC_ARG;
10035
0
    }
10036
10037
5.22k
    if (err == MP_OKAY) {
10038
        /* x must be in the range [0, p-1] */
10039
5.22k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10040
147
            err = ECC_OUT_OF_RANGE_E;
10041
147
        }
10042
5.22k
    }
10043
10044
5.22k
    if (err == MP_OKAY) {
10045
        /* y must be in the range [0, p-1] */
10046
5.07k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10047
155
            err = ECC_OUT_OF_RANGE_E;
10048
155
        }
10049
5.07k
    }
10050
10051
5.22k
    if (err == MP_OKAY) {
10052
        /* z must be one, that is point must be in affine form. */
10053
4.92k
        if (!mp_isone(ecp->z)) {
10054
1.04k
            err = ECC_BAD_ARG_E;
10055
1.04k
        }
10056
4.92k
    }
10057
10058
5.22k
    if (err == MP_OKAY) {
10059
        /* Check x and y are valid for curve equation. */
10060
3.88k
        err = _ecc_is_point(ecp, a, b, prime);
10061
3.88k
    }
10062
10063
5.22k
    return err;
10064
5.22k
}
10065
10066
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10067
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10068
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10069
/* validate privkey * generator == pubkey, 0 on success */
10070
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10071
{
10072
    int        err;
10073
    ecc_point* base = NULL;
10074
    ecc_point* res  = NULL;
10075
#ifdef WOLFSSL_NO_MALLOC
10076
    ecc_point lcl_base;
10077
    ecc_point lcl_res;
10078
#endif
10079
    DECLARE_CURVE_SPECS(3);
10080
10081
    if (key == NULL)
10082
        return BAD_FUNC_ARG;
10083
10084
    ALLOC_CURVE_SPECS(3, err);
10085
    if (err != MP_OKAY) {
10086
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10087
        return err;
10088
    }
10089
10090
#ifdef WOLFSSL_NO_MALLOC
10091
    res = &lcl_res;
10092
#endif
10093
    err = wc_ecc_new_point_ex(&res, key->heap);
10094
10095
#ifdef WOLFSSL_HAVE_SP_ECC
10096
#ifndef WOLFSSL_SP_NO_256
10097
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10098
        if (err == MP_OKAY) {
10099
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10100
        }
10101
    }
10102
    else
10103
#endif
10104
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10105
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10106
        if (err == MP_OKAY) {
10107
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10108
        }
10109
    }
10110
    else
10111
#endif
10112
#ifdef WOLFSSL_SP_384
10113
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10114
        if (err == MP_OKAY) {
10115
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10116
        }
10117
    }
10118
    else
10119
#endif
10120
#ifdef WOLFSSL_SP_521
10121
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10122
        if (err == MP_OKAY) {
10123
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10124
        }
10125
    }
10126
    else
10127
#endif
10128
#endif
10129
    {
10130
        if (err == MP_OKAY) {
10131
        #ifdef WOLFSSL_NO_MALLOC
10132
            base = &lcl_base;
10133
        #endif
10134
            err = wc_ecc_new_point_ex(&base, key->heap);
10135
        }
10136
10137
        if (err == MP_OKAY) {
10138
            /* load curve info */
10139
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10140
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10141
        }
10142
10143
        /* set up base generator */
10144
        if (err == MP_OKAY)
10145
            err = mp_copy(curve->Gx, base->x);
10146
        if (err == MP_OKAY)
10147
            err = mp_copy(curve->Gy, base->y);
10148
        if (err == MP_OKAY)
10149
            err = mp_set(base->z, 1);
10150
10151
#ifdef WOLFSSL_KCAPI_ECC
10152
        if (err == MP_OKAY) {
10153
            word32 pubkey_sz = (word32)key->dp->size*2;
10154
            if (key->handle == NULL) {
10155
                /* if handle loaded, then pubkey_raw already populated */
10156
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10157
            }
10158
            if (err == 0) {
10159
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10160
                                           pubkey_sz/2);
10161
            }
10162
            if (err == MP_OKAY) {
10163
                err = mp_read_unsigned_bin(res->y,
10164
                                           key->pubkey_raw + pubkey_sz/2,
10165
                                           pubkey_sz/2);
10166
            }
10167
            if (err == MP_OKAY) {
10168
                err = mp_set(res->z, 1);
10169
            }
10170
        }
10171
        (void)a;
10172
        (void)prime;
10173
#else
10174
#ifdef ECC_TIMING_RESISTANT
10175
        if (err == MP_OKAY)
10176
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10177
                                          curve->order, key->rng, 1, key->heap);
10178
#else
10179
        if (err == MP_OKAY)
10180
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10181
                                              curve->order, NULL, 1, key->heap);
10182
#endif
10183
#endif /* WOLFSSL_KCAPI_ECC */
10184
    }
10185
10186
    if (err == MP_OKAY) {
10187
        /* compare result to public key */
10188
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10189
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10190
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10191
            /* didn't match */
10192
            err = ECC_PRIV_KEY_E;
10193
        }
10194
    }
10195
10196
    wc_ecc_curve_free(curve);
10197
    wc_ecc_del_point_ex(res, key->heap);
10198
    wc_ecc_del_point_ex(base, key->heap);
10199
    FREE_CURVE_SPECS();
10200
10201
    return err;
10202
}
10203
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10204
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10205
10206
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10207
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10208
10209
/* check privkey generator helper, creates prime needed */
10210
static int ecc_check_privkey_gen_helper(ecc_key* key)
10211
{
10212
    int    err;
10213
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
10214
    DECLARE_CURVE_SPECS(2);
10215
#endif
10216
10217
    if (key == NULL)
10218
        return BAD_FUNC_ARG;
10219
10220
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10221
    /* Hardware based private key, so this operation is not supported */
10222
    err = MP_OKAY; /* just report success */
10223
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10224
    /* Hardware based private key, so this operation is not supported */
10225
    err = MP_OKAY; /* just report success */
10226
#elif defined(WOLFSSL_KCAPI_ECC)
10227
    /* Hardware based private key, so this operation is not supported */
10228
    err = MP_OKAY; /* just report success */
10229
#else
10230
    ALLOC_CURVE_SPECS(2, err);
10231
10232
    /* load curve info */
10233
    if (err == MP_OKAY)
10234
        err = wc_ecc_curve_load(key->dp, &curve,
10235
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10236
10237
    if (err == MP_OKAY)
10238
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10239
10240
    wc_ecc_curve_free(curve);
10241
    FREE_CURVE_SPECS();
10242
10243
#endif /* WOLFSSL_ATECC508A */
10244
10245
    return err;
10246
}
10247
10248
/* Performs a Pairwise Consistency Test on an ECC key pair. */
10249
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10250
{
10251
    int err = 0;
10252
    word32 flags = key->flags;
10253
10254
    /* If flags not set default to cofactor and dec/sign */
10255
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10256
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10257
    }
10258
10259
    if (flags & WC_ECC_FLAG_COFACTOR) {
10260
        err = ecc_check_privkey_gen_helper(key);
10261
    }
10262
10263
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10264
#ifndef WOLFSSL_SMALL_STACK
10265
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10266
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10267
#else
10268
        byte* sig;
10269
#endif
10270
        byte* digest;
10271
        word32 sigLen, digestLen;
10272
        int dynRng = 0, res = 0;
10273
10274
        sigLen = (word32)wc_ecc_sig_size(key);
10275
        digestLen = WC_SHA256_DIGEST_SIZE;
10276
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
10277
            DYNAMIC_TYPE_ECC, return MEMORY_E);
10278
        digest = sig + sigLen;
10279
10280
        if (rng == NULL) {
10281
            dynRng = 1;
10282
            rng = wc_rng_new(NULL, 0, key->heap);
10283
            if (rng == NULL) {
10284
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10285
                return MEMORY_E;
10286
            }
10287
        }
10288
10289
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10290
10291
        if (!err)
10292
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10293
                    rng, key);
10294
        if (!err)
10295
            err = wc_ecc_verify_hash(sig, sigLen,
10296
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10297
10298
        if (res == 0)
10299
            err = ECC_PCT_E;
10300
10301
        if (dynRng) {
10302
            wc_rng_free(rng);
10303
        }
10304
        ForceZero(sig, sigLen + digestLen);
10305
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10306
    }
10307
    (void)rng;
10308
10309
    if (err != 0)
10310
        err = ECC_PCT_E;
10311
10312
    return err;
10313
}
10314
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10315
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10316
10317
#ifndef WOLFSSL_SP_MATH
10318
/* validate order * pubkey = point at infinity, 0 on success */
10319
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10320
        mp_int* prime, mp_int* order)
10321
{
10322
    ecc_point* inf = NULL;
10323
#ifdef WOLFSSL_NO_MALLOC
10324
    ecc_point  lcl_inf;
10325
#endif
10326
    int err;
10327
10328
    if (key == NULL)
10329
        return BAD_FUNC_ARG;
10330
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10331
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10332
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10333
       return IS_POINT_E;
10334
   }
10335
10336
#ifdef WOLFSSL_NO_MALLOC
10337
    inf = &lcl_inf;
10338
#endif
10339
    err = wc_ecc_new_point_ex(&inf, key->heap);
10340
    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
#if !defined(WOLFSSL_SP_MATH)
10372
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10373
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10374
            err = ECC_INF_E;
10375
#else
10376
        {
10377
            (void)a;
10378
            (void)prime;
10379
10380
            err = WC_KEY_SIZE_E;
10381
        }
10382
#endif
10383
    }
10384
10385
    wc_ecc_del_point_ex(inf, key->heap);
10386
10387
    return err;
10388
}
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
4.38k
{
10430
4.38k
    int err = MP_OKAY;
10431
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10432
    mp_int* b = NULL;
10433
    #ifdef USE_ECC_B_PARAM
10434
        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
#endif
10442
10443
4.38k
    ASSERT_SAVED_VECTOR_REGISTERS();
10444
10445
4.38k
    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
4.38k
#ifdef WOLFSSL_HAVE_SP_ECC
10459
4.38k
#ifndef WOLFSSL_SP_NO_256
10460
4.38k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10461
1.24k
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10462
1.24k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10463
1.24k
    }
10464
3.13k
#endif
10465
3.13k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10466
3.13k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10467
770
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10468
770
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10469
770
    }
10470
2.36k
#endif
10471
2.36k
#ifdef WOLFSSL_SP_384
10472
2.36k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10473
1.12k
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10474
1.12k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10475
1.12k
    }
10476
1.24k
#endif
10477
1.24k
#ifdef WOLFSSL_SP_521
10478
1.24k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10479
1.24k
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10480
1.24k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10481
1.24k
    }
10482
0
#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
0
#endif
10490
10491
#ifndef WOLFSSL_SP_MATH
10492
    #ifdef USE_ECC_B_PARAM
10493
        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
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10523
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10524
        FREE_CURVE_SPECS();
10525
        return ECC_INF_E;
10526
    }
10527
10528
    /* load curve info */
10529
    if (err == MP_OKAY)
10530
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10531
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10532
#ifdef USE_ECC_B_PARAM
10533
            | ECC_CURVE_FIELD_BF
10534
#endif
10535
    ));
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
    if (err == MP_OKAY)
10545
        b = curve->Bf;
10546
#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
    if (err == MP_OKAY) {
10552
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10553
                mp_isneg(key->pubkey.x)) {
10554
            err = ECC_OUT_OF_RANGE_E;
10555
        }
10556
    }
10557
10558
    /* Qy must be in the range [0, p-1] */
10559
    if (err == MP_OKAY) {
10560
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10561
                mp_isneg(key->pubkey.y)) {
10562
            err = ECC_OUT_OF_RANGE_E;
10563
        }
10564
    }
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
    if (err == MP_OKAY)
10570
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10571
10572
    if (!partial) {
10573
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10574
        /* pubkey * order must be at infinity */
10575
        if (err == MP_OKAY)
10576
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10577
                    curve->prime, curve->order);
10578
    }
10579
10580
    if (priv) {
10581
        /* SP 800-56Ar3, section 5.6.2.1.2 */
10582
        /* private keys must be in the range [1, n-1] */
10583
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10584
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10585
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10586
        #ifdef WOLFSSL_KCAPI_ECC
10587
            && key->handle == NULL
10588
        #endif
10589
        ) {
10590
            err = ECC_PRIV_KEY_E;
10591
        }
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
    }
10600
10601
    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
    FREE_CURVE_SPECS();
10609
10610
#else
10611
    /* The single precision math curve is not available */
10612
0
    err = WC_KEY_SIZE_E;
10613
0
#endif /* !WOLFSSL_SP_MATH */
10614
0
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10615
10616
0
    (void)partial;
10617
0
    (void)priv;
10618
0
    return err;
10619
1.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.0k
{
10626
14.0k
    int ret;
10627
14.0k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10628
14.0k
    ret = _ecc_validate_public_key(key, 0, 1);
10629
14.0k
    RESTORE_VECTOR_REGISTERS();
10630
14.0k
    return ret;
10631
14.0k
}
10632
10633
10634
#ifdef HAVE_ECC_KEY_IMPORT
10635
/* import public ECC key in ANSI X9.63 format */
10636
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
10637
                          int curve_id)
10638
378
{
10639
378
    int err = MP_OKAY;
10640
378
#ifdef HAVE_COMP_KEY
10641
378
    int compressed = 0;
10642
378
#endif
10643
378
    int keysize = 0;
10644
378
    byte pointType;
10645
#ifdef WOLFSSL_CRYPTOCELL
10646
    const CRYS_ECPKI_Domain_t* pDomain;
10647
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10648
#endif
10649
378
    if (in == NULL || key == NULL)
10650
0
        return BAD_FUNC_ARG;
10651
10652
    /* must be odd */
10653
378
    if ((inLen & 1) == 0) {
10654
0
        return ECC_BAD_ARG_E;
10655
0
    }
10656
10657
    /* make sure required variables are reset */
10658
378
    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
378
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10678
378
    #ifndef WOLFSSL_ECC_BLIND_K
10679
378
                                                                      NULL, NULL
10680
    #else
10681
                                                                key->kb, key->ku
10682
    #endif
10683
378
                            );
10684
378
    #endif
10685
378
    if (err != MP_OKAY)
10686
0
        return MEMORY_E;
10687
#ifdef WOLFSSL_ECC_BLIND_K
10688
    mp_forcezero(key->kb);
10689
#endif
10690
10691
378
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10692
10693
    /* check for point type (4, 2, or 3) */
10694
378
    pointType = in[0];
10695
378
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10696
96
                                         pointType != ECC_POINT_COMP_ODD) {
10697
8
        err = ASN_PARSE_E;
10698
8
    }
10699
10700
378
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10701
213
    #ifdef HAVE_COMP_KEY
10702
213
        compressed = 1;
10703
    #else
10704
        err = NOT_COMPILED_IN;
10705
    #endif
10706
213
    }
10707
10708
    /* adjust to skip first byte */
10709
378
    inLen -= 1;
10710
378
    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
378
    if (err == MP_OKAY) {
10725
370
    #ifdef HAVE_COMP_KEY
10726
        /* adjust inLen if compressed */
10727
370
        if (compressed)
10728
213
            inLen = inLen*2 + 1;  /* used uncompressed len */
10729
370
    #endif
10730
10731
        /* determine key size */
10732
370
        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
370
        err = wc_ecc_set_curve(key, keysize, curve_id);
10736
370
        key->type = ECC_PUBLICKEY;
10737
370
    }
10738
10739
    /* read data */
10740
378
    if (err == MP_OKAY)
10741
370
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10742
10743
378
#ifdef HAVE_COMP_KEY
10744
378
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10745
#if !defined(WOLFSSL_SP_MATH)
10746
    #ifdef WOLFSSL_SMALL_STACK
10747
        mp_int* t1 = NULL;
10748
        mp_int* t2 = NULL;
10749
    #else
10750
        mp_int t1[1], t2[1];
10751
    #endif
10752
        int did_init = 0;
10753
10754
        DECLARE_CURVE_SPECS(3);
10755
        ALLOC_CURVE_SPECS(3, err);
10756
10757
        #ifdef WOLFSSL_SMALL_STACK
10758
        if (err == MP_OKAY) {
10759
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10760
            if (t1 == NULL) {
10761
                err = MEMORY_E;
10762
            }
10763
        }
10764
        if (err == MP_OKAY) {
10765
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10766
            if (t2 == NULL) {
10767
                err = MEMORY_E;
10768
            }
10769
        }
10770
        #endif
10771
        if (err == MP_OKAY) {
10772
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10773
                err = MEMORY_E;
10774
            else
10775
                did_init = 1;
10776
        }
10777
10778
        /* load curve info */
10779
        if (err == MP_OKAY)
10780
            err = wc_ecc_curve_load(key->dp, &curve,
10781
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10782
                 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
        if (err == MP_OKAY)
10797
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10798
        if (err == MP_OKAY)
10799
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10800
10801
        /* compute x^3 + a*x */
10802
        if (err == MP_OKAY)
10803
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10804
        if (err == MP_OKAY)
10805
            err = mp_add(t1, t2, t1);
10806
10807
        /* compute x^3 + a*x + b */
10808
        if (err == MP_OKAY)
10809
            err = mp_add(t1, curve->Bf, t1);
10810
10811
        /* compute sqrt(x^3 + a*x + b) */
10812
        if (err == MP_OKAY)
10813
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10814
10815
        /* adjust y */
10816
        if (err == MP_OKAY) {
10817
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10818
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10819
                err = mp_mod(t2, curve->prime, t2);
10820
            }
10821
            else {
10822
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10823
            }
10824
            if (err == MP_OKAY)
10825
                err = mp_copy(t2, key->pubkey.y);
10826
        }
10827
10828
        if (did_init) {
10829
            mp_clear(t2);
10830
            mp_clear(t1);
10831
        }
10832
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10833
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10834
10835
        wc_ecc_curve_free(curve);
10836
        FREE_CURVE_SPECS();
10837
#else
10838
213
    #ifndef WOLFSSL_SP_NO_256
10839
213
        if (key->dp->id == ECC_SECP256R1) {
10840
60
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
10841
60
                key->pubkey.y);
10842
60
        }
10843
153
        else
10844
153
    #endif
10845
153
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10846
153
        if (key->dp->id == ECC_SM2P256V1) {
10847
43
            sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
10848
43
        }
10849
110
        else
10850
110
    #endif
10851
110
    #ifdef WOLFSSL_SP_384
10852
110
        if (key->dp->id == ECC_SECP384R1) {
10853
70
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
10854
70
                key->pubkey.y);
10855
70
        }
10856
40
        else
10857
40
    #endif
10858
40
    #ifdef WOLFSSL_SP_521
10859
40
        if (key->dp->id == ECC_SECP521R1) {
10860
40
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
10861
40
                key->pubkey.y);
10862
40
        }
10863
0
        else
10864
0
    #endif
10865
0
        {
10866
0
            err = WC_KEY_SIZE_E;
10867
0
        }
10868
213
#endif
10869
213
    }
10870
378
#endif /* HAVE_COMP_KEY */
10871
10872
378
    if (err == MP_OKAY) {
10873
283
    #ifdef HAVE_COMP_KEY
10874
283
        if (compressed == 0)
10875
157
    #endif
10876
157
        {
10877
157
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10878
157
                (word32)keysize);
10879
157
        }
10880
283
    }
10881
378
    if (err == MP_OKAY)
10882
283
        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
378
    if (err != MP_OKAY) {
10930
95
        mp_clear(key->pubkey.x);
10931
95
        mp_clear(key->pubkey.y);
10932
95
        mp_clear(key->pubkey.z);
10933
95
        mp_clear(key->k);
10934
95
    }
10935
10936
378
    RESTORE_VECTOR_REGISTERS();
10937
10938
378
    return err;
10939
378
}
10940
10941
WOLFSSL_ABI
10942
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
10943
193
{
10944
193
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
10945
193
}
10946
#endif /* HAVE_ECC_KEY_IMPORT */
10947
10948
#ifdef HAVE_ECC_KEY_EXPORT
10949
10950
/* export ecc key to component form, d is optional if only exporting public
10951
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
10952
 * return MP_OKAY on success */
10953
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
10954
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
10955
0
{
10956
0
    int err = 0;
10957
0
    word32 keySz;
10958
10959
0
    if (key == NULL) {
10960
0
        return BAD_FUNC_ARG;
10961
0
    }
10962
10963
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
10964
0
        return ECC_BAD_ARG_E;
10965
0
    }
10966
0
    keySz = (word32)key->dp->size;
10967
10968
    /* private key, d */
10969
0
    if (d != NULL) {
10970
0
        if (dLen == NULL ||
10971
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
10972
0
            return BAD_FUNC_ARG;
10973
10974
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10975
        /* Hardware cannot export private portion */
10976
        return NOT_COMPILED_IN;
10977
    #else
10978
    #if defined(WOLFSSL_SECO_CAAM)
10979
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
10980
            /* Hardware cannot export private portion */
10981
            WOLFSSL_MSG("Can not export private key from HSM");
10982
            return NOT_COMPILED_IN;
10983
        }
10984
    #endif
10985
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10986
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
10987
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
10988
                *dLen = keySz + WC_CAAM_MAC_SZ;
10989
                return BUFFER_E;
10990
            }
10991
10992
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
10993
                encType);
10994
            *dLen = keySz + WC_CAAM_MAC_SZ;
10995
        }
10996
        else if (encType == WC_TYPE_BLACK_KEY &&
10997
                key->blackKey != CAAM_BLACK_KEY_ECB &&
10998
                key->blackKey > 0) {
10999
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11000
                *dLen = keySz + WC_CAAM_MAC_SZ;
11001
                return BUFFER_E;
11002
            }
11003
11004
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11005
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11006
                    return WC_HW_E;
11007
            }
11008
11009
            *dLen = keySz + WC_CAAM_MAC_SZ;
11010
        }
11011
        else
11012
    #endif
11013
0
        {
11014
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11015
0
            if (err != MP_OKAY)
11016
0
                return err;
11017
0
        }
11018
0
    #endif
11019
0
    }
11020
11021
    /* public x component */
11022
0
    if (qx != NULL) {
11023
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11024
0
            return BAD_FUNC_ARG;
11025
11026
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11027
0
        if (err != MP_OKAY)
11028
0
            return err;
11029
0
    }
11030
11031
    /* public y component */
11032
0
    if (qy != NULL) {
11033
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11034
0
            return BAD_FUNC_ARG;
11035
11036
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11037
0
        if (err != MP_OKAY)
11038
0
            return err;
11039
0
    }
11040
11041
0
    return err;
11042
0
}
11043
11044
11045
/* export ecc private key only raw, outLen is in/out size as unsigned bin
11046
   return MP_OKAY on success */
11047
WOLFSSL_ABI
11048
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11049
0
{
11050
0
    if (out == NULL || outLen == NULL) {
11051
0
        return BAD_FUNC_ARG;
11052
0
    }
11053
11054
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11055
    /* check if black key in secure memory */
11056
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11057
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11058
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11059
            WC_TYPE_BLACK_KEY);
11060
    }
11061
#endif
11062
11063
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11064
0
        WC_TYPE_UNSIGNED_BIN);
11065
0
}
11066
11067
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11068
 * return MP_OKAY on success, negative on error */
11069
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11070
                             byte* qy, word32* qyLen)
11071
0
{
11072
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11073
0
        return BAD_FUNC_ARG;
11074
0
    }
11075
11076
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11077
0
        WC_TYPE_UNSIGNED_BIN);
11078
0
}
11079
11080
/* export ecc key to raw elements including public (Qx,Qy) and
11081
 *   private (d) as unsigned bin
11082
 * return MP_OKAY on success, negative on error */
11083
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11084
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11085
0
{
11086
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11087
0
        WC_TYPE_UNSIGNED_BIN);
11088
0
}
11089
11090
#endif /* HAVE_ECC_KEY_EXPORT */
11091
11092
#ifdef HAVE_ECC_KEY_IMPORT
11093
/* import private key, public part optional if (pub) passed as NULL */
11094
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11095
                                 const byte* pub, word32 pubSz, ecc_key* key,
11096
                                 int curve_id)
11097
8.39k
{
11098
8.39k
    int ret;
11099
#ifdef WOLFSSL_CRYPTOCELL
11100
    const CRYS_ECPKI_Domain_t* pDomain;
11101
#endif
11102
8.39k
    if (key == NULL || priv == NULL)
11103
112
        return BAD_FUNC_ARG;
11104
11105
    /* public optional, NULL if only importing private */
11106
8.28k
    if (pub != NULL) {
11107
0
    #ifndef NO_ASN
11108
0
        word32 idx = 0;
11109
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
11110
0
        if (ret < 0)
11111
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11112
0
        key->type = ECC_PRIVATEKEY;
11113
    #else
11114
        (void)pubSz;
11115
        ret = NOT_COMPILED_IN;
11116
    #endif
11117
0
    }
11118
8.28k
    else {
11119
        /* make sure required variables are reset */
11120
8.28k
        wc_ecc_reset(key);
11121
11122
        /* set key size */
11123
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11124
         *       on created keys or signatures */
11125
8.28k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11126
8.28k
        key->type = ECC_PRIVATEKEY_ONLY;
11127
8.28k
    }
11128
11129
8.28k
    if (ret != 0)
11130
836
        return ret;
11131
11132
#ifdef WOLFSSL_CRYPTOCELL
11133
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11134
    /* import private key - priv checked for NULL at top */
11135
    if (priv[0] != '\0') {
11136
11137
        /* Create private key from external key buffer*/
11138
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11139
                                      priv,
11140
                                      privSz,
11141
                                      &key->ctx.privKey);
11142
11143
        if (ret != SA_SILIB_RET_OK) {
11144
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11145
            return ret;
11146
        }
11147
11148
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11149
    #ifdef WOLFSSL_ECC_BLIND_K
11150
        if (ret == MP_OKAY) {
11151
            err = ecc_blind_k_rng(key, NULL);
11152
        }
11153
    #endif
11154
    }
11155
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11156
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11157
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11158
        int part = caamFindUnusedPartition();
11159
        if (part >= 0) {
11160
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11161
            if (vaddr == 0) {
11162
                WOLFSSL_MSG("Unable to get partition");
11163
                return MEMORY_E;
11164
            }
11165
11166
            key->partNum  = part;
11167
            key->blackKey = (word32)vaddr;
11168
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11169
                return WC_HW_E;
11170
11171
            if (pub != NULL) {
11172
                /* +1 to account for x963 compressed bit */
11173
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11174
                    return WC_HW_E;
11175
                key->securePubKey = (word32)vaddr + privSz;
11176
            }
11177
        }
11178
        else {
11179
            WOLFSSL_MSG("Unable to find an unused partition");
11180
            return MEMORY_E;
11181
        }
11182
    #else
11183
        key->blackKey = CAAM_BLACK_KEY_CCM;
11184
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11185
    #ifdef WOLFSSL_ECC_BLIND_K
11186
        if (ret == MP_OKAY) {
11187
            err = ecc_blind_k_rng(key, NULL);
11188
        }
11189
    #endif
11190
    #endif
11191
    }
11192
    else {
11193
        key->blackKey = 0;
11194
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11195
    #ifdef WOLFSSL_ECC_BLIND_K
11196
        if (ret == MP_OKAY) {
11197
            err = ecc_blind_k_rng(key, NULL);
11198
        }
11199
    #endif
11200
11201
        /* If using AES-ECB encrypted black keys check here if key is valid,
11202
         * if not valid than assume is an encrypted key. A public key is needed
11203
         * for testing validity. */
11204
        if (key->devId == WOLFSSL_CAAM_DEVID && (
11205
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11206
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11207
            if ((pub != NULL) && (ret == MP_OKAY) &&
11208
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11209
                key->blackKey = CAAM_BLACK_KEY_ECB;
11210
            }
11211
            else if ((pub == NULL) && (ret == MP_OKAY)) {
11212
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11213
                key->blackKey = CAAM_BLACK_KEY_ECB;
11214
            }
11215
            else {
11216
                WOLFSSL_MSG("Importing key that is not a black key!");
11217
            }
11218
        }
11219
    }
11220
#else
11221
11222
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11223
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11224
#endif
11225
11226
7.44k
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11227
#ifdef HAVE_WOLF_BIGINT
11228
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11229
                                                                 privSz) != 0) {
11230
        mp_clear(key->k);
11231
        ret = ASN_GETINT_E;
11232
    }
11233
#endif /* HAVE_WOLF_BIGINT */
11234
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11235
    if (ret == 0) {
11236
        WC_DECLARE_VAR(order, mp_int, 1, 0);
11237
11238
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
11239
            ret=MEMORY_E);
11240
11241
        if (ret == 0) {
11242
            ret = mp_init(order);
11243
        }
11244
        if (ret == 0) {
11245
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11246
        }
11247
    #ifdef WOLFSSL_SM2
11248
        /* SM2 curve: private key must be less than order-1. */
11249
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11250
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11251
            ret = mp_sub_d(order, 1, order);
11252
        }
11253
    #endif
11254
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11255
            ret = ECC_PRIV_KEY_E;
11256
        }
11257
11258
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
11259
    }
11260
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11261
#ifdef WOLFSSL_ECC_BLIND_K
11262
    if (ret == 0) {
11263
        ret = ecc_blind_k_rng(key, NULL);
11264
    }
11265
#endif
11266
11267
7.44k
#endif /* WOLFSSL_CRYPTOCELL */
11268
11269
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11270
    if ((pub != NULL) && (ret == MP_OKAY))
11271
        /* public key needed to perform key validation */
11272
        ret = _ecc_validate_public_key(key, 1, 1);
11273
11274
#endif
11275
11276
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11277
    RESTORE_VECTOR_REGISTERS();
11278
#endif
11279
11280
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11281
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11282
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11283
    }
11284
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11285
    if (ret == 0) {
11286
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11287
    }
11288
#endif
11289
11290
7.44k
    return ret;
11291
8.28k
}
11292
11293
/* ecc private key import, public key in ANSI X9.63 format, private raw */
11294
WOLFSSL_ABI
11295
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11296
                           word32 pubSz, ecc_key* key)
11297
51
{
11298
51
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11299
51
                                                                ECC_CURVE_DEF);
11300
51
}
11301
#endif /* HAVE_ECC_KEY_IMPORT */
11302
11303
#ifndef NO_ASN
11304
/**
11305
   Convert ECC R,S to signature
11306
   r       R component of signature
11307
   s       S component of signature
11308
   out     DER-encoded ECDSA signature
11309
   outlen  [in/out] output buffer size, output signature size
11310
   return  MP_OKAY on success
11311
*/
11312
WOLFSSL_ABI
11313
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11314
2.34k
{
11315
2.34k
    int err;
11316
2.34k
#ifdef WOLFSSL_SMALL_STACK
11317
2.34k
    mp_int* rtmp = NULL;
11318
2.34k
    mp_int* stmp = NULL;
11319
#else
11320
    mp_int  rtmp[1];
11321
    mp_int  stmp[1];
11322
#endif
11323
11324
2.34k
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11325
8
        return ECC_BAD_ARG_E;
11326
11327
2.33k
#ifdef WOLFSSL_SMALL_STACK
11328
2.33k
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11329
2.33k
    if (rtmp == NULL)
11330
5
        return MEMORY_E;
11331
2.33k
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11332
2.33k
    if (stmp == NULL) {
11333
4
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11334
4
        return MEMORY_E;
11335
4
    }
11336
2.32k
#endif
11337
11338
2.32k
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11339
2.32k
    if (err != MP_OKAY) {
11340
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11341
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11342
0
        return err;
11343
0
    }
11344
11345
2.32k
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11346
2.32k
    if (err == MP_OKAY)
11347
2.30k
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11348
11349
2.32k
    if (err == MP_OKAY) {
11350
2.29k
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11351
38
            err = MP_ZERO_E;
11352
2.29k
    }
11353
2.32k
    if (err == MP_OKAY) {
11354
2.26k
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11355
0
            err = MP_READ_E;
11356
0
        }
11357
2.26k
    }
11358
11359
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11360
2.32k
    if (err == MP_OKAY)
11361
2.26k
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11362
11363
2.32k
    mp_clear(rtmp);
11364
2.32k
    mp_clear(stmp);
11365
2.32k
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11366
2.32k
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11367
11368
2.32k
    return err;
11369
2.32k
}
11370
11371
/**
11372
   Convert ECC R,S raw unsigned bin to signature
11373
   r       R component of signature
11374
   rSz     R size
11375
   s       S component of signature
11376
   sSz     S size
11377
   out     DER-encoded ECDSA signature
11378
   outlen  [in/out] output buffer size, output signature size
11379
   return  MP_OKAY on success
11380
*/
11381
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11382
    byte* out, word32* outlen)
11383
350
{
11384
350
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11385
3
        return ECC_BAD_ARG_E;
11386
11387
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11388
347
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11389
350
}
11390
11391
/**
11392
   Convert ECC signature to R,S
11393
   sig     DER-encoded ECDSA signature
11394
   sigLen  length of signature in octets
11395
   r       R component of signature
11396
   rLen    [in/out] output "r" buffer size, output "r" size
11397
   s       S component of signature
11398
   sLen    [in/out] output "s" buffer size, output "s" size
11399
   return  MP_OKAY on success, negative on error
11400
*/
11401
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11402
                     byte* s, word32* sLen)
11403
0
{
11404
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11405
0
        return ECC_BAD_ARG_E;
11406
11407
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11408
0
}
11409
#endif /* !NO_ASN */
11410
11411
#ifdef HAVE_ECC_KEY_IMPORT
11412
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
11413
          const char* qy, const char* d, int curve_id, int encType)
11414
5.42k
{
11415
5.42k
    int err = MP_OKAY;
11416
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11417
    !defined(WOLFSSL_ATECC608A)
11418
    const CRYS_ECPKI_Domain_t* pDomain;
11419
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11420
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11421
#endif
11422
11423
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11424
    defined(WOLFSSL_CRYPTOCELL)
11425
    word32 keySz = 0;
11426
#endif
11427
11428
    /* if d is NULL, only import as public key using Qx,Qy */
11429
5.42k
    if (key == NULL || qx == NULL || qy == NULL) {
11430
0
        return BAD_FUNC_ARG;
11431
0
    }
11432
11433
    /* make sure required variables are reset */
11434
5.42k
    wc_ecc_reset(key);
11435
11436
    /* set curve type and index */
11437
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11438
     *       on created keys or signatures */
11439
5.42k
    err = wc_ecc_set_curve(key, 0, curve_id);
11440
5.42k
    if (err != 0) {
11441
0
        return err;
11442
0
    }
11443
11444
    /* init key */
11445
#ifdef ALT_ECC_SIZE
11446
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11447
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11448
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11449
    alt_fp_init(key->pubkey.x);
11450
    alt_fp_init(key->pubkey.y);
11451
    alt_fp_init(key->pubkey.z);
11452
    key->k = (mp_int*)key->ka;
11453
    alt_fp_init(key->k);
11454
#ifdef WOLFSSL_ECC_BLIND_K
11455
    key->kb = (mp_int*)key->kba;
11456
    key->ku = (mp_int*)key->kua;
11457
    alt_fp_init(key->kb);
11458
    alt_fp_init(key->ku);
11459
#endif
11460
#else
11461
5.42k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11462
5.42k
#ifndef WOLFSSL_ECC_BLIND_K
11463
5.42k
                                                                      NULL, NULL
11464
#else
11465
                                                                key->kb, key->ku
11466
#endif
11467
5.42k
                        );
11468
5.42k
#endif
11469
5.42k
    if (err != MP_OKAY)
11470
0
        return MEMORY_E;
11471
#ifdef WOLFSSL_ECC_BLIND_K
11472
    mp_forcezero(key->kb);
11473
#endif
11474
11475
    /* read Qx */
11476
5.42k
    if (err == MP_OKAY) {
11477
5.42k
        if (encType == WC_TYPE_HEX_STR)
11478
5.42k
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
11479
0
        else
11480
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
11481
0
                (word32)key->dp->size);
11482
11483
5.42k
        if (mp_isneg(key->pubkey.x)) {
11484
0
            WOLFSSL_MSG("Invalid Qx");
11485
0
            err = BAD_FUNC_ARG;
11486
0
        }
11487
5.42k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11488
49
            err = BAD_FUNC_ARG;
11489
49
        }
11490
5.42k
    }
11491
11492
    /* read Qy */
11493
5.42k
    if (err == MP_OKAY) {
11494
5.32k
        if (encType == WC_TYPE_HEX_STR)
11495
5.32k
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
11496
0
        else
11497
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
11498
0
                (word32)key->dp->size);
11499
11500
5.32k
        if (mp_isneg(key->pubkey.y)) {
11501
0
            WOLFSSL_MSG("Invalid Qy");
11502
0
            err = BAD_FUNC_ARG;
11503
0
        }
11504
5.32k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11505
49
            err = BAD_FUNC_ARG;
11506
49
        }
11507
5.32k
    }
11508
11509
5.42k
    if (err == MP_OKAY) {
11510
5.24k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11511
93
            WOLFSSL_MSG("Invalid Qx and Qy");
11512
93
            err = ECC_INF_E;
11513
93
        }
11514
5.24k
    }
11515
11516
5.42k
    if (err == MP_OKAY)
11517
5.15k
        err = mp_set(key->pubkey.z, 1);
11518
11519
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11520
    /* For SECP256R1 only save raw public key for hardware */
11521
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
11522
        keySz = key->dp->size;
11523
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11524
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11525
        if (err == MP_OKAY)
11526
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
11527
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11528
    }
11529
#elif defined(WOLFSSL_CRYPTOCELL)
11530
    if (err == MP_OKAY) {
11531
        keyRaw[0] = ECC_POINT_UNCOMP;
11532
        keySz = (word32)key->dp->size;
11533
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
11534
            WC_TYPE_UNSIGNED_BIN);
11535
        if (err == MP_OKAY) {
11536
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
11537
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11538
        }
11539
11540
        if (err == MP_OKAY) {
11541
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11542
11543
            /* create public key from external key buffer */
11544
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11545
                                                   keyRaw,
11546
                                                   keySz*2 + 1,
11547
                                                   &key->ctx.pubKey,
11548
                                                   &tempBuff);
11549
        }
11550
11551
        if (err != SA_SILIB_RET_OK){
11552
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11553
            return err;
11554
        }
11555
    }
11556
#elif defined(WOLFSSL_KCAPI_ECC)
11557
    if (err == MP_OKAY) {
11558
        word32 keySz = key->dp->size;
11559
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11560
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11561
        if (err == MP_OKAY) {
11562
            err = wc_export_int(key->pubkey.y,
11563
                &key->pubkey_raw[keySz], &keySz, keySz,
11564
                WC_TYPE_UNSIGNED_BIN);
11565
        }
11566
    }
11567
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11568
    if (err == MP_OKAY) {
11569
        const word32 keySize = key->dp->size;
11570
        word32 bufSize = sizeof(key->keyRaw);
11571
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
11572
                            WC_TYPE_UNSIGNED_BIN);
11573
        if (err == MP_OKAY) {
11574
            const word32 offset = bufSize;
11575
            bufSize = sizeof(key->keyRaw) - offset;
11576
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
11577
                                keySize, WC_TYPE_UNSIGNED_BIN);
11578
        }
11579
        if (err == MP_OKAY) {
11580
            mp_reverse(key->keyRaw, keySize);
11581
            mp_reverse(&key->keyRaw[keySize], keySize);
11582
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
11583
                                           keySize * 2);
11584
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
11585
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
11586
                                              xil_curve_type[key->dp->id],
11587
                                              XIL_CAST_U64(key->keyRaw));
11588
            if (err) {
11589
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
11590
                err = WC_HW_E;
11591
            }
11592
#endif
11593
        }
11594
    }
11595
#endif
11596
11597
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11598
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11599
#endif
11600
11601
    /* import private key */
11602
5.42k
    if (err == MP_OKAY) {
11603
5.15k
        if (d != NULL) {
11604
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11605
            /* Hardware doesn't support loading private key */
11606
            err = NOT_COMPILED_IN;
11607
11608
        #elif defined(WOLFSSL_CRYPTOCELL)
11609
            key->type = ECC_PRIVATEKEY;
11610
11611
            if (encType == WC_TYPE_HEX_STR)
11612
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11613
            else
11614
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
11615
                    key->dp->size);
11616
            if (err == MP_OKAY) {
11617
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
11618
                    WC_TYPE_UNSIGNED_BIN);
11619
            }
11620
        #ifdef WOLFSSL_ECC_BLIND_K
11621
            if (err == 0) {
11622
                err = ecc_blind_k_rng(key, NULL);
11623
            }
11624
        #endif
11625
11626
            if (err == MP_OKAY) {
11627
                /* Create private key from external key buffer*/
11628
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
11629
                                              keyRaw,
11630
                                              keySz,
11631
                                              &key->ctx.privKey);
11632
11633
                if (err != SA_SILIB_RET_OK){
11634
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11635
                    return err;
11636
                }
11637
            }
11638
11639
        #else
11640
0
            key->type = ECC_PRIVATEKEY;
11641
0
            if (encType == WC_TYPE_HEX_STR)
11642
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11643
0
            else {
11644
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11645
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11646
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11647
                    key->dp->size + WC_CAAM_MAC_SZ);
11648
                }
11649
                else
11650
            #endif /* WOLFSSL_QNX_CAAM */
11651
0
                {
11652
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11653
0
                        (word32)key->dp->size);
11654
0
                }
11655
0
            }
11656
        #ifdef WOLFSSL_ECC_BLIND_K
11657
            if (err == 0) {
11658
                err = ecc_blind_k_rng(key, NULL);
11659
            }
11660
        #endif
11661
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11662
            if (err == MP_OKAY) {
11663
                const word32 key_size = key->dp->size;
11664
                word32 buf_size = key_size;
11665
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
11666
                                    WC_TYPE_UNSIGNED_BIN);
11667
                mp_reverse(key->privKey, key_size);
11668
            }
11669
#endif
11670
11671
0
        #endif /* #else-case of custom HW-specific implementations */
11672
0
            if (mp_iszero(key->k) || mp_isneg(key->k)) {
11673
0
                WOLFSSL_MSG("Invalid private key");
11674
0
                err = BAD_FUNC_ARG;
11675
0
            }
11676
5.15k
        } else {
11677
5.15k
            key->type = ECC_PUBLICKEY;
11678
5.15k
        }
11679
5.15k
    }
11680
11681
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11682
    if (err == MP_OKAY) {
11683
        err = wc_ecc_check_key(key);
11684
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
11685
                                  mp_iszero(key->pubkey.y))) {
11686
            err = BAD_FUNC_ARG;
11687
        }
11688
    }
11689
#endif
11690
11691
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11692
    RESTORE_VECTOR_REGISTERS();
11693
#endif
11694
11695
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11696
    if (err == MP_OKAY) {
11697
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11698
    }
11699
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11700
    if (err == MP_OKAY) {
11701
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
11702
    }
11703
#endif
11704
11705
5.42k
    if (err != MP_OKAY) {
11706
277
        mp_clear(key->pubkey.x);
11707
277
        mp_clear(key->pubkey.y);
11708
277
        mp_clear(key->pubkey.z);
11709
277
        mp_clear(key->k);
11710
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11711
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11712
#endif
11713
277
    }
11714
11715
5.42k
    return err;
11716
5.42k
}
11717
11718
/**
11719
   Import raw ECC key
11720
   key       The destination ecc_key structure
11721
   qx        x component of the public key, as ASCII hex string
11722
   qy        y component of the public key, as ASCII hex string
11723
   d         private key, as ASCII hex string, optional if importing public
11724
             key only
11725
   curve_id  The id of the curve.
11726
   @return    MP_OKAY on success
11727
*/
11728
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
11729
                   const char* d, int curve_id)
11730
0
{
11731
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
11732
0
        WC_TYPE_HEX_STR);
11733
0
}
11734
11735
/* Import x, y and optional private (d) as unsigned binary */
11736
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
11737
                   const byte* d, int curve_id)
11738
0
{
11739
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
11740
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
11741
0
}
11742
11743
/**
11744
   Import raw ECC key
11745
   key       The destination ecc_key structure
11746
   qx        x component of the public key, as ASCII hex string
11747
   qy        y component of the public key, as ASCII hex string
11748
   d         private key, as ASCII hex string, optional if importing public
11749
             key only
11750
   curveName ECC curve name, from ecc_sets[]
11751
   return    MP_OKAY on success
11752
*/
11753
WOLFSSL_ABI
11754
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
11755
                   const char* d, const char* curveName)
11756
11.8k
{
11757
11.8k
    int err, x;
11758
11759
    /* if d is NULL, only import as public key using Qx,Qy */
11760
11.8k
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
11761
0
        return BAD_FUNC_ARG;
11762
0
    }
11763
11764
    /* set curve type and index */
11765
142k
    for (x = 0; ecc_sets[x].size != 0; x++) {
11766
142k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11767
142k
                     XSTRLEN(curveName)) == 0) {
11768
11.8k
            break;
11769
11.8k
        }
11770
142k
    }
11771
11772
11.8k
    if (ecc_sets[x].size == 0) {
11773
0
        WOLFSSL_MSG("ecc_set curve name not found");
11774
0
        err = ASN_PARSE_E;
11775
11.8k
    } else {
11776
11.8k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
11777
11.8k
            WC_TYPE_HEX_STR);
11778
11.8k
    }
11779
11780
0
    return err;
11781
11.8k
}
11782
#endif /* HAVE_ECC_KEY_IMPORT */
11783
11784
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
11785
/* public key size in octets */
11786
static int ecc_public_key_size(ecc_key* key, word32* sz)
11787
352
{
11788
352
    if (key == NULL || key->dp == NULL)
11789
0
        return BAD_FUNC_ARG;
11790
11791
    /* 'Uncompressed' | x | y */
11792
352
    *sz = 1 + 2 * (word32)key->dp->size;
11793
11794
352
    return 0;
11795
352
}
11796
#endif
11797
11798
/* key size in octets */
11799
WOLFSSL_ABI
11800
int wc_ecc_size(ecc_key* key)
11801
319
{
11802
319
    if (key == NULL || key->dp == NULL)
11803
0
        return 0;
11804
11805
319
    return key->dp->size;
11806
319
}
11807
11808
/* maximum signature size based on key size */
11809
WOLFSSL_ABI
11810
int wc_ecc_sig_size_calc(int sz)
11811
0
{
11812
0
    int maxSigSz = 0;
11813
11814
    /* calculate based on key bits */
11815
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
11816
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
11817
11818
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11819
0
    if (maxSigSz < (128 + 2)) {
11820
0
        maxSigSz -= 1;
11821
0
    }
11822
11823
0
    return maxSigSz;
11824
0
}
11825
11826
/* maximum signature size based on actual key curve */
11827
WOLFSSL_ABI
11828
int wc_ecc_sig_size(const ecc_key* key)
11829
694
{
11830
694
    int maxSigSz;
11831
694
    int orderBits, keySz;
11832
11833
694
    if (key == NULL || key->dp == NULL)
11834
0
        return 0;
11835
11836
    /* the signature r and s will always be less than order */
11837
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
11838
        extra byte for r and s, so add 2 */
11839
694
    keySz = key->dp->size;
11840
694
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11841
694
    if (orderBits > keySz * 8) {
11842
0
        keySz = (orderBits + 7) >> 3;
11843
0
    }
11844
    /* maximum possible signature header size is 7 bytes */
11845
694
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11846
694
    if ((orderBits % 8) == 0) {
11847
        /* MSB can be set, so add 2 */
11848
416
        maxSigSz += ECC_MAX_PAD_SZ;
11849
416
    }
11850
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11851
694
    if (maxSigSz < (128 + 2)) {
11852
416
        maxSigSz -= 1;
11853
416
    }
11854
11855
694
    return maxSigSz;
11856
694
}
11857
11858
11859
#ifdef FP_ECC
11860
11861
/* fixed point ECC cache */
11862
/* number of entries in the cache */
11863
#ifndef FP_ENTRIES
11864
    #define FP_ENTRIES 15
11865
#endif
11866
11867
/* number of bits in LUT */
11868
#ifndef FP_LUT
11869
    #define FP_LUT     8U
11870
#endif
11871
11872
#ifdef ECC_SHAMIR
11873
    /* Sharmir requires a bigger LUT, TAO */
11874
    #if (FP_LUT > 12) || (FP_LUT < 4)
11875
        #error FP_LUT must be between 4 and 12 inclusively
11876
    #endif
11877
#else
11878
    #if (FP_LUT > 12) || (FP_LUT < 2)
11879
        #error FP_LUT must be between 2 and 12 inclusively
11880
    #endif
11881
#endif
11882
11883
11884
#if !defined(WOLFSSL_SP_MATH)
11885
11886
/** Our FP cache */
11887
typedef struct {
11888
   ecc_point* g;               /* cached COPY of base point */
11889
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
11890
   int        LUT_set;         /* flag to determine if the LUT has been computed */
11891
   mp_int     mu;              /* copy of the montgomery constant */
11892
   int        lru_count;       /* amount of times this entry has been used */
11893
   int        lock;            /* flag to indicate cache eviction */
11894
                               /* permitted (0) or not (1) */
11895
} fp_cache_t;
11896
11897
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
11898
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
11899
11900
#ifndef HAVE_THREAD_LS
11901
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
11902
#ifndef WOLFSSL_MUTEX_INITIALIZER
11903
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
11904
#endif
11905
#endif /* HAVE_THREAD_LS */
11906
11907
/* simple table to help direct the generation of the LUT */
11908
static const struct {
11909
   int ham, terma, termb;
11910
} lut_orders[] = {
11911
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
11912
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
11913
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
11914
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
11915
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
11916
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
11917
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
11918
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
11919
#if FP_LUT > 6
11920
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
11921
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
11922
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
11923
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
11924
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
11925
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
11926
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
11927
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
11928
#if FP_LUT > 7
11929
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
11930
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
11931
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
11932
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
11933
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
11934
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
11935
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
11936
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
11937
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
11938
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
11939
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
11940
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
11941
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
11942
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
11943
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
11944
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
11945
#if FP_LUT > 8
11946
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
11947
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
11948
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
11949
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
11950
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
11951
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
11952
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
11953
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
11954
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
11955
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
11956
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
11957
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
11958
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
11959
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
11960
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
11961
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
11962
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
11963
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
11964
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
11965
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
11966
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
11967
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
11968
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
11969
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
11970
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
11971
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
11972
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
11973
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
11974
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
11975
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
11976
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
11977
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
11978
#if FP_LUT > 9
11979
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
11980
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
11981
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
11982
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
11983
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
11984
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
11985
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
11986
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
11987
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
11988
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
11989
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
11990
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
11991
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
11992
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
11993
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
11994
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
11995
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
11996
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
11997
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
11998
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
11999
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12000
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12001
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12002
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12003
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12004
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12005
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12006
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12007
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12008
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12009
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12010
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12011
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12012
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12013
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12014
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12015
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12016
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12017
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12018
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12019
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12020
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12021
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12022
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12023
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12024
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12025
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12026
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12027
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12028
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12029
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12030
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12031
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12032
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12033
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12034
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12035
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12036
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12037
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12038
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12039
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12040
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12041
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12042
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12043
#if FP_LUT > 10
12044
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12045
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12046
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12047
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12048
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12049
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12050
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12051
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12052
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12053
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12054
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12055
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12056
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12057
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12058
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12059
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12060
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12061
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12062
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12063
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12064
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12065
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12066
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12067
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12068
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12069
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12070
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12071
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12072
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12073
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12074
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12075
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12076
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12077
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12078
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12079
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12080
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12081
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12082
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12083
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12084
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12085
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12086
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12087
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12088
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12089
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12090
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12091
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12092
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12093
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12094
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12095
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12096
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12097
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12098
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12099
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12100
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12101
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12102
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12103
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12104
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12105
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12106
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12107
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12108
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12109
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12110
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12111
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12112
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12113
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12114
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12115
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12116
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12117
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12118
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12119
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12120
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12121
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12122
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12123
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12124
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12125
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12126
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12127
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12128
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12129
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12130
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12131
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12132
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12133
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12134
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12135
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12136
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12137
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12138
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12139
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12140
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12141
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12142
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12143
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12144
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12145
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12146
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12147
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12148
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12149
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12150
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12151
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12152
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12153
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12154
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12155
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12156
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12157
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12158
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12159
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12160
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12161
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12162
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12163
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12164
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12165
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12166
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12167
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12168
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12169
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12170
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12171
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12172
#if FP_LUT > 11
12173
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12174
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12175
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12176
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12177
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12178
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12179
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12180
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12181
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12182
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12183
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12184
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12185
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12186
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12187
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12188
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12189
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12190
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12191
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12192
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12193
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12194
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12195
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12196
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12197
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12198
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12199
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12200
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12201
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12202
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12203
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12204
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12205
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12206
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12207
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12208
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12209
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12210
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12211
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12212
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12213
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12214
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12215
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12216
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12217
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12218
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12219
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12220
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12221
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12222
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12223
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12224
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12225
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12226
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12227
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12228
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12229
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12230
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12231
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12232
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12233
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12234
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12235
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12236
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12237
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12238
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12239
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12240
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12241
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12242
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12243
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12244
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12245
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12246
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12247
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12248
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12249
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12250
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12251
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12252
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12253
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12254
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12255
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12256
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12257
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12258
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12259
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12260
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12261
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12262
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12263
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12264
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12265
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12266
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12267
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12268
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12269
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12270
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12271
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12272
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12273
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12274
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12275
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12276
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12277
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12278
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12279
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12280
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12281
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12282
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12283
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12284
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12285
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12286
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12287
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12288
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12289
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12290
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12291
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12292
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12293
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12294
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12295
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12296
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12297
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12298
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12299
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12300
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12301
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12302
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12303
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12304
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12305
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12306
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12307
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12308
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12309
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12310
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12311
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12312
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12313
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12314
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12315
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12316
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12317
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12318
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12319
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12320
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12321
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12322
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12323
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12324
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12325
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12326
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12327
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12328
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12329
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12330
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12331
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12332
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12333
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12334
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12335
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12336
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12337
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12338
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12339
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12340
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
12341
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
12342
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
12343
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
12344
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
12345
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
12346
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
12347
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
12348
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
12349
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
12350
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
12351
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
12352
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
12353
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
12354
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
12355
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
12356
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
12357
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
12358
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
12359
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
12360
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
12361
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
12362
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
12363
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
12364
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
12365
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
12366
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
12367
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
12368
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
12369
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
12370
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
12371
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
12372
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
12373
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
12374
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
12375
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
12376
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
12377
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
12378
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
12379
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
12380
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
12381
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
12382
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
12383
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
12384
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
12385
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
12386
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
12387
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
12388
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
12389
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
12390
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
12391
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
12392
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
12393
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
12394
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
12395
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
12396
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
12397
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
12398
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
12399
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
12400
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
12401
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
12402
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
12403
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
12404
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
12405
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
12406
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
12407
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
12408
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
12409
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
12410
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
12411
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
12412
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
12413
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
12414
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
12415
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
12416
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
12417
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
12418
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
12419
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
12420
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
12421
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
12422
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
12423
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
12424
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
12425
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
12426
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
12427
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
12428
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
12429
#endif
12430
#endif
12431
#endif
12432
#endif
12433
#endif
12434
#endif
12435
};
12436
12437
12438
/* find a hole and free as required, return -1 if no hole found */
12439
static int find_hole(void)
12440
{
12441
#ifdef WOLFSSL_NO_MALLOC
12442
   return -1;
12443
#else
12444
   int      x, y, z;
12445
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
12446
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
12447
          z = x;
12448
          y = fp_cache[x].lru_count;
12449
       }
12450
   }
12451
12452
   /* decrease all */
12453
   for (x = 0; x < FP_ENTRIES; x++) {
12454
      if (fp_cache[x].lru_count > 3) {
12455
         --(fp_cache[x].lru_count);
12456
      }
12457
   }
12458
12459
   /* free entry z */
12460
   if (z >= 0 && fp_cache[z].g) {
12461
      mp_clear(&fp_cache[z].mu);
12462
      wc_ecc_del_point(fp_cache[z].g);
12463
      fp_cache[z].g  = NULL;
12464
      for (x = 0; x < (1<<FP_LUT); x++) {
12465
         wc_ecc_del_point(fp_cache[z].LUT[x]);
12466
         fp_cache[z].LUT[x] = NULL;
12467
      }
12468
      fp_cache[z].LUT_set = 0;
12469
      fp_cache[z].lru_count = 0;
12470
   }
12471
   return z;
12472
#endif /* !WOLFSSL_NO_MALLOC */
12473
}
12474
12475
/* determine if a base is already in the cache and if so, where */
12476
static int find_base(ecc_point* g)
12477
{
12478
   int x;
12479
   for (x = 0; x < FP_ENTRIES; x++) {
12480
      if (fp_cache[x].g != NULL &&
12481
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
12482
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
12483
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
12484
         break;
12485
      }
12486
   }
12487
   if (x == FP_ENTRIES) {
12488
      x = -1;
12489
   }
12490
   return x;
12491
}
12492
12493
/* add a new base to the cache */
12494
static int add_entry(int idx, ecc_point *g)
12495
{
12496
   unsigned x, y;
12497
12498
   /* allocate base and LUT */
12499
   fp_cache[idx].g = wc_ecc_new_point();
12500
   if (fp_cache[idx].g == NULL) {
12501
      return MP_MEM;
12502
   }
12503
12504
   /* copy x and y */
12505
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
12506
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
12507
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
12508
      wc_ecc_del_point(fp_cache[idx].g);
12509
      fp_cache[idx].g = NULL;
12510
      return MP_MEM;
12511
   }
12512
12513
   for (x = 0; x < (1U<<FP_LUT); x++) {
12514
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
12515
      if (fp_cache[idx].LUT[x] == NULL) {
12516
         for (y = 0; y < x; y++) {
12517
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
12518
            fp_cache[idx].LUT[y] = NULL;
12519
         }
12520
         wc_ecc_del_point(fp_cache[idx].g);
12521
         fp_cache[idx].g         = NULL;
12522
         fp_cache[idx].lru_count = 0;
12523
         return MP_MEM;
12524
      }
12525
   }
12526
12527
   fp_cache[idx].LUT_set   = 0;
12528
   fp_cache[idx].lru_count = 0;
12529
12530
   return MP_OKAY;
12531
}
12532
#endif
12533
12534
#if !defined(WOLFSSL_SP_MATH)
12535
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
12536
 *
12537
 * The algorithm builds patterns in increasing bit order by first making all
12538
 * single bit input patterns, then all two bit input patterns and so on
12539
 */
12540
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
12541
    mp_int* mu)
12542
{
12543
   int err;
12544
   unsigned x, y, bitlen, lut_gap;
12545
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
12546
   int infinity;
12547
12548
#ifdef WOLFSSL_SMALL_STACK
12549
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12550
       return MEMORY_E;
12551
#endif
12552
12553
   err = mp_init(tmp);
12554
   if (err != MP_OKAY) {
12555
       err = MP_MEM;
12556
       goto errout;
12557
   }
12558
12559
   /* sanity check to make sure lut_order table is of correct size,
12560
      should compile out to a NOP if true */
12561
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
12562
       err = BAD_FUNC_ARG;
12563
       goto errout;
12564
   }
12565
12566
   /* get bitlen and round up to next multiple of FP_LUT */
12567
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12568
   x       = bitlen % FP_LUT;
12569
   if (x) {
12570
       bitlen += FP_LUT - x;
12571
   }
12572
   lut_gap = bitlen / FP_LUT;
12573
12574
   /* init the mu */
12575
   err = mp_init_copy(&fp_cache[idx].mu, mu);
12576
   if (err != MP_OKAY)
12577
       goto errout;
12578
12579
   /* copy base */
12580
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
12581
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
12582
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
12583
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
12584
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
12585
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
12586
       err = MP_MULMOD_E;
12587
       goto errout;
12588
   }
12589
12590
   /* make all single bit entries */
12591
   for (x = 1; x < FP_LUT; x++) {
12592
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
12593
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
12594
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
12595
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
12596
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
12597
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
12598
          err = MP_INIT_E;
12599
          goto errout;
12600
      } else {
12601
12602
         /* now double it bitlen/FP_LUT times */
12603
         for (y = 0; y < lut_gap; y++) {
12604
             if ((err = ecc_projective_dbl_point_safe(
12605
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12606
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12607
                                      a, modulus, mp)) != MP_OKAY) {
12608
                 goto errout;
12609
             }
12610
         }
12611
     }
12612
  }
12613
12614
   /* now make all entries in increase order of hamming weight */
12615
   for (x = 2; x <= FP_LUT; x++) {
12616
       if (err != MP_OKAY)
12617
           goto errout;
12618
       for (y = 0; y < (1UL<<FP_LUT); y++) {
12619
           if (lut_orders[y].ham != (int)x) continue;
12620
12621
           /* perform the add */
12622
           if ((err = ecc_projective_add_point_safe(
12623
                           fp_cache[idx].LUT[lut_orders[y].terma],
12624
                           fp_cache[idx].LUT[lut_orders[y].termb],
12625
                           fp_cache[idx].LUT[y], a, modulus, mp,
12626
                           &infinity)) != MP_OKAY) {
12627
               goto errout;
12628
           }
12629
       }
12630
   }
12631
12632
   /* now map all entries back to affine space to make point addition faster */
12633
   for (x = 1; x < (1UL<<FP_LUT); x++) {
12634
       if (err != MP_OKAY)
12635
           break;
12636
12637
       /* convert z to normal from montgomery */
12638
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
12639
12640
       /* invert it */
12641
       if (err == MP_OKAY)
12642
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
12643
                         fp_cache[idx].LUT[x]->z);
12644
12645
       if (err == MP_OKAY)
12646
         /* now square it */
12647
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
12648
12649
       if (err == MP_OKAY)
12650
         /* fix x */
12651
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
12652
                         fp_cache[idx].LUT[x]->x);
12653
12654
       if (err == MP_OKAY)
12655
         /* get 1/z^3 */
12656
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
12657
12658
       if (err == MP_OKAY)
12659
         /* fix y */
12660
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
12661
                         fp_cache[idx].LUT[x]->y);
12662
12663
       if (err == MP_OKAY)
12664
         /* free z */
12665
         mp_clear(fp_cache[idx].LUT[x]->z);
12666
   }
12667
12668
  errout:
12669
12670
   mp_clear(tmp);
12671
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12672
12673
   if (err == MP_OKAY) {
12674
       fp_cache[idx].LUT_set = 1;
12675
       return MP_OKAY;
12676
   }
12677
12678
   /* err cleanup */
12679
   for (y = 0; y < (1U<<FP_LUT); y++) {
12680
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
12681
      fp_cache[idx].LUT[y] = NULL;
12682
   }
12683
   wc_ecc_del_point(fp_cache[idx].g);
12684
   fp_cache[idx].g         = NULL;
12685
   fp_cache[idx].LUT_set   = 0;
12686
   fp_cache[idx].lru_count = 0;
12687
   mp_clear(&fp_cache[idx].mu);
12688
12689
   return err;
12690
}
12691
12692
/* perform a fixed point ECC mulmod */
12693
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
12694
                        mp_int* modulus, mp_digit mp, int map)
12695
{
12696
#ifdef WOLFCRYPT_HAVE_SAKKE
12697
    #define KB_SIZE 256
12698
#else
12699
    #define KB_SIZE 128
12700
#endif
12701
12702
#ifdef WOLFSSL_SMALL_STACK
12703
   unsigned char* kb = NULL;
12704
   mp_int*        tk = NULL;
12705
   mp_int*        order = NULL;
12706
#else
12707
   unsigned char kb[KB_SIZE];
12708
   mp_int        tk[1];
12709
   mp_int        order[1];
12710
#endif
12711
   int      x, err;
12712
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
12713
   int first;
12714
   int tk_zeroize = 0;
12715
12716
#ifdef WOLFSSL_SMALL_STACK
12717
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12718
   if (tk == NULL) {
12719
      err = MEMORY_E; goto done;
12720
   }
12721
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12722
   if (order == NULL) {
12723
      err = MEMORY_E; goto done;
12724
   }
12725
#endif
12726
12727
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
12728
       err = MP_INIT_E; goto done;
12729
   }
12730
12731
   if ((err = mp_copy(k, tk)) != MP_OKAY)
12732
       goto done;
12733
   tk_zeroize = 1;
12734
12735
#ifdef WOLFSSL_CHECK_MEM_ZERO
12736
   mp_memzero_add("accel_fp_mul tk", tk);
12737
#endif
12738
12739
   /* if it's smaller than modulus we fine */
12740
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
12741
      /* find order */
12742
       y = (unsigned)mp_unsigned_bin_size(modulus);
12743
      for (x = 0; ecc_sets[x].size; x++) {
12744
         if (y <= (unsigned)ecc_sets[x].size) break;
12745
      }
12746
12747
      /* back off if we are on the 521 bit curve */
12748
      if (y == 66) --x;
12749
12750
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12751
                                                MP_RADIX_HEX)) != MP_OKAY) {
12752
         goto done;
12753
      }
12754
12755
      /* k must be less than modulus */
12756
      if (mp_cmp(tk, order) != MP_LT) {
12757
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
12758
            goto done;
12759
         }
12760
      }
12761
   }
12762
12763
   /* get bitlen and round up to next multiple of FP_LUT */
12764
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12765
   x       = bitlen % FP_LUT;
12766
   if (x) {
12767
      bitlen += FP_LUT - (unsigned)x;
12768
   }
12769
   lut_gap = bitlen / FP_LUT;
12770
12771
   /* get the k value */
12772
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
12773
      err = BUFFER_E; goto done;
12774
   }
12775
12776
   /* store k */
12777
#ifdef WOLFSSL_SMALL_STACK
12778
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12779
   if (kb == NULL) {
12780
      err = MEMORY_E; goto done;
12781
   }
12782
#endif
12783
12784
   XMEMSET(kb, 0, KB_SIZE);
12785
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
12786
   #ifdef WOLFSSL_CHECK_MEM_ZERO
12787
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
12788
   #endif
12789
      /* let's reverse kb so it's little endian */
12790
      x = 0;
12791
      y = (unsigned)mp_unsigned_bin_size(tk);
12792
      if (y > 0) {
12793
          y -= 1;
12794
      }
12795
12796
      while ((unsigned)x < y) {
12797
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
12798
         ++x; --y;
12799
      }
12800
12801
      /* at this point we can start, yipee */
12802
      first = 1;
12803
      for (x = (int)lut_gap-1; x >= 0; x--) {
12804
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
12805
             by x bits from the start */
12806
          bitpos = (unsigned)x;
12807
          for (y = z = 0; y < FP_LUT; y++) {
12808
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
12809
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
12810
                                    the mult in each loop */
12811
          }
12812
12813
          /* double if not first */
12814
          if (!first) {
12815
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
12816
                                                              mp)) != MP_OKAY) {
12817
                break;
12818
             }
12819
          }
12820
12821
          /* add if not first, otherwise copy */
12822
          if (!first && z) {
12823
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
12824
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
12825
                break;
12826
             }
12827
          } else if (z) {
12828
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
12829
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
12830
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
12831
                 err = MP_MEM;
12832
                 break;
12833
             }
12834
             first = 0;
12835
          }
12836
      }
12837
   }
12838
12839
   if (err == MP_OKAY) {
12840
      (void) z; /* Acknowledge the unused assignment */
12841
      ForceZero(kb, KB_SIZE);
12842
12843
      /* map R back from projective space */
12844
      if (map) {
12845
         err = ecc_map(R, modulus, mp);
12846
      } else {
12847
         err = MP_OKAY;
12848
      }
12849
   }
12850
12851
done:
12852
   /* cleanup */
12853
   mp_clear(order);
12854
   /* Ensure it was initialized. */
12855
   if (tk_zeroize) {
12856
       mp_forcezero(tk);
12857
   }
12858
12859
#ifdef WOLFSSL_SMALL_STACK
12860
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12861
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12862
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12863
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
12864
   wc_MemZero_Check(kb, KB_SIZE);
12865
   mp_memzero_check(tk);
12866
#endif
12867
12868
#undef KB_SIZE
12869
12870
   return err;
12871
}
12872
#endif
12873
12874
#ifdef ECC_SHAMIR
12875
#if !defined(WOLFSSL_SP_MATH)
12876
/* perform a fixed point ECC mulmod */
12877
static int accel_fp_mul2add(int idx1, int idx2,
12878
                            mp_int* kA, mp_int* kB,
12879
                            ecc_point *R, mp_int* a,
12880
                            mp_int* modulus, mp_digit mp)
12881
{
12882
#define KB_SIZE 128
12883
12884
#ifdef WOLFSSL_SMALL_STACK
12885
   unsigned char* kb[2] = {NULL, NULL};
12886
   mp_int*        tka = NULL;
12887
   mp_int*        tkb = NULL;
12888
   mp_int*        order = NULL;
12889
#else
12890
   unsigned char kb[2][KB_SIZE];
12891
   mp_int        tka[1];
12892
   mp_int        tkb[1];
12893
   mp_int        order[1];
12894
#endif
12895
   int      x, err;
12896
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
12897
   int first;
12898
12899
#ifdef WOLFSSL_SMALL_STACK
12900
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12901
   if (tka == NULL) {
12902
      err = MEMORY_E; goto done;
12903
   }
12904
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12905
   if (tkb == NULL) {
12906
      err = MEMORY_E; goto done;
12907
   }
12908
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12909
   if (order == NULL) {
12910
      err = MEMORY_E; goto done;
12911
   }
12912
#endif
12913
12914
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
12915
      err = MP_INIT_E; goto done;
12916
   }
12917
12918
   /* if it's smaller than modulus we fine */
12919
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
12920
      /* find order */
12921
      y = (unsigned)mp_unsigned_bin_size(modulus);
12922
      for (x = 0; ecc_sets[x].size; x++) {
12923
         if (y <= (unsigned)ecc_sets[x].size) break;
12924
      }
12925
12926
      /* back off if we are on the 521 bit curve */
12927
      if (y == 66) --x;
12928
12929
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12930
                                                MP_RADIX_HEX)) != MP_OKAY) {
12931
         goto done;
12932
      }
12933
12934
      /* kA must be less than modulus */
12935
      if (mp_cmp(kA, order) != MP_LT) {
12936
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
12937
            goto done;
12938
         }
12939
      } else {
12940
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12941
            goto done;
12942
         }
12943
      }
12944
   } else {
12945
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12946
         goto done;
12947
      }
12948
   }
12949
#ifdef WOLFSSL_CHECK_MEM_ZERO
12950
   mp_memzero_add("accel_fp_mul2add tka", tka);
12951
#endif
12952
12953
   /* if it's smaller than modulus we fine */
12954
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
12955
      /* find order */
12956
      y = (unsigned)mp_unsigned_bin_size(modulus);
12957
      for (x = 0; ecc_sets[x].size; x++) {
12958
         if (y <= (unsigned)ecc_sets[x].size) break;
12959
      }
12960
12961
      /* back off if we are on the 521 bit curve */
12962
      if (y == 66) --x;
12963
12964
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12965
                                                MP_RADIX_HEX)) != MP_OKAY) {
12966
         goto done;
12967
      }
12968
12969
      /* kB must be less than modulus */
12970
      if (mp_cmp(kB, order) != MP_LT) {
12971
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
12972
            goto done;
12973
         }
12974
      } else {
12975
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12976
            goto done;
12977
         }
12978
      }
12979
   } else {
12980
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12981
         goto done;
12982
      }
12983
   }
12984
#ifdef WOLFSSL_CHECK_MEM_ZERO
12985
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
12986
#endif
12987
12988
   /* get bitlen and round up to next multiple of FP_LUT */
12989
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12990
   x       = bitlen % FP_LUT;
12991
   if (x) {
12992
      bitlen += FP_LUT - (unsigned)x;
12993
   }
12994
   lut_gap = bitlen / FP_LUT;
12995
12996
   /* get the k value */
12997
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
12998
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
12999
      err = BUFFER_E; goto done;
13000
   }
13001
13002
   /* store k */
13003
#ifdef WOLFSSL_SMALL_STACK
13004
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13005
   if (kb[0] == NULL) {
13006
      err = MEMORY_E; goto done;
13007
   }
13008
#endif
13009
13010
   XMEMSET(kb[0], 0, KB_SIZE);
13011
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13012
      goto done;
13013
   }
13014
#ifdef WOLFSSL_CHECK_MEM_ZERO
13015
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13016
#endif
13017
13018
   /* let's reverse kb so it's little endian */
13019
   x = 0;
13020
   y = (unsigned)mp_unsigned_bin_size(tka);
13021
   if (y > 0) {
13022
       y -= 1;
13023
   }
13024
   mp_clear(tka);
13025
   while ((unsigned)x < y) {
13026
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13027
      ++x; --y;
13028
   }
13029
13030
   /* store b */
13031
#ifdef WOLFSSL_SMALL_STACK
13032
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13033
   if (kb[1] == NULL) {
13034
      err = MEMORY_E; goto done;
13035
   }
13036
#endif
13037
13038
   XMEMSET(kb[1], 0, KB_SIZE);
13039
#ifdef WOLFSSL_CHECK_MEM_ZERO
13040
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13041
#endif
13042
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13043
      x = 0;
13044
      y = (unsigned)mp_unsigned_bin_size(tkb);
13045
      if (y > 0) {
13046
          y -= 1;
13047
      }
13048
13049
      while ((unsigned)x < y) {
13050
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13051
         ++x; --y;
13052
      }
13053
13054
      /* at this point we can start, yipee */
13055
      first = 1;
13056
      for (x = (int)lut_gap-1; x >= 0; x--) {
13057
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13058
             offset by x bits from the start */
13059
          bitpos = (unsigned)x;
13060
          for (y = zA = zB = 0; y < FP_LUT; y++) {
13061
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13062
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13063
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13064
                                      the mult in each loop */
13065
          }
13066
13067
          /* double if not first */
13068
          if (!first) {
13069
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13070
                                                              mp)) != MP_OKAY) {
13071
                break;
13072
             }
13073
13074
             /* add if not first, otherwise copy */
13075
             if (zA) {
13076
                if ((err = ecc_projective_add_point_safe(R,
13077
                                             fp_cache[idx1].LUT[zA], R, a,
13078
                                             modulus, mp, &first)) != MP_OKAY) {
13079
                   break;
13080
                }
13081
             }
13082
13083
             if (zB) {
13084
                if ((err = ecc_projective_add_point_safe(R,
13085
                                             fp_cache[idx2].LUT[zB], R, a,
13086
                                             modulus, mp, &first)) != MP_OKAY) {
13087
                   break;
13088
                }
13089
             }
13090
          } else {
13091
             if (zA) {
13092
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13093
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13094
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13095
                     err = MP_MEM;
13096
                     break;
13097
                 }
13098
                    first = 0;
13099
             }
13100
             if (zB && first == 0) {
13101
                if ((err = ecc_projective_add_point_safe(R,
13102
                                        fp_cache[idx2].LUT[zB], R, a,
13103
                                        modulus, mp, &first)) != MP_OKAY){
13104
                   break;
13105
                }
13106
             } else if (zB && first == 1) {
13107
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13108
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13109
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13110
                     err = MP_MEM;
13111
                     break;
13112
                 }
13113
                    first = 0;
13114
             }
13115
          }
13116
      }
13117
   }
13118
13119
done:
13120
   /* cleanup */
13121
   mp_forcezero(tkb);
13122
   mp_forcezero(tka);
13123
   mp_clear(order);
13124
13125
#ifdef WOLFSSL_SMALL_STACK
13126
   if (kb[0])
13127
#endif
13128
      ForceZero(kb[0], KB_SIZE);
13129
#ifdef WOLFSSL_SMALL_STACK
13130
   if (kb[1])
13131
#endif
13132
      ForceZero(kb[1], KB_SIZE);
13133
13134
#ifdef WOLFSSL_SMALL_STACK
13135
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13136
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13137
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13138
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13139
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13140
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13141
   wc_MemZero_Check(kb[1], KB_SIZE);
13142
   wc_MemZero_Check(kb[0], KB_SIZE);
13143
   mp_memzero_check(tkb);
13144
   mp_memzero_check(tka);
13145
#endif
13146
13147
#undef KB_SIZE
13148
13149
    if (err != MP_OKAY)
13150
        return err;
13151
13152
   return ecc_map(R, modulus, mp);
13153
}
13154
13155
13156
/** ECC Fixed Point mulmod global with heap hint used
13157
  Computes kA*A + kB*B = C using Shamir's Trick
13158
  A        First point to multiply
13159
  kA       What to multiple A by
13160
  B        Second point to multiply
13161
  kB       What to multiple B by
13162
  C        [out] Destination point (can overlap with A or B)
13163
  a        ECC curve parameter a
13164
  modulus  Modulus for curve
13165
  return MP_OKAY on success
13166
*/
13167
int ecc_mul2add(ecc_point* A, mp_int* kA,
13168
                ecc_point* B, mp_int* kB,
13169
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13170
{
13171
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13172
   mp_digit mp = 0;
13173
#ifdef WOLFSSL_SMALL_STACK
13174
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13175
13176
   if (mu == NULL)
13177
       return MP_MEM;
13178
#else
13179
   mp_int   mu[1];
13180
#endif
13181
13182
   err = mp_init(mu);
13183
   if (err != MP_OKAY) {
13184
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13185
       return err;
13186
   }
13187
13188
#ifndef HAVE_THREAD_LS
13189
#ifndef WOLFSSL_MUTEX_INITIALIZER
13190
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13191
        wc_InitMutex(&ecc_fp_lock);
13192
        initMutex = 1;
13193
   }
13194
#endif
13195
13196
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13197
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13198
      return BAD_MUTEX_E;
13199
   }
13200
#endif /* HAVE_THREAD_LS */
13201
13202
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13203
13204
      /* find point */
13205
      idx1 = find_base(A);
13206
13207
      /* no entry? */
13208
      if (idx1 == -1) {
13209
         /* find hole and add it */
13210
         if ((idx1 = find_hole()) >= 0) {
13211
            err = add_entry(idx1, A);
13212
         }
13213
      }
13214
      if (err == MP_OKAY && idx1 != -1) {
13215
         /* increment LRU */
13216
         ++(fp_cache[idx1].lru_count);
13217
      }
13218
13219
      if (err == MP_OKAY) {
13220
        /* find point */
13221
        idx2 = find_base(B);
13222
13223
        /* no entry? */
13224
        if (idx2 == -1) {
13225
           /* find hole and add it */
13226
           if ((idx2 = find_hole()) >= 0)
13227
              err = add_entry(idx2, B);
13228
         }
13229
      }
13230
13231
      if (err == MP_OKAY && idx2 != -1) {
13232
         /* increment LRU */
13233
         ++(fp_cache[idx2].lru_count);
13234
      }
13235
13236
      if (err == MP_OKAY) {
13237
        /* if it's >= 2 AND the LUT is not set build the LUT */
13238
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13239
           /* compute mp */
13240
           err = mp_montgomery_setup(modulus, &mp);
13241
13242
           if (err == MP_OKAY) {
13243
             mpInit = 1;
13244
             err = mp_montgomery_calc_normalization(mu, modulus);
13245
           }
13246
13247
           if (err == MP_OKAY)
13248
             /* build the LUT */
13249
             err = build_lut(idx1, a, modulus, mp, mu);
13250
        }
13251
      }
13252
13253
      if (err == MP_OKAY) {
13254
        /* if it's >= 2 AND the LUT is not set build the LUT */
13255
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13256
           if (mpInit == 0) {
13257
                /* compute mp */
13258
                err = mp_montgomery_setup(modulus, &mp);
13259
                if (err == MP_OKAY) {
13260
                    mpInit = 1;
13261
                    err = mp_montgomery_calc_normalization(mu, modulus);
13262
                }
13263
            }
13264
13265
            if (err == MP_OKAY)
13266
              /* build the LUT */
13267
              err = build_lut(idx2, a, modulus, mp, mu);
13268
        }
13269
      }
13270
13271
13272
      if (err == MP_OKAY) {
13273
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13274
                                     fp_cache[idx2].LUT_set) {
13275
           if (mpInit == 0) {
13276
              /* compute mp */
13277
              err = mp_montgomery_setup(modulus, &mp);
13278
           }
13279
           if (err == MP_OKAY)
13280
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13281
        } else {
13282
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13283
        }
13284
      }
13285
13286
      RESTORE_VECTOR_REGISTERS();
13287
13288
#ifndef HAVE_THREAD_LS
13289
    wc_UnLockMutex(&ecc_fp_lock);
13290
#endif /* HAVE_THREAD_LS */
13291
    mp_clear(mu);
13292
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13293
13294
    return err;
13295
}
13296
#endif
13297
#endif /* ECC_SHAMIR */
13298
13299
/** ECC Fixed Point mulmod global
13300
    k        The multiplicand
13301
    G        Base point to multiply
13302
    R        [out] Destination of product
13303
    a        ECC curve parameter a
13304
    modulus  The modulus for the curve
13305
    map      [boolean] If non-zero maps the point back to affine coordinates,
13306
             otherwise it's left in jacobian-montgomery form
13307
    return MP_OKAY if successful
13308
*/
13309
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13310
    mp_int* modulus, int map, void* heap)
13311
{
13312
#if !defined(WOLFSSL_SP_MATH)
13313
   int   idx, err = MP_OKAY;
13314
   mp_digit mp = 0;
13315
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13316
   int      mpSetup = 0;
13317
#ifndef HAVE_THREAD_LS
13318
   int got_ecc_fp_lock = 0;
13319
#endif
13320
13321
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13322
       return ECC_BAD_ARG_E;
13323
   }
13324
13325
   /* k can't have more bits than modulus count plus 1 */
13326
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13327
      return ECC_OUT_OF_RANGE_E;
13328
   }
13329
13330
#ifdef WOLFSSL_SMALL_STACK
13331
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13332
       return MP_MEM;
13333
#endif
13334
13335
   if (mp_init(mu) != MP_OKAY) {
13336
       err = MP_INIT_E;
13337
       goto out;
13338
   }
13339
13340
#ifndef HAVE_THREAD_LS
13341
#ifndef WOLFSSL_MUTEX_INITIALIZER
13342
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13343
        wc_InitMutex(&ecc_fp_lock);
13344
        initMutex = 1;
13345
   }
13346
#endif
13347
13348
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13349
      err = BAD_MUTEX_E;
13350
      goto out;
13351
   }
13352
   got_ecc_fp_lock = 1;
13353
#endif /* HAVE_THREAD_LS */
13354
13355
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13356
13357
      /* find point */
13358
      idx = find_base(G);
13359
13360
      /* no entry? */
13361
      if (idx == -1) {
13362
         /* find hole and add it */
13363
         idx = find_hole();
13364
13365
         if (idx >= 0)
13366
            err = add_entry(idx, G);
13367
      }
13368
      if (err == MP_OKAY && idx >= 0) {
13369
         /* increment LRU */
13370
         ++(fp_cache[idx].lru_count);
13371
      }
13372
13373
13374
      if (err == MP_OKAY) {
13375
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13376
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13377
           /* compute mp */
13378
           err = mp_montgomery_setup(modulus, &mp);
13379
13380
           if (err == MP_OKAY) {
13381
             /* compute mu */
13382
             mpSetup = 1;
13383
             err = mp_montgomery_calc_normalization(mu, modulus);
13384
           }
13385
13386
           if (err == MP_OKAY)
13387
             /* build the LUT */
13388
             err = build_lut(idx, a, modulus, mp, mu);
13389
        }
13390
      }
13391
13392
      if (err == MP_OKAY) {
13393
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13394
           if (mpSetup == 0) {
13395
              /* compute mp */
13396
              err = mp_montgomery_setup(modulus, &mp);
13397
           }
13398
           if (err == MP_OKAY)
13399
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13400
        } else {
13401
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
13402
        }
13403
      }
13404
13405
      RESTORE_VECTOR_REGISTERS();
13406
13407
  out:
13408
13409
#ifndef HAVE_THREAD_LS
13410
    if (got_ecc_fp_lock)
13411
        wc_UnLockMutex(&ecc_fp_lock);
13412
#endif /* HAVE_THREAD_LS */
13413
    mp_clear(mu);
13414
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13415
13416
    return err;
13417
13418
#else /* WOLFSSL_SP_MATH */
13419
13420
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13421
        return ECC_BAD_ARG_E;
13422
    }
13423
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13424
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13425
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13426
        return IS_POINT_E;
13427
    }
13428
13429
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13430
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13431
        int ret;
13432
        SAVE_VECTOR_REGISTERS(return _svr_ret);
13433
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13434
        RESTORE_VECTOR_REGISTERS();
13435
        return ret;
13436
    }
13437
#endif
13438
#ifndef WOLFSSL_SP_NO_256
13439
    if (mp_count_bits(modulus) == 256) {
13440
        int ret;
13441
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13442
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13443
        RESTORE_VECTOR_REGISTERS();
13444
        return ret;
13445
    }
13446
#endif
13447
#ifdef WOLFSSL_SP_384
13448
    if (mp_count_bits(modulus) == 384) {
13449
        int ret;
13450
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13451
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13452
        RESTORE_VECTOR_REGISTERS();
13453
        return ret;
13454
    }
13455
#endif
13456
#ifdef WOLFSSL_SP_521
13457
    if (mp_count_bits(modulus) == 521) {
13458
        int ret;
13459
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13460
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13461
        RESTORE_VECTOR_REGISTERS();
13462
        return ret;
13463
    }
13464
#endif
13465
    return WC_KEY_SIZE_E;
13466
#endif /* WOLFSSL_SP_MATH */
13467
}
13468
13469
/** ECC Fixed Point mulmod global
13470
    k        The multiplicand
13471
    G        Base point to multiply
13472
    R        [out] Destination of product
13473
    a        ECC curve parameter a
13474
    modulus  The modulus for the curve
13475
    map      [boolean] If non-zero maps the point back to affine coordinates,
13476
             otherwise it's left in jacobian-montgomery form
13477
    return MP_OKAY if successful
13478
*/
13479
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13480
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
13481
{
13482
#if !defined(WOLFSSL_SP_MATH)
13483
   int   idx, err = MP_OKAY;
13484
   mp_digit mp = 0;
13485
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13486
   int      mpSetup = 0;
13487
#ifndef HAVE_THREAD_LS
13488
   int got_ecc_fp_lock = 0;
13489
#endif
13490
13491
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13492
                                                                order == NULL) {
13493
       return ECC_BAD_ARG_E;
13494
   }
13495
13496
   /* k can't have more bits than order */
13497
   if (mp_count_bits(k) > mp_count_bits(order)) {
13498
      return ECC_OUT_OF_RANGE_E;
13499
   }
13500
13501
#ifdef WOLFSSL_SMALL_STACK
13502
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13503
       return MP_MEM;
13504
#endif
13505
13506
   if (mp_init(mu) != MP_OKAY) {
13507
       err = MP_INIT_E;
13508
       goto out;
13509
   }
13510
13511
#ifndef HAVE_THREAD_LS
13512
#ifndef WOLFSSL_MUTEX_INITIALIZER
13513
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13514
        wc_InitMutex(&ecc_fp_lock);
13515
        initMutex = 1;
13516
   }
13517
#endif
13518
13519
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13520
      err = BAD_MUTEX_E;
13521
      goto out;
13522
   }
13523
   got_ecc_fp_lock = 1;
13524
#endif /* HAVE_THREAD_LS */
13525
13526
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13527
13528
      /* find point */
13529
      idx = find_base(G);
13530
13531
      /* no entry? */
13532
      if (idx == -1) {
13533
         /* find hole and add it */
13534
         idx = find_hole();
13535
13536
         if (idx >= 0)
13537
            err = add_entry(idx, G);
13538
      }
13539
      if (err == MP_OKAY && idx >= 0) {
13540
         /* increment LRU */
13541
         ++(fp_cache[idx].lru_count);
13542
      }
13543
13544
13545
      if (err == MP_OKAY) {
13546
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13547
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13548
           /* compute mp */
13549
           err = mp_montgomery_setup(modulus, &mp);
13550
13551
           if (err == MP_OKAY) {
13552
             /* compute mu */
13553
             mpSetup = 1;
13554
             err = mp_montgomery_calc_normalization(mu, modulus);
13555
           }
13556
13557
           if (err == MP_OKAY)
13558
             /* build the LUT */
13559
             err = build_lut(idx, a, modulus, mp, mu);
13560
        }
13561
      }
13562
13563
      if (err == MP_OKAY) {
13564
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13565
           if (mpSetup == 0) {
13566
              /* compute mp */
13567
              err = mp_montgomery_setup(modulus, &mp);
13568
           }
13569
           if (err == MP_OKAY)
13570
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13571
        } else {
13572
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
13573
        }
13574
      }
13575
13576
      RESTORE_VECTOR_REGISTERS();
13577
13578
  out:
13579
13580
#ifndef HAVE_THREAD_LS
13581
    if (got_ecc_fp_lock)
13582
        wc_UnLockMutex(&ecc_fp_lock);
13583
#endif /* HAVE_THREAD_LS */
13584
    mp_clear(mu);
13585
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13586
13587
    return err;
13588
13589
#else /* WOLFSSL_SP_MATH */
13590
13591
    (void)rng;
13592
13593
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13594
                                                                order == NULL) {
13595
        return ECC_BAD_ARG_E;
13596
    }
13597
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13598
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13599
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13600
        return IS_POINT_E;
13601
    }
13602
13603
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13604
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13605
        int ret;
13606
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13607
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13608
        RESTORE_VECTOR_REGISTERS();
13609
        return ret;
13610
    }
13611
#endif
13612
#ifndef WOLFSSL_SP_NO_256
13613
    if (mp_count_bits(modulus) == 256) {
13614
        int ret;
13615
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13616
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13617
        RESTORE_VECTOR_REGISTERS();
13618
        return ret;
13619
    }
13620
#endif
13621
#ifdef WOLFSSL_SP_384
13622
    if (mp_count_bits(modulus) == 384) {
13623
        int ret;
13624
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13625
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13626
        RESTORE_VECTOR_REGISTERS();
13627
        return ret;
13628
    }
13629
#endif
13630
#ifdef WOLFSSL_SP_521
13631
    if (mp_count_bits(modulus) == 521) {
13632
        int ret;
13633
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13634
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13635
        RESTORE_VECTOR_REGISTERS();
13636
        return ret;
13637
    }
13638
#endif
13639
    return WC_KEY_SIZE_E;
13640
#endif /* WOLFSSL_SP_MATH */
13641
}
13642
13643
#if !defined(WOLFSSL_SP_MATH)
13644
/* helper function for freeing the cache ...
13645
   must be called with the cache mutex locked */
13646
static void wc_ecc_fp_free_cache(void)
13647
{
13648
   unsigned x, y;
13649
   for (x = 0; x < FP_ENTRIES; x++) {
13650
      if (fp_cache[x].g != NULL) {
13651
         for (y = 0; y < (1U<<FP_LUT); y++) {
13652
            wc_ecc_del_point(fp_cache[x].LUT[y]);
13653
            fp_cache[x].LUT[y] = NULL;
13654
         }
13655
         wc_ecc_del_point(fp_cache[x].g);
13656
         fp_cache[x].g         = NULL;
13657
         mp_clear(&fp_cache[x].mu);
13658
         fp_cache[x].LUT_set   = 0;
13659
         fp_cache[x].lru_count = 0;
13660
         fp_cache[x].lock = 0;
13661
      }
13662
   }
13663
}
13664
#endif
13665
13666
13667
/** Init the Fixed Point cache */
13668
void wc_ecc_fp_init(void)
13669
{
13670
#ifndef WOLFSSL_SP_MATH
13671
#ifndef HAVE_THREAD_LS
13672
#ifndef WOLFSSL_MUTEX_INITIALIZER
13673
   if (initMutex == 0) {
13674
        wc_InitMutex(&ecc_fp_lock);
13675
        initMutex = 1;
13676
   }
13677
#endif
13678
#endif
13679
#endif
13680
}
13681
13682
13683
/** Free the Fixed Point cache */
13684
WOLFSSL_ABI
13685
void wc_ecc_fp_free(void)
13686
{
13687
#if !defined(WOLFSSL_SP_MATH)
13688
#ifndef HAVE_THREAD_LS
13689
#ifndef WOLFSSL_MUTEX_INITIALIZER
13690
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13691
        wc_InitMutex(&ecc_fp_lock);
13692
        initMutex = 1;
13693
   }
13694
#endif
13695
13696
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
13697
#endif /* HAVE_THREAD_LS */
13698
13699
       wc_ecc_fp_free_cache();
13700
13701
#ifndef HAVE_THREAD_LS
13702
       wc_UnLockMutex(&ecc_fp_lock);
13703
#ifndef WOLFSSL_MUTEX_INITIALIZER
13704
       wc_FreeMutex(&ecc_fp_lock);
13705
       initMutex = 0;
13706
#endif
13707
   }
13708
#endif /* HAVE_THREAD_LS */
13709
#endif
13710
}
13711
13712
13713
#endif /* FP_ECC */
13714
13715
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
13716
4.97k
{
13717
4.97k
    int err = 0;
13718
13719
4.97k
#ifdef ECC_TIMING_RESISTANT
13720
4.97k
    if (key == NULL) {
13721
0
        err = BAD_FUNC_ARG;
13722
0
    }
13723
4.97k
    else {
13724
4.97k
        key->rng = rng;
13725
4.97k
    }
13726
#else
13727
    (void)key;
13728
    (void)rng;
13729
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
13730
#endif
13731
13732
4.97k
    return err;
13733
4.97k
}
13734
13735
#ifdef HAVE_ECC_ENCRYPT
13736
13737
13738
enum ecCliState {
13739
    ecCLI_INIT      = 1,
13740
    ecCLI_SALT_GET  = 2,
13741
    ecCLI_SALT_SET  = 3,
13742
    ecCLI_SENT_REQ  = 4,
13743
    ecCLI_RECV_RESP = 5,
13744
    ecCLI_BAD_STATE = 99
13745
};
13746
13747
enum ecSrvState {
13748
    ecSRV_INIT      = 1,
13749
    ecSRV_SALT_GET  = 2,
13750
    ecSRV_SALT_SET  = 3,
13751
    ecSRV_RECV_REQ  = 4,
13752
    ecSRV_SENT_RESP = 5,
13753
    ecSRV_BAD_STATE = 99
13754
};
13755
13756
13757
struct ecEncCtx {
13758
    const byte* kdfSalt;   /* optional salt for kdf */
13759
    const byte* kdfInfo;   /* optional info for kdf */
13760
    const byte* macSalt;   /* optional salt for mac */
13761
    word32    kdfSaltSz;   /* size of kdfSalt */
13762
    word32    kdfInfoSz;   /* size of kdfInfo */
13763
    word32    macSaltSz;   /* size of macSalt */
13764
    void*     heap;        /* heap hint for memory used */
13765
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13766
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13767
    byte      encAlgo;     /* which encryption type */
13768
    byte      kdfAlgo;     /* which key derivation function type */
13769
    byte      macAlgo;     /* which mac function type */
13770
    byte      protocol;    /* are we REQ_RESP client or server ? */
13771
    byte      cliSt;       /* protocol state, for sanity checks */
13772
    byte      srvSt;       /* protocol state, for sanity checks */
13773
    WC_RNG*   rng;
13774
};
13775
13776
/* optional set info, can be called before or after set_peer_salt */
13777
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
13778
0
{
13779
0
    if (ctx == NULL)
13780
0
        return BAD_FUNC_ARG;
13781
13782
0
    ctx->encAlgo = encAlgo;
13783
0
    ctx->kdfAlgo = kdfAlgo;
13784
0
    ctx->macAlgo = macAlgo;
13785
13786
0
    return 0;
13787
0
}
13788
13789
13790
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
13791
0
{
13792
0
    if (ctx == NULL || ctx->protocol == 0)
13793
0
        return NULL;
13794
13795
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13796
0
        if (ctx->cliSt == ecCLI_INIT) {
13797
0
            ctx->cliSt =  ecCLI_SALT_GET;
13798
0
            return ctx->clientSalt;
13799
0
        }
13800
0
        else {
13801
0
            ctx->cliSt = ecCLI_BAD_STATE;
13802
0
            return NULL;
13803
0
        }
13804
0
    }
13805
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13806
0
        if (ctx->srvSt == ecSRV_INIT) {
13807
0
            ctx->srvSt =  ecSRV_SALT_GET;
13808
0
            return ctx->serverSalt;
13809
0
        }
13810
0
        else {
13811
0
            ctx->srvSt = ecSRV_BAD_STATE;
13812
0
            return NULL;
13813
0
        }
13814
0
    }
13815
13816
0
    return NULL;
13817
0
}
13818
13819
13820
/* optional set info, can be called before or after set_peer_salt */
13821
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
13822
0
{
13823
0
    if (ctx == NULL || info == 0 || sz < 0)
13824
0
        return BAD_FUNC_ARG;
13825
13826
0
    ctx->kdfInfo   = info;
13827
0
    ctx->kdfInfoSz = (word32)sz;
13828
13829
0
    return 0;
13830
0
}
13831
13832
13833
static const char* exchange_info = "Secure Message Exchange";
13834
13835
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
13836
0
{
13837
0
    byte tmp[EXCHANGE_SALT_SZ/2];
13838
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
13839
13840
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13841
0
        return BAD_FUNC_ARG;
13842
13843
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13844
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
13845
0
        if (ctx->cliSt == ecCLI_SALT_GET)
13846
0
            ctx->cliSt =  ecCLI_SALT_SET;
13847
0
        else {
13848
0
            ctx->cliSt =  ecCLI_BAD_STATE;
13849
0
            return BAD_STATE_E;
13850
0
        }
13851
0
    }
13852
0
    else {
13853
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
13854
0
        if (ctx->srvSt == ecSRV_SALT_GET)
13855
0
            ctx->srvSt =  ecSRV_SALT_SET;
13856
0
        else {
13857
0
            ctx->srvSt =  ecSRV_BAD_STATE;
13858
0
            return BAD_STATE_E;
13859
0
        }
13860
0
    }
13861
13862
    /* mix half and half */
13863
    /* tmp stores 2nd half of client before overwrite */
13864
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
13865
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
13866
0
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
13867
13868
0
    ctx->kdfSalt   = ctx->clientSalt;
13869
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
13870
13871
0
    ctx->macSalt   = ctx->serverSalt;
13872
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
13873
13874
0
    if (ctx->kdfInfo == NULL) {
13875
        /* default info */
13876
0
        ctx->kdfInfo   = (const byte*)exchange_info;
13877
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
13878
0
    }
13879
13880
0
    return 0;
13881
0
}
13882
13883
/* Set the salt pointer into context.
13884
 *
13885
 * @param  [in, out]  ctx   ECIES context object.
13886
 * @param  [in]       salt  Salt to use with KDF.
13887
 * @param  [in]       sz    Length of salt in bytes.
13888
 * @return  0 on success.
13889
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13890
 */
13891
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13892
0
{
13893
0
    if (ctx == NULL || (salt == NULL && sz != 0))
13894
0
        return BAD_FUNC_ARG;
13895
13896
    /* truncate salt if exceeds max */
13897
0
    if (sz > EXCHANGE_SALT_SZ)
13898
0
        sz = EXCHANGE_SALT_SZ;
13899
13900
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
13901
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
13902
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13903
0
        ctx->cliSt = ecCLI_SALT_SET;
13904
0
        ctx->kdfSalt = ctx->clientSalt;
13905
0
    }
13906
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13907
0
        ctx->srvSt = ecSRV_SALT_SET;
13908
0
        ctx->kdfSalt = ctx->serverSalt;
13909
0
    }
13910
13911
0
    if (salt != NULL) {
13912
0
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
13913
0
    }
13914
0
    ctx->kdfSaltSz = sz;
13915
13916
0
    return 0;
13917
0
}
13918
13919
/* Set your own salt. By default we generate a random salt for ourselves.
13920
 * This allows overriding that after init or reset.
13921
 *
13922
 * @param  [in, out]  ctx   ECIES context object.
13923
 * @param  [in]       salt  Salt to use for ourselves
13924
 * @param  [in]       sz    Length of salt in bytes.
13925
 * @return  0 on success.
13926
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13927
 */
13928
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13929
0
{
13930
0
    byte* saltBuffer;
13931
13932
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13933
0
        return BAD_FUNC_ARG;
13934
13935
0
    if (sz > EXCHANGE_SALT_SZ)
13936
0
        sz = EXCHANGE_SALT_SZ;
13937
0
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
13938
0
        ctx->clientSalt :
13939
0
        ctx->serverSalt;
13940
0
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
13941
0
    XMEMCPY(saltBuffer, salt, sz);
13942
13943
0
    return 0;
13944
0
}
13945
13946
13947
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
13948
0
{
13949
0
    byte* saltBuffer;
13950
13951
0
    if (ctx == NULL || flags == 0)
13952
0
        return BAD_FUNC_ARG;
13953
13954
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
13955
13956
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
13957
0
}
13958
13959
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
13960
671
{
13961
671
    if (ctx) {
13962
671
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
13963
13964
671
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13965
671
        #ifdef WOLFSSL_AES_128
13966
671
            ctx->encAlgo  = ecAES_128_CBC;
13967
        #else
13968
            ctx->encAlgo  = ecAES_256_CBC;
13969
        #endif
13970
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
13971
        #ifdef WOLFSSL_AES_256
13972
            ctx->encAlgo  = ecAES_256_CTR;
13973
        #else
13974
            ctx->encAlgo  = ecAES_128_CTR;
13975
        #endif
13976
    #else
13977
        #error "No valid encryption algorithm for ECIES configured."
13978
    #endif
13979
671
        ctx->kdfAlgo  = ecHKDF_SHA256;
13980
671
        ctx->macAlgo  = ecHMAC_SHA256;
13981
671
        ctx->protocol = (byte)flags;
13982
671
        ctx->rng      = rng;
13983
13984
671
        if (flags == REQ_RESP_CLIENT)
13985
0
            ctx->cliSt = ecCLI_INIT;
13986
671
        if (flags == REQ_RESP_SERVER)
13987
0
            ctx->srvSt = ecSRV_INIT;
13988
671
    }
13989
671
}
13990
13991
13992
/* allow ecc context reset so user doesn't have to init/free for reuse */
13993
WOLFSSL_ABI
13994
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
13995
0
{
13996
0
    if (ctx == NULL || rng == NULL)
13997
0
        return BAD_FUNC_ARG;
13998
13999
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
14000
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
14001
0
}
14002
14003
14004
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14005
0
{
14006
0
    int       ret = 0;
14007
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14008
0
                                                              DYNAMIC_TYPE_ECC);
14009
14010
0
    if (ctx) {
14011
0
        ctx->protocol = (byte)flags;
14012
0
        ctx->heap     = heap;
14013
0
    }
14014
14015
0
    ret = wc_ecc_ctx_reset(ctx, rng);
14016
0
    if (ret != 0) {
14017
0
        wc_ecc_ctx_free(ctx);
14018
0
        ctx = NULL;
14019
0
    }
14020
14021
0
    return ctx;
14022
0
}
14023
14024
14025
/* alloc/init and set defaults, return new Context  */
14026
WOLFSSL_ABI
14027
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14028
0
{
14029
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14030
0
}
14031
14032
14033
/* free any resources, clear any keys */
14034
WOLFSSL_ABI
14035
void wc_ecc_ctx_free(ecEncCtx* ctx)
14036
0
{
14037
0
    if (ctx) {
14038
0
        void* heap = ctx->heap;
14039
0
        ForceZero(ctx, sizeof(ecEncCtx));
14040
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14041
0
        (void)heap;
14042
0
    }
14043
0
}
14044
14045
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14046
                             int* keysLen, word32* digestSz, word32* blockSz)
14047
671
{
14048
671
    if (ctx) {
14049
671
        switch (ctx->encAlgo) {
14050
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14051
671
            case ecAES_128_CBC:
14052
671
                *encKeySz = KEY_SIZE_128;
14053
671
                *ivSz     = IV_SIZE_128;
14054
671
                *blockSz  = WC_AES_BLOCK_SIZE;
14055
671
                break;
14056
0
            case ecAES_256_CBC:
14057
0
                *encKeySz = KEY_SIZE_256;
14058
0
                *ivSz     = IV_SIZE_128;
14059
0
                *blockSz  = WC_AES_BLOCK_SIZE;
14060
0
                break;
14061
0
        #endif
14062
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14063
0
            case ecAES_128_CTR:
14064
0
                *encKeySz = KEY_SIZE_128;
14065
0
                *ivSz     = 12;
14066
0
                *blockSz  = 1;
14067
0
                break;
14068
0
            case ecAES_256_CTR:
14069
0
                *encKeySz = KEY_SIZE_256;
14070
0
                *ivSz     = 12;
14071
0
                *blockSz  = 1;
14072
0
                break;
14073
0
        #endif
14074
0
            default:
14075
0
                return BAD_FUNC_ARG;
14076
671
        }
14077
14078
671
        switch (ctx->macAlgo) {
14079
671
            case ecHMAC_SHA256:
14080
671
                *digestSz = WC_SHA256_DIGEST_SIZE;
14081
671
                break;
14082
0
            default:
14083
0
                return BAD_FUNC_ARG;
14084
671
        }
14085
671
    } else
14086
0
        return BAD_FUNC_ARG;
14087
14088
#ifdef WOLFSSL_ECIES_OLD
14089
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14090
#else
14091
671
    *keysLen  = *encKeySz + (int)*digestSz;
14092
671
#endif
14093
14094
671
    return 0;
14095
671
}
14096
14097
14098
/* ecc encrypt with shared secret run through kdf
14099
   ctx holds non default algos and inputs
14100
   msgSz should be the right size for encAlgo, i.e., already padded
14101
   return 0 on success */
14102
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14103
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14104
349
{
14105
349
    int          ret = 0;
14106
349
    word32       blockSz = 0;
14107
349
#ifndef WOLFSSL_ECIES_OLD
14108
349
#ifndef WOLFSSL_ECIES_GEN_IV
14109
349
    byte         iv[ECC_MAX_IV_SIZE];
14110
349
#endif
14111
349
    word32       pubKeySz = 0;
14112
349
#endif
14113
349
    word32       digestSz = 0;
14114
349
    ecEncCtx     localCtx;
14115
349
#ifdef WOLFSSL_SMALL_STACK
14116
349
    byte*        sharedSecret;
14117
349
    byte*        keys;
14118
#else
14119
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14120
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14121
#else
14122
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14123
#endif
14124
    byte         keys[ECC_BUFSIZE];         /* max size */
14125
#endif
14126
349
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14127
349
    word32       sharedSz = ECC_MAXSIZE;
14128
#else
14129
    /* 'Uncompressed' byte | public key x | public key y | secret */
14130
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14131
#endif
14132
349
    int          keysLen = 0;
14133
349
    int          encKeySz = 0;
14134
349
    int          ivSz = 0;
14135
349
    int          offset = 0;         /* keys offset if doing msg exchange */
14136
349
    byte*        encKey = NULL;
14137
349
    byte*        encIv = NULL;
14138
349
    byte*        macKey = NULL;
14139
14140
349
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14141
319
                           outSz  == NULL)
14142
30
        return BAD_FUNC_ARG;
14143
14144
319
    if (ctx == NULL) {  /* use defaults */
14145
319
        ecc_ctx_init(&localCtx, 0, NULL);
14146
319
        ctx = &localCtx;
14147
319
    }
14148
14149
319
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14150
319
                            &blockSz);
14151
319
    if (ret != 0)
14152
0
        return ret;
14153
14154
319
#ifndef WOLFSSL_ECIES_OLD
14155
319
    if (!compressed) {
14156
319
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14157
319
    }
14158
0
    else {
14159
0
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14160
0
    }
14161
#else
14162
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14163
#endif
14164
14165
319
    if (ctx->protocol == REQ_RESP_SERVER) {
14166
0
        offset = keysLen;
14167
0
        keysLen *= 2;
14168
14169
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
14170
0
            return BAD_STATE_E;
14171
14172
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14173
0
    }
14174
319
    else if (ctx->protocol == REQ_RESP_CLIENT) {
14175
0
        if (ctx->cliSt != ecCLI_SALT_SET)
14176
0
            return BAD_STATE_E;
14177
14178
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14179
0
    }
14180
14181
319
    if (keysLen > ECC_BUFSIZE) /* keys size */
14182
0
        return BUFFER_E;
14183
14184
319
    if ((msgSz % blockSz) != 0)
14185
53
        return BAD_PADDING_E;
14186
14187
#ifdef WOLFSSL_ECIES_OLD
14188
    if (*outSz < (msgSz + digestSz))
14189
        return BUFFER_E;
14190
#elif defined(WOLFSSL_ECIES_GEN_IV)
14191
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14192
        return BUFFER_E;
14193
#else
14194
266
    if (*outSz < (pubKeySz + msgSz + digestSz))
14195
17
        return BUFFER_E;
14196
249
#endif
14197
14198
249
#ifdef ECC_TIMING_RESISTANT
14199
249
    if (ctx->rng != NULL && privKey->rng == NULL)
14200
0
        privKey->rng = ctx->rng;
14201
249
#endif
14202
14203
249
#ifndef WOLFSSL_ECIES_OLD
14204
249
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14205
249
#ifdef ECC_TIMING_RESISTANT
14206
249
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14207
#else
14208
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14209
#endif
14210
249
        if (ret != 0)
14211
39
            return ret;
14212
249
    }
14213
210
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14214
210
    if (ret != 0)
14215
1
        return ret;
14216
209
    out += pubKeySz;
14217
209
#endif
14218
14219
209
#ifdef WOLFSSL_SMALL_STACK
14220
209
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14221
209
    if (sharedSecret == NULL)
14222
1
        return MEMORY_E;
14223
14224
208
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14225
208
    if (keys == NULL) {
14226
1
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14227
1
        return MEMORY_E;
14228
1
    }
14229
207
#endif
14230
14231
207
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14232
14233
#ifdef WOLFSSL_ECIES_ISO18033
14234
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14235
    sharedSz -= pubKeySz;
14236
#endif
14237
14238
207
    do {
14239
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14240
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14241
        if (ret != 0)
14242
            break;
14243
    #endif
14244
207
    #ifndef WOLFSSL_ECIES_ISO18033
14245
207
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14246
    #else
14247
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14248
                                                                     &sharedSz);
14249
    #endif
14250
207
    }
14251
207
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14252
14253
207
    if (ret == 0) {
14254
    #ifdef WOLFSSL_ECIES_ISO18033
14255
        /* KDF data is encoded public key and secret. */
14256
        sharedSz += pubKeySz;
14257
    #endif
14258
202
        switch (ctx->kdfAlgo) {
14259
202
            case ecHKDF_SHA256 :
14260
202
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14261
202
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14262
202
                           keys, (word32)keysLen);
14263
202
                break;
14264
0
            case ecHKDF_SHA1 :
14265
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14266
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14267
0
                           keys, (word32)keysLen);
14268
0
                break;
14269
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14270
0
            case ecKDF_X963_SHA1 :
14271
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14272
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14273
0
                break;
14274
0
            case ecKDF_X963_SHA256 :
14275
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14276
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14277
0
                break;
14278
0
            case ecKDF_SHA1 :
14279
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14280
0
                           NULL, 0, keys, (word32)keysLen);
14281
0
                break;
14282
0
            case ecKDF_SHA256 :
14283
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14284
0
                           NULL, 0, keys, (word32)keysLen);
14285
0
                break;
14286
0
#endif
14287
14288
14289
0
            default:
14290
0
                ret = BAD_FUNC_ARG;
14291
0
                break;
14292
202
        }
14293
202
    }
14294
14295
207
    if (ret == 0) {
14296
    #ifdef WOLFSSL_ECIES_OLD
14297
        encKey = keys + offset;
14298
        encIv  = encKey + encKeySz;
14299
        macKey = encKey + encKeySz + ivSz;
14300
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14301
        encKey = keys + offset;
14302
        encIv  = out;
14303
        out += ivSz;
14304
        macKey = encKey + encKeySz;
14305
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14306
    #else
14307
189
        XMEMSET(iv, 0, (size_t)ivSz);
14308
189
        encKey = keys + offset;
14309
189
        encIv  = iv;
14310
189
        macKey = encKey + encKeySz;
14311
189
    #endif
14312
189
    }
14313
14314
207
    if (ret == 0) {
14315
189
       switch (ctx->encAlgo) {
14316
189
            case ecAES_128_CBC:
14317
189
            case ecAES_256_CBC:
14318
189
            {
14319
189
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14320
189
            #ifdef WOLFSSL_SMALL_STACK
14321
189
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14322
189
                                          DYNAMIC_TYPE_AES);
14323
189
                if (aes == NULL) {
14324
1
                    ret = MEMORY_E;
14325
1
                    break;
14326
1
                }
14327
            #else
14328
                Aes aes[1];
14329
            #endif
14330
188
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14331
188
                if (ret == 0) {
14332
188
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14333
188
                                                                AES_ENCRYPTION);
14334
188
                    if (ret == 0) {
14335
188
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14336
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14337
                                                    defined(WC_ASYNC_ENABLE_AES)
14338
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14339
                                            WC_ASYNC_FLAG_NONE);
14340
                    #endif
14341
188
                    }
14342
188
                    wc_AesFree(aes);
14343
188
                }
14344
188
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14345
        #else
14346
                ret = NOT_COMPILED_IN;
14347
        #endif
14348
188
                break;
14349
189
            }
14350
0
            case ecAES_128_CTR:
14351
0
            case ecAES_256_CTR:
14352
0
            {
14353
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14354
0
                byte ctr_iv[WC_AES_BLOCK_SIZE];
14355
            #ifndef WOLFSSL_SMALL_STACK
14356
                Aes aes[1];
14357
            #else
14358
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14359
0
                                            DYNAMIC_TYPE_AES);
14360
0
                if (aes == NULL) {
14361
0
                    ret = MEMORY_E;
14362
0
                    break;
14363
0
                }
14364
0
            #endif
14365
14366
                /* Include 4 byte counter starting at all zeros. */
14367
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14368
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14369
0
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14370
14371
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14372
0
                if (ret == 0) {
14373
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14374
0
                                                                AES_ENCRYPTION);
14375
0
                    if (ret == 0) {
14376
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
14377
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14378
                                                    defined(WC_ASYNC_ENABLE_AES)
14379
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14380
                                            WC_ASYNC_FLAG_NONE);
14381
                    #endif
14382
0
                    }
14383
0
                    wc_AesFree(aes);
14384
0
                }
14385
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14386
        #else
14387
                ret = NOT_COMPILED_IN;
14388
        #endif
14389
0
                break;
14390
0
            }
14391
0
            default:
14392
0
                ret = BAD_FUNC_ARG;
14393
0
                break;
14394
189
        }
14395
189
    }
14396
14397
207
    if (ret == 0) {
14398
188
        switch (ctx->macAlgo) {
14399
188
            case ecHMAC_SHA256:
14400
188
            {
14401
188
            #ifdef WOLFSSL_SMALL_STACK
14402
188
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14403
188
                                             DYNAMIC_TYPE_HMAC);
14404
188
                if (hmac == NULL) {
14405
1
                    ret = MEMORY_E;
14406
1
                    break;
14407
1
                }
14408
            #else
14409
                Hmac hmac[1];
14410
            #endif
14411
187
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14412
187
                if (ret == 0) {
14413
187
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14414
187
                                                         WC_SHA256_DIGEST_SIZE);
14415
187
                    if (ret == 0) {
14416
187
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14417
187
                        ret = wc_HmacUpdate(hmac, out, msgSz);
14418
                    #else
14419
                        /* IV is before encrypted message. */
14420
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
14421
                    #endif
14422
187
                    }
14423
187
                    if (ret == 0)
14424
186
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14425
187
                    if (ret == 0)
14426
186
                        ret = wc_HmacFinal(hmac, out+msgSz);
14427
187
                    wc_HmacFree(hmac);
14428
187
                }
14429
187
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14430
187
                break;
14431
188
            }
14432
14433
0
            default:
14434
0
                ret = BAD_FUNC_ARG;
14435
0
                break;
14436
188
        }
14437
188
    }
14438
14439
207
    if (ret == 0) {
14440
#ifdef WOLFSSL_ECIES_OLD
14441
        *outSz = msgSz + digestSz;
14442
#elif defined(WOLFSSL_ECIES_GEN_IV)
14443
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
14444
#else
14445
186
        *outSz = pubKeySz + msgSz + digestSz;
14446
186
#endif
14447
186
    }
14448
14449
207
    RESTORE_VECTOR_REGISTERS();
14450
14451
207
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14452
207
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14453
14454
207
    return ret;
14455
207
}
14456
14457
/* ecc encrypt with shared secret run through kdf
14458
   ctx holds non default algos and inputs
14459
   msgSz should be the right size for encAlgo, i.e., already padded
14460
   return 0 on success */
14461
WOLFSSL_ABI
14462
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14463
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14464
349
{
14465
349
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14466
349
}
14467
14468
/* ecc decrypt with shared secret run through kdf
14469
   ctx holds non default algos and inputs
14470
   return 0 on success */
14471
WOLFSSL_ABI
14472
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14473
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14474
381
{
14475
381
    int          ret = 0;
14476
381
    word32       blockSz = 0;
14477
381
#ifndef WOLFSSL_ECIES_OLD
14478
381
#ifndef WOLFSSL_ECIES_GEN_IV
14479
381
    byte         iv[ECC_MAX_IV_SIZE];
14480
381
#endif
14481
381
    word32       pubKeySz = 0;
14482
381
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
14483
381
#endif
14484
381
    word32       digestSz = 0;
14485
381
    ecEncCtx     localCtx;
14486
381
#ifdef WOLFSSL_SMALL_STACK
14487
381
    byte*        sharedSecret;
14488
381
    byte*        keys;
14489
#else
14490
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14491
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14492
#else
14493
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14494
#endif
14495
    byte         keys[ECC_BUFSIZE];         /* max size */
14496
#endif
14497
381
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14498
381
    word32       sharedSz = ECC_MAXSIZE;
14499
#else
14500
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14501
#endif
14502
381
    int          keysLen = 0;
14503
381
    int          encKeySz = 0;
14504
381
    int          ivSz = 0;
14505
381
    int          offset = 0;       /* in case using msg exchange */
14506
381
    byte*        encKey = NULL;
14507
381
    const byte*  encIv = NULL;
14508
381
    byte*        macKey = NULL;
14509
14510
14511
381
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14512
29
        return BAD_FUNC_ARG;
14513
#ifdef WOLFSSL_ECIES_OLD
14514
    if (pubKey == NULL)
14515
        return BAD_FUNC_ARG;
14516
#endif
14517
14518
352
    if (ctx == NULL) {  /* use defaults */
14519
352
        ecc_ctx_init(&localCtx, 0, NULL);
14520
352
        ctx = &localCtx;
14521
352
    }
14522
14523
352
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14524
352
                            &blockSz);
14525
352
    if (ret != 0)
14526
0
        return ret;
14527
14528
352
#ifndef WOLFSSL_ECIES_OLD
14529
352
    ret = ecc_public_key_size(privKey, &pubKeySz);
14530
352
    if (ret != 0)
14531
0
        return ret;
14532
352
#ifdef HAVE_COMP_KEY
14533
352
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14534
138
        pubKeySz = (pubKeySz / 2) + 1;
14535
138
    }
14536
352
#endif /* HAVE_COMP_KEY */
14537
352
#endif /* WOLFSSL_ECIES_OLD */
14538
14539
352
    if (ctx->protocol == REQ_RESP_CLIENT) {
14540
0
        offset = keysLen;
14541
0
        keysLen *= 2;
14542
14543
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
14544
0
            return BAD_STATE_E;
14545
14546
0
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14547
0
    }
14548
352
    else if (ctx->protocol == REQ_RESP_SERVER) {
14549
0
        if (ctx->srvSt != ecSRV_SALT_SET)
14550
0
            return BAD_STATE_E;
14551
14552
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
14553
0
    }
14554
14555
352
    if (keysLen > ECC_BUFSIZE) /* keys size */
14556
0
        return BUFFER_E;
14557
14558
#ifdef WOLFSSL_ECIES_OLD
14559
    if (((msgSz - digestSz) % blockSz) != 0)
14560
        return BAD_PADDING_E;
14561
14562
    if (*outSz < (msgSz - digestSz))
14563
        return BUFFER_E;
14564
#elif defined(WOLFSSL_ECIES_GEN_IV)
14565
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
14566
        return BAD_PADDING_E;
14567
14568
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
14569
        return BAD_FUNC_ARG;
14570
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
14571
        return BUFFER_E;
14572
#else
14573
352
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14574
122
        return BAD_PADDING_E;
14575
14576
230
    if (msgSz < pubKeySz + blockSz + digestSz)
14577
20
        return BAD_FUNC_ARG;
14578
210
    if (*outSz < (msgSz - digestSz - pubKeySz))
14579
16
        return BUFFER_E;
14580
194
#endif
14581
14582
194
#ifdef ECC_TIMING_RESISTANT
14583
194
    if (ctx->rng != NULL && privKey->rng == NULL)
14584
0
        privKey->rng = ctx->rng;
14585
194
#endif
14586
14587
194
#ifdef WOLFSSL_SMALL_STACK
14588
194
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14589
194
    if (sharedSecret == NULL) {
14590
14
    #ifndef WOLFSSL_ECIES_OLD
14591
14
        if (pubKey == peerKey)
14592
0
            wc_ecc_free(peerKey);
14593
14
    #endif
14594
14
        return MEMORY_E;
14595
14
    }
14596
14597
180
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14598
180
    if (keys == NULL) {
14599
8
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14600
8
    #ifndef WOLFSSL_ECIES_OLD
14601
8
        if (pubKey == peerKey)
14602
0
            wc_ecc_free(peerKey);
14603
8
    #endif
14604
8
        return MEMORY_E;
14605
8
    }
14606
172
#endif
14607
14608
172
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14609
14610
172
#ifndef WOLFSSL_ECIES_OLD
14611
172
    if (pubKey == NULL) {
14612
0
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
14613
0
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
14614
0
        pubKey = peerKey;
14615
0
    }
14616
172
    else {
14617
        /* if a public key was passed in we should free it here before init
14618
         * and import */
14619
172
        wc_ecc_free(pubKey);
14620
172
    }
14621
172
    if (ret == 0) {
14622
172
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14623
172
    }
14624
172
    if (ret == 0) {
14625
172
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14626
172
    }
14627
172
    if (ret == 0) {
14628
        /* Point is not MACed. */
14629
86
        msg += pubKeySz;
14630
86
        msgSz -= pubKeySz;
14631
86
    }
14632
172
#endif
14633
14634
172
    if (ret == 0) {
14635
    #ifdef WOLFSSL_ECIES_ISO18033
14636
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14637
        sharedSz -= pubKeySz;
14638
    #endif
14639
14640
86
        do {
14641
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14642
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
14643
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
14644
            if (ret != 0)
14645
                break;
14646
        #endif
14647
86
        #ifndef WOLFSSL_ECIES_ISO18033
14648
86
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14649
86
                                                                    &sharedSz);
14650
        #else
14651
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14652
                                                          pubKeySz, &sharedSz);
14653
        #endif
14654
86
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14655
86
    }
14656
172
    if (ret == 0) {
14657
    #ifdef WOLFSSL_ECIES_ISO18033
14658
        /* KDF data is encoded public key and secret. */
14659
        sharedSz += pubKeySz;
14660
    #endif
14661
77
        switch (ctx->kdfAlgo) {
14662
77
            case ecHKDF_SHA256 :
14663
77
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14664
77
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14665
77
                           keys, (word32)keysLen);
14666
77
                break;
14667
0
            case ecHKDF_SHA1 :
14668
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14669
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14670
0
                           keys, (word32)keysLen);
14671
0
                break;
14672
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14673
0
            case ecKDF_X963_SHA1 :
14674
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14675
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14676
0
                break;
14677
0
            case ecKDF_X963_SHA256 :
14678
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14679
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14680
0
                break;
14681
0
            case ecKDF_SHA1 :
14682
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14683
0
                           NULL, 0, keys, (word32)keysLen);
14684
0
                break;
14685
0
            case ecKDF_SHA256 :
14686
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14687
0
                           NULL, 0, keys, (word32)keysLen);
14688
0
                break;
14689
0
#endif
14690
14691
0
            default:
14692
0
                ret = BAD_FUNC_ARG;
14693
0
                break;
14694
77
         }
14695
77
    }
14696
14697
172
    if (ret == 0) {
14698
    #ifdef WOLFSSL_ECIES_OLD
14699
        encKey = keys + offset;
14700
        encIv  = encKey + encKeySz;
14701
        macKey = encKey + encKeySz + ivSz;
14702
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14703
        encKey = keys + offset;
14704
        encIv  = msg;
14705
        msg   += ivSz;
14706
        msgSz -= ivSz;
14707
        macKey = encKey + encKeySz;
14708
    #else
14709
77
        XMEMSET(iv, 0, (size_t)ivSz);
14710
77
        encKey = keys + offset;
14711
77
        encIv  = iv;
14712
77
        macKey = encKey + encKeySz;
14713
77
    #endif
14714
14715
77
        switch (ctx->macAlgo) {
14716
77
            case ecHMAC_SHA256:
14717
77
            {
14718
77
                byte verify[WC_SHA256_DIGEST_SIZE];
14719
77
            #ifdef WOLFSSL_SMALL_STACK
14720
77
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14721
77
                                             DYNAMIC_TYPE_HMAC);
14722
77
                if (hmac == NULL) {
14723
0
                    ret = MEMORY_E;
14724
0
                    break;
14725
0
                }
14726
            #else
14727
                Hmac hmac[1];
14728
            #endif
14729
77
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14730
77
                if (ret == 0) {
14731
77
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14732
77
                                                         WC_SHA256_DIGEST_SIZE);
14733
77
                    if (ret == 0)
14734
77
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14735
77
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
14736
                    #else
14737
                        /* IV is before encrypted message. */
14738
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
14739
                    #endif
14740
77
                    if (ret == 0)
14741
77
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14742
14743
77
                    if (ret == 0)
14744
77
                        ret = wc_HmacFinal(hmac, verify);
14745
77
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14746
77
                                                             digestSz) != 0)) {
14747
56
                        ret = HASH_TYPE_E;
14748
56
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14749
56
                    }
14750
14751
77
                    wc_HmacFree(hmac);
14752
77
                }
14753
77
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14754
77
                break;
14755
77
            }
14756
14757
0
            default:
14758
0
                ret = BAD_FUNC_ARG;
14759
0
                break;
14760
77
        }
14761
77
    }
14762
14763
172
    if (ret == 0) {
14764
21
        switch (ctx->encAlgo) {
14765
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14766
21
            case ecAES_128_CBC:
14767
21
            case ecAES_256_CBC:
14768
21
            {
14769
21
            #ifdef WOLFSSL_SMALL_STACK
14770
21
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14771
21
                                          DYNAMIC_TYPE_AES);
14772
21
                if (aes == NULL) {
14773
0
                    ret = MEMORY_E;
14774
0
                    break;
14775
0
                }
14776
            #else
14777
                Aes aes[1];
14778
            #endif
14779
21
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14780
21
                if (ret == 0) {
14781
21
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14782
21
                                                                AES_DECRYPTION);
14783
21
                    if (ret == 0) {
14784
21
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
14785
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14786
                                                    defined(WC_ASYNC_ENABLE_AES)
14787
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14788
                                                            WC_ASYNC_FLAG_NONE);
14789
                    #endif
14790
21
                    }
14791
21
                    wc_AesFree(aes);
14792
21
                }
14793
21
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14794
21
                break;
14795
21
            }
14796
0
        #endif
14797
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14798
0
            case ecAES_128_CTR:
14799
0
            case ecAES_256_CTR:
14800
0
            {
14801
0
            #ifdef WOLFSSL_SMALL_STACK
14802
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14803
0
                                          DYNAMIC_TYPE_AES);
14804
0
                if (aes == NULL) {
14805
0
                    ret = MEMORY_E;
14806
0
                    break;
14807
0
                }
14808
             #else
14809
                Aes aes[1];
14810
             #endif
14811
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14812
0
                if (ret == 0) {
14813
0
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
14814
                    /* Make a 16 byte IV from the bytes passed in. */
14815
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14816
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14817
0
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14818
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14819
0
                                                                AES_ENCRYPTION);
14820
0
                    if (ret == 0) {
14821
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
14822
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14823
                                                    defined(WC_ASYNC_ENABLE_AES)
14824
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14825
                                                            WC_ASYNC_FLAG_NONE);
14826
                    #endif
14827
0
                    }
14828
0
                    wc_AesFree(aes);
14829
0
                }
14830
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14831
0
                break;
14832
0
            }
14833
0
        #endif
14834
0
            default:
14835
0
                ret = BAD_FUNC_ARG;
14836
0
                break;
14837
21
        }
14838
21
    }
14839
14840
172
    if (ret == 0)
14841
21
       *outSz = msgSz - digestSz;
14842
14843
172
    RESTORE_VECTOR_REGISTERS();
14844
14845
172
#ifndef WOLFSSL_ECIES_OLD
14846
172
    if (pubKey == peerKey)
14847
0
        wc_ecc_free(peerKey);
14848
172
#endif
14849
172
#ifdef WOLFSSL_SMALL_STACK
14850
172
#ifndef WOLFSSL_ECIES_OLD
14851
172
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14852
172
#endif
14853
172
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14854
172
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14855
172
#endif
14856
14857
172
    return ret;
14858
172
}
14859
14860
14861
#endif /* HAVE_ECC_ENCRYPT */
14862
14863
14864
#ifdef HAVE_COMP_KEY
14865
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
14866
    !defined(WOLFSSL_CRYPTOCELL)
14867
14868
#ifndef WOLFSSL_SP_MATH
14869
#if !defined(SQRTMOD_USE_MOD_EXP)
14870
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
14871
 */
14872
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
14873
{
14874
#ifdef WOLFSSL_SMALL_STACK
14875
    mp_int*  a1 = NULL;
14876
    mp_int*  n1 = NULL;
14877
#else
14878
    mp_int   a1[1], n1[1];
14879
#endif
14880
    int      res;
14881
    int      s = 1;
14882
    int      k;
14883
    mp_int*  t[2];
14884
    mp_int*  ts;
14885
    mp_digit residue;
14886
14887
    if (mp_isneg(a) == MP_YES) {
14888
        return MP_VAL;
14889
    }
14890
    if (mp_isneg(n) == MP_YES) {
14891
        return MP_VAL;
14892
    }
14893
    if (mp_iseven(n) == MP_YES) {
14894
        return MP_VAL;
14895
    }
14896
14897
#ifdef WOLFSSL_SMALL_STACK
14898
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14899
    if (a1 == NULL) {
14900
        return MP_MEM;
14901
    }
14902
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14903
    if (n1 == NULL) {
14904
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
14905
        return MP_MEM;
14906
    }
14907
#endif
14908
14909
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
14910
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14911
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14912
        return res;
14913
    }
14914
14915
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
14916
14917
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
14918
        goto done;
14919
    }
14920
14921
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
14922
        goto done;
14923
    }
14924
14925
    t[0] = a1;
14926
    t[1] = n1;
14927
14928
    /* Keep reducing until first number is 0. */
14929
    while (!mp_iszero(t[0])) {
14930
        /* Divide by 2 until odd. */
14931
        k = mp_cnt_lsb(t[0]);
14932
        if (k > 0) {
14933
            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
            residue = t[1]->dp[0] & 7;
14939
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
14940
                s = -s;
14941
            }
14942
        }
14943
14944
        /* Swap t[0] and t[1]. */
14945
        ts   = t[0];
14946
        t[0] = t[1];
14947
        t[1] = ts;
14948
14949
        /* Negate s if both numbers == 3 mod 4. */
14950
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
14951
             s = -s;
14952
        }
14953
14954
        /* Reduce first number modulo second. */
14955
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
14956
            res = mp_sub(t[0], t[1], t[0]);
14957
        }
14958
        else {
14959
            res = mp_mod(t[0], t[1], t[0]);
14960
        }
14961
        if (res != MP_OKAY) {
14962
            goto done;
14963
        }
14964
    }
14965
14966
    /* When the two numbers have divisors in common. */
14967
    if (!mp_isone(t[1])) {
14968
        s = 0;
14969
    }
14970
    *c = s;
14971
14972
done:
14973
14974
    RESTORE_VECTOR_REGISTERS();
14975
14976
    /* cleanup */
14977
    mp_clear(n1);
14978
    mp_clear(a1);
14979
14980
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14981
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14982
14983
  return res;
14984
}
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
{
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
  int res, legendre, done = 0;
15043
  mp_digit i;
15044
#ifdef WOLFSSL_SMALL_STACK
15045
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15046
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15047
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15048
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15049
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15050
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15051
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15052
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15053
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15054
  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
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15060
15061
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15062
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15063
    res = MP_INIT_E;
15064
    goto out;
15065
  }
15066
15067
#ifdef WOLFSSL_SMALL_STACK
15068
  if ((t1 == NULL) ||
15069
      (C == NULL) ||
15070
      (Q == NULL) ||
15071
      (S == NULL) ||
15072
      (Z == NULL) ||
15073
      (M == NULL) ||
15074
      (T == NULL) ||
15075
      (R == NULL) ||
15076
      (N == NULL) ||
15077
      (two == NULL)) {
15078
    res = MP_MEM;
15079
    goto out;
15080
  }
15081
#endif
15082
15083
  /* first handle the simple cases n = 0 or n = 1 */
15084
  if (mp_cmp_d(n, 0) == MP_EQ) {
15085
    mp_zero(ret);
15086
    res = MP_OKAY;
15087
    goto out;
15088
  }
15089
  if (mp_cmp_d(n, 1) == MP_EQ) {
15090
    res = mp_set(ret, 1);
15091
    goto out;
15092
  }
15093
15094
  /* prime must be odd */
15095
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15096
    res = MP_VAL;
15097
    goto out;
15098
  }
15099
15100
  /* reduce n to less than prime */
15101
  res = mp_mod(n, prime, N);
15102
  if (res != MP_OKAY) {
15103
    goto out;
15104
  }
15105
  /* when N is zero, sqrt is zero */
15106
  if (mp_iszero(N)) {
15107
    mp_set(ret, 0);
15108
    goto out;
15109
  }
15110
15111
  /* is quadratic non-residue mod prime */
15112
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15113
    goto out;
15114
  }
15115
  if (legendre == -1) {
15116
    res = MP_VAL;
15117
    goto out;
15118
  }
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
  res = mp_mod_d(prime, 4, &i);
15125
  if (res == MP_OKAY && i == 3) {
15126
    res = mp_add_d(prime, 1, t1);
15127
15128
    if (res == MP_OKAY)
15129
      res = mp_div_2(t1, t1);
15130
    if (res == MP_OKAY)
15131
      res = mp_div_2(t1, t1);
15132
    if (res == MP_OKAY)
15133
      res = mp_exptmod(N, t1, prime, ret);
15134
15135
    done = 1;
15136
  }
15137
15138
  /* NOW: TonelliShanks algorithm */
15139
  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
    res = mp_copy(prime, Q);
15145
    if (res == MP_OKAY)
15146
      res = mp_sub_d(Q, 1, Q);
15147
15148
    /* S = 0 */
15149
    if (res == MP_OKAY)
15150
      mp_zero(S);
15151
15152
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15153
      /* Q = Q / 2 */
15154
      res = mp_div_2(Q, Q);
15155
15156
      /* S = S + 1 */
15157
      if (res == MP_OKAY)
15158
        res = mp_add_d(S, 1, S);
15159
    }
15160
15161
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15162
    /* Z = 2 */
15163
    if (res == MP_OKAY)
15164
      res = mp_set_int(Z, 2);
15165
15166
    while (res == MP_OKAY) {
15167
      res = mp_jacobi(Z, prime, &legendre);
15168
      if (res == MP_OKAY && legendre == -1)
15169
        break;
15170
15171
#if defined(WOLFSSL_CUSTOM_CURVES)
15172
      /* P224R1 succeeds with a value of 11. */
15173
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15174
        /* This is to clamp the loop in case 'prime' is not really prime */
15175
        res = MP_VAL;
15176
        break;
15177
      }
15178
#endif
15179
15180
      /* Z = Z + 1 */
15181
      if (res == MP_OKAY)
15182
        res = mp_add_d(Z, 1, Z);
15183
15184
      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
        res = MP_VAL;
15187
        break;
15188
      }
15189
    }
15190
15191
    /* C = Z ^ Q mod prime */
15192
    if (res == MP_OKAY)
15193
      res = mp_exptmod(Z, Q, prime, C);
15194
15195
    /* t1 = (Q + 1) / 2 */
15196
    if (res == MP_OKAY)
15197
      res = mp_add_d(Q, 1, t1);
15198
    if (res == MP_OKAY)
15199
      res = mp_div_2(t1, t1);
15200
15201
    /* R = n ^ ((Q + 1) / 2) mod prime */
15202
    if (res == MP_OKAY)
15203
      res = mp_exptmod(N, t1, prime, R);
15204
15205
    /* T = n ^ Q mod prime */
15206
    if (res == MP_OKAY)
15207
      res = mp_exptmod(N, Q, prime, T);
15208
15209
    /* M = S */
15210
    if (res == MP_OKAY)
15211
      res = mp_copy(S, M);
15212
15213
    if (res == MP_OKAY)
15214
      res = mp_set_int(two, 2);
15215
15216
    while (res == MP_OKAY && done == 0) {
15217
      res = mp_copy(T, t1);
15218
15219
      /* reduce to 1 and count */
15220
      i = 0;
15221
      while (res == MP_OKAY) {
15222
        if (mp_cmp_d(t1, 1) == MP_EQ)
15223
            break;
15224
        res = mp_exptmod(t1, two, prime, t1);
15225
        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
          res = MP_VAL;
15228
          break;
15229
        }
15230
        if (res == MP_OKAY)
15231
          i++;
15232
      }
15233
      if (res == MP_OKAY && i == 0) {
15234
        res = mp_copy(R, ret);
15235
        done = 1;
15236
      }
15237
15238
      if (done == 0) {
15239
        /* t1 = 2 ^ (M - i - 1) */
15240
        if (res == MP_OKAY)
15241
          res = mp_sub_d(M, i, t1);
15242
        if (res == MP_OKAY)
15243
          res = mp_sub_d(t1, 1, t1);
15244
        if (res == MP_OKAY)
15245
          res = mp_exptmod(two, t1, prime, t1);
15246
15247
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15248
        if (res == MP_OKAY)
15249
          res = mp_exptmod(C, t1, prime, t1);
15250
15251
        /* C = (t1 * t1) mod prime */
15252
        if (res == MP_OKAY)
15253
          res = mp_sqrmod(t1, prime, C);
15254
15255
        /* R = (R * t1) mod prime */
15256
        if (res == MP_OKAY)
15257
          res = mp_mulmod(R, t1, prime, R);
15258
15259
        /* T = (T * C) mod prime */
15260
        if (res == MP_OKAY)
15261
          res = mp_mulmod(T, C, prime, T);
15262
15263
        /* M = i */
15264
        if (res == MP_OKAY)
15265
          res = mp_set(M, i);
15266
      }
15267
    }
15268
  }
15269
15270
  out:
15271
15272
  RESTORE_VECTOR_REGISTERS();
15273
15274
#ifdef WOLFSSL_SMALL_STACK
15275
  if (t1) {
15276
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15277
      mp_clear(t1);
15278
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15279
  }
15280
  if (C) {
15281
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15282
      mp_clear(C);
15283
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15284
  }
15285
  if (Q) {
15286
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15287
      mp_clear(Q);
15288
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15289
  }
15290
  if (S) {
15291
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15292
      mp_clear(S);
15293
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15294
  }
15295
  if (Z) {
15296
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15297
      mp_clear(Z);
15298
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15299
  }
15300
  if (M) {
15301
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15302
      mp_clear(M);
15303
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15304
  }
15305
  if (T) {
15306
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15307
      mp_clear(T);
15308
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15309
  }
15310
  if (R) {
15311
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15312
      mp_clear(R);
15313
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15314
  }
15315
  if (N) {
15316
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15317
      mp_clear(N);
15318
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15319
  }
15320
  if (two) {
15321
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15322
      mp_clear(two);
15323
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15324
  }
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
  return res;
15341
#endif
15342
}
15343
#endif /* !WOLFSSL_SP_MATH */
15344
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
15345
15346
#ifdef HAVE_ECC_KEY_EXPORT
15347
/* export public ECC key in ANSI X9.63 format compressed */
15348
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
15349
2.48k
{
15350
2.48k
   word32 numlen;
15351
2.48k
   int    ret = MP_OKAY;
15352
15353
2.48k
   if (key == NULL || outLen == NULL)
15354
0
       return BAD_FUNC_ARG;
15355
15356
2.48k
   if (key->type == ECC_PRIVATEKEY_ONLY)
15357
62
       return ECC_PRIVATEONLY_E;
15358
15359
2.42k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15360
388
       return ECC_BAD_ARG_E;
15361
388
   }
15362
15363
2.03k
   numlen = (word32)key->dp->size;
15364
15365
2.03k
   if (*outLen < (1 + numlen)) {
15366
1.01k
      *outLen = 1 + numlen;
15367
1.01k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15368
1.01k
   }
15369
15370
1.01k
   if (out == NULL)
15371
0
       return BAD_FUNC_ARG;
15372
15373
1.01k
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15374
0
       return ECC_BAD_ARG_E;
15375
15376
   /* store first byte */
15377
1.01k
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15378
15379
   /* pad and store x */
15380
1.01k
   XMEMSET(out+1, 0, numlen);
15381
1.01k
   ret = mp_to_unsigned_bin(
15382
1.01k
       key->pubkey.x,
15383
1.01k
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15384
1.01k
   *outLen = 1 + numlen;
15385
15386
1.01k
   return ret;
15387
1.01k
}
15388
#endif /* HAVE_ECC_KEY_EXPORT */
15389
#endif /* HAVE_COMP_KEY */
15390
15391
#ifdef HAVE_OID_ENCODING
15392
int wc_ecc_oid_cache_init(void)
15393
{
15394
    int ret = 0;
15395
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15396
    ret = wc_InitMutex(&ecc_oid_cache_lock);
15397
#endif
15398
    return ret;
15399
}
15400
15401
void wc_ecc_oid_cache_free(void)
15402
{
15403
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15404
    wc_FreeMutex(&ecc_oid_cache_lock);
15405
#endif
15406
}
15407
#endif /* HAVE_OID_ENCODING */
15408
15409
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
15410
6.53k
{
15411
6.53k
    int x;
15412
6.53k
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
15413
#ifdef HAVE_OID_ENCODING
15414
    oid_cache_t* o = NULL;
15415
#endif
15416
15417
6.53k
    if (oidSum == 0) {
15418
34
        return BAD_FUNC_ARG;
15419
34
    }
15420
15421
#ifdef HAVE_OID_ENCODING
15422
    #ifndef WOLFSSL_MUTEX_INITIALIZER
15423
        /* extra sanity check if wolfCrypt_Init not called */
15424
        if (eccOidLockInit == 0) {
15425
            wc_InitMutex(&ecc_oid_cache_lock);
15426
            eccOidLockInit = 1;
15427
        }
15428
    #endif
15429
15430
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
15431
        return BAD_MUTEX_E;
15432
    }
15433
#endif
15434
15435
    /* find matching OID sum (based on encoded value) */
15436
28.9k
    for (x = 0; ecc_sets[x].size != 0; x++) {
15437
26.3k
        if (ecc_sets[x].oidSum == oidSum) {
15438
        #ifdef HAVE_OID_ENCODING
15439
            /* check cache */
15440
            ret = 0;
15441
            o = &ecc_oid_cache[x];
15442
            if (o->oidSz == 0) {
15443
                o->oidSz = sizeof(o->oid);
15444
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
15445
                                                            o->oid, &o->oidSz);
15446
            }
15447
            if (oidSz) {
15448
                *oidSz = o->oidSz;
15449
            }
15450
            if (oid) {
15451
                *oid = o->oid;
15452
            }
15453
15454
            /* on success return curve id */
15455
            if (ret == 0) {
15456
                ret = ecc_sets[x].id;
15457
            }
15458
            break;
15459
        #else
15460
3.96k
            if (oidSz) {
15461
3.96k
                *oidSz = ecc_sets[x].oidSz;
15462
3.96k
            }
15463
3.96k
            if (oid) {
15464
3.96k
                *oid = ecc_sets[x].oid;
15465
3.96k
            }
15466
3.96k
            ret = ecc_sets[x].id;
15467
3.96k
            break;
15468
3.96k
        #endif
15469
3.96k
        }
15470
26.3k
    }
15471
15472
#ifdef HAVE_OID_ENCODING
15473
    wc_UnLockMutex(&ecc_oid_cache_lock);
15474
#endif
15475
15476
6.50k
    return ret;
15477
6.53k
}
15478
15479
#ifdef WOLFSSL_CUSTOM_CURVES
15480
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15481
{
15482
    if (key == NULL || dp == NULL) {
15483
        return BAD_FUNC_ARG;
15484
    }
15485
15486
    key->idx = ECC_CUSTOM_IDX;
15487
    key->dp = dp;
15488
15489
    return 0;
15490
}
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 */