Coverage Report

Created: 2026-02-14 07:18

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/keygen/secret.
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
80.3k
#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
186k
const ecc_set_type *wc_ecc_get_sets(void) {
1410
186k
    return ecc_sets;
1411
186k
}
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
255k
    #define ECC_CURVE_FIELD_PRIME   0x01
1497
255k
    #define ECC_CURVE_FIELD_AF      0x02
1498
#ifdef USE_ECC_B_PARAM
1499
253k
    #define ECC_CURVE_FIELD_BF      0x04
1500
#endif
1501
232k
    #define ECC_CURVE_FIELD_ORDER   0x08
1502
192k
    #define ECC_CURVE_FIELD_GX      0x10
1503
192k
    #define ECC_CURVE_FIELD_GY      0x20
1504
#ifdef USE_ECC_B_PARAM
1505
5.12k
    #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
17.5k
        mp_int* spec_ints = NULL;                                       \
1591
17.5k
        ecc_curve_spec curve_lcl;                                       \
1592
17.5k
        ecc_curve_spec* curve = &curve_lcl;                             \
1593
17.5k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1594
17.5k
        curve->spec_count = intcount
1595
1596
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1597
15.8k
    do {                                                                \
1598
15.8k
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1599
15.8k
                            DYNAMIC_TYPE_ECC);                          \
1600
15.8k
        if (spec_ints == NULL)                                          \
1601
15.8k
            (err) = MEMORY_E;                                           \
1602
15.8k
        else {                                                          \
1603
15.5k
            curve->spec_ints = spec_ints;                               \
1604
15.5k
            (err) = MP_OKAY;                                            \
1605
15.5k
        }                                                               \
1606
15.8k
    } while (0)
1607
#endif
1608
    #define FREE_CURVE_SPECS()                                          \
1609
15.8k
        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
68.5k
{
1646
68.5k
    if (curve == NULL) {
1647
0
        return;
1648
0
    }
1649
1650
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1651
56.5k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1652
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1653
56.5k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1654
68.5k
#ifdef USE_ECC_B_PARAM
1655
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1656
55.6k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1657
68.5k
#endif
1658
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1659
46.5k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1660
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1661
28.6k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1662
68.5k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1663
28.6k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1664
1665
68.5k
    curve->load_mask = 0;
1666
68.5k
}
1667
1668
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1669
72.2k
{
1670
72.2k
    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
72.2k
        wc_ecc_curve_cache_free_spec(curve);
1681
72.2k
    #endif
1682
72.2k
    }
1683
72.2k
}
1684
1685
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1686
    mp_int** dst, byte mask)
1687
86.8k
{
1688
86.8k
    int err;
1689
1690
86.8k
#ifndef ECC_CACHE_CURVE
1691
    /* get mp_int from temp */
1692
86.8k
    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
86.8k
    *dst = &curve->spec_ints[curve->spec_use++];
1701
86.8k
#endif
1702
86.8k
#endif
1703
1704
#ifdef WOLFSSL_SP_MATH_ALL
1705
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1706
#else
1707
86.8k
    err = mp_init(*dst);
1708
86.8k
#endif
1709
86.8k
    if (err == MP_OKAY) {
1710
86.8k
        curve->load_mask |= mask;
1711
1712
86.8k
        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
86.8k
    }
1719
86.8k
    return err;
1720
86.8k
}
1721
1722
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1723
    byte load_mask)
1724
66.9k
{
1725
66.9k
    int ret = 0;
1726
66.9k
    ecc_curve_spec* curve;
1727
66.9k
    byte load_items = 0; /* mask of items to load */
1728
#ifdef ECC_CACHE_CURVE
1729
    int x;
1730
#endif
1731
1732
66.9k
    if (dp == NULL || pCurve == NULL)
1733
0
        return BAD_FUNC_ARG;
1734
1735
#ifdef ECC_CACHE_CURVE
1736
    x = wc_ecc_get_curve_idx(dp->id);
1737
    if (x == ECC_CURVE_INVALID)
1738
        return ECC_BAD_ARG_E;
1739
1740
#if !defined(SINGLE_THREADED)
1741
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1742
    if (ret != 0) {
1743
        return ret;
1744
    }
1745
#endif
1746
1747
#ifdef WOLFSSL_NO_MALLOC
1748
    curve = &ecc_curve_spec_cache[x];
1749
#else
1750
    /* make sure cache has been allocated */
1751
    if (ecc_curve_spec_cache[x] == NULL
1752
    #ifdef WOLFSSL_CUSTOM_CURVES
1753
        || dp->id == ECC_CURVE_CUSTOM
1754
    #endif
1755
    ) {
1756
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1757
        if (curve == NULL) {
1758
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1759
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1760
        #endif
1761
            return MEMORY_E;
1762
        }
1763
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1764
1765
        /* set curve pointer to cache */
1766
    #ifdef WOLFSSL_CUSTOM_CURVES
1767
        if (dp->id != ECC_CURVE_CUSTOM)
1768
    #endif
1769
        {
1770
            ecc_curve_spec_cache[x] = curve;
1771
        }
1772
    }
1773
    else {
1774
        curve = ecc_curve_spec_cache[x];
1775
    }
1776
#endif /* WOLFSSL_NO_MALLOC */
1777
1778
    /* return new or cached curve */
1779
    *pCurve = curve;
1780
#else
1781
66.9k
    curve = *pCurve;
1782
66.9k
#endif /* ECC_CACHE_CURVE */
1783
1784
    /* make sure the curve is initialized */
1785
66.9k
    if (curve->dp != dp) {
1786
66.9k
        curve->load_mask = 0;
1787
1788
    #ifdef ECC_CACHE_CURVE
1789
        curve->prime = &curve->prime_lcl;
1790
        curve->Af = &curve->Af_lcl;
1791
        #ifdef USE_ECC_B_PARAM
1792
            curve->Bf = &curve->Bf_lcl;
1793
        #endif
1794
        curve->order = &curve->order_lcl;
1795
        curve->Gx = &curve->Gx_lcl;
1796
        curve->Gy = &curve->Gy_lcl;
1797
    #endif
1798
66.9k
    }
1799
66.9k
    curve->dp = dp; /* set dp info */
1800
1801
    /* determine items to load */
1802
66.9k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1803
66.9k
    curve->load_mask |= load_items;
1804
1805
    /* load items */
1806
66.9k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1807
56.5k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1808
56.5k
            ECC_CURVE_FIELD_PRIME);
1809
66.9k
    if (load_items & ECC_CURVE_FIELD_AF)
1810
56.5k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1811
56.5k
            ECC_CURVE_FIELD_AF);
1812
66.9k
#ifdef USE_ECC_B_PARAM
1813
66.9k
    if (load_items & ECC_CURVE_FIELD_BF)
1814
55.6k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1815
55.6k
            ECC_CURVE_FIELD_BF);
1816
66.9k
#endif
1817
66.9k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1818
46.5k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1819
46.5k
            ECC_CURVE_FIELD_ORDER);
1820
66.9k
    if (load_items & ECC_CURVE_FIELD_GX)
1821
28.6k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1822
28.6k
            ECC_CURVE_FIELD_GX);
1823
66.9k
    if (load_items & ECC_CURVE_FIELD_GY)
1824
28.6k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1825
28.6k
            ECC_CURVE_FIELD_GY);
1826
1827
    /* check for error */
1828
66.9k
    if (ret != 0) {
1829
185
        wc_ecc_curve_free(curve);
1830
185
        ret = MP_READ_E;
1831
185
    }
1832
1833
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1834
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1835
#endif
1836
1837
66.9k
    return ret;
1838
66.9k
}
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
12.0k
{
1884
12.0k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1885
12.0k
    if (curve_idx == ECC_CURVE_INVALID)
1886
55
        return NULL;
1887
12.0k
    return ecc_sets[curve_idx].name;
1888
12.0k
}
1889
1890
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1891
57.5k
{
1892
57.5k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1893
0
        return BAD_FUNC_ARG;
1894
0
    }
1895
1896
57.5k
    if (keysize > ECC_MAXSIZE) {
1897
880
        return ECC_BAD_ARG_E;
1898
880
    }
1899
1900
    /* handle custom case */
1901
56.7k
    if (key->idx != ECC_CUSTOM_IDX) {
1902
56.3k
        int x;
1903
1904
        /* default values */
1905
56.3k
        key->idx = 0;
1906
56.3k
        key->dp = NULL;
1907
1908
        /* find ecc_set based on curve_id or key size */
1909
801k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1910
801k
            if (curve_id > ECC_CURVE_DEF) {
1911
699k
                if (curve_id == ecc_sets[x].id)
1912
50.5k
                  break;
1913
699k
            }
1914
102k
            else if (keysize <= ecc_sets[x].size) {
1915
5.62k
                break;
1916
5.62k
            }
1917
801k
        }
1918
56.3k
        if (ecc_sets[x].size == 0) {
1919
177
            WOLFSSL_MSG("ECC Curve not found");
1920
177
            return ECC_CURVE_OID_E;
1921
177
        }
1922
1923
56.1k
        key->idx = x;
1924
56.1k
        key->dp  = &ecc_sets[x];
1925
56.1k
    }
1926
1927
56.5k
    return 0;
1928
56.7k
}
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.69k
{
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.69k
    int modBits = mp_count_bits(modulus);
2281
2282
1.69k
    (void)a;
2283
1.69k
    (void)mp;
2284
2285
1.69k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2286
1.69k
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2287
357
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2288
357
                                            R->x, R->y, R->z);
2289
357
    }
2290
1.33k
#endif
2291
1.33k
#ifndef WOLFSSL_SP_NO_256
2292
1.33k
    if (modBits == 256) {
2293
341
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2294
341
                                         R->x, R->y, R->z);
2295
341
    }
2296
995
#endif
2297
995
#ifdef WOLFSSL_SP_384
2298
995
    if (modBits == 384) {
2299
475
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2300
475
                                         R->x, R->y, R->z);
2301
475
    }
2302
520
#endif
2303
520
#ifdef WOLFSSL_SP_521
2304
520
    if (modBits == 521) {
2305
520
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2306
520
                                         R->x, R->y, R->z);
2307
520
    }
2308
0
#endif
2309
0
    return ECC_BAD_ARG_E;
2310
520
#endif
2311
520
}
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
3.02k
{
2316
3.02k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2317
0
        return ECC_BAD_ARG_E;
2318
0
    }
2319
2320
3.02k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2321
3.00k
        mp_cmp(P->y, modulus) != MP_LT ||
2322
2.96k
        mp_cmp(P->z, modulus) != MP_LT ||
2323
2.96k
        mp_cmp(Q->x, modulus) != MP_LT ||
2324
2.92k
        mp_cmp(Q->y, modulus) != MP_LT ||
2325
2.88k
        mp_cmp(Q->z, modulus) != MP_LT) {
2326
140
        return ECC_OUT_OF_RANGE_E;
2327
140
    }
2328
2329
2.88k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2330
3.02k
}
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
981
{
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
981
    int modBits = mp_count_bits(modulus);
2649
2650
981
    (void)a;
2651
981
    (void)mp;
2652
2653
981
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2654
981
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2655
198
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2656
198
    }
2657
783
#endif
2658
783
#ifndef WOLFSSL_SP_NO_256
2659
783
    if (modBits == 256) {
2660
325
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2661
325
    }
2662
458
#endif
2663
458
#ifdef WOLFSSL_SP_384
2664
458
    if (modBits == 384) {
2665
240
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2666
240
    }
2667
218
#endif
2668
218
#ifdef WOLFSSL_SP_521
2669
218
    if (modBits == 521) {
2670
218
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2671
218
    }
2672
0
#endif
2673
0
    return ECC_BAD_ARG_E;
2674
218
#endif
2675
218
}
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.63k
{
2680
4.63k
    if (P == NULL || R == NULL || modulus == NULL)
2681
0
        return ECC_BAD_ARG_E;
2682
2683
4.63k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2684
4.60k
        mp_cmp(P->y, modulus) != MP_LT ||
2685
4.56k
        mp_cmp(P->z, modulus) != MP_LT) {
2686
71
        return ECC_OUT_OF_RANGE_E;
2687
71
    }
2688
2689
4.56k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2690
4.63k
}
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.59k
{
2706
2.59k
    int err = MP_OKAY;
2707
2.59k
    (void)ct;
2708
2709
2.59k
    if (P == NULL || modulus == NULL){
2710
0
        return ECC_BAD_ARG_E;
2711
0
    }
2712
2.59k
    {
2713
        #if !defined(WOLFSSL_SP_MATH)
2714
        DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2715
        DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2716
        #ifdef ALT_ECC_SIZE
2717
        DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2718
        DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2719
        DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2720
        #endif
2721
        mp_int *x, *y, *z;
2722
2723
        /* special case for point at infinity */
2724
        if (mp_cmp_d(P->z, 0) == MP_EQ) {
2725
            err = mp_set(P->x, 0);
2726
            if (err == MP_OKAY)
2727
                err = mp_set(P->y, 0);
2728
            if (err == MP_OKAY)
2729
                err = mp_set(P->z, 1);
2730
            return err;
2731
        }
2732
2733
        #ifdef WOLFSSL_SMALL_STACK
2734
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2735
        if (P->key != NULL) {
2736
            t1 = P->key->t1;
2737
            t2 = P->key->t2;
2738
        #ifdef ALT_ECC_SIZE
2739
            rx = P->key->x;
2740
            ry = P->key->y;
2741
            rz = P->key->z;
2742
        #endif
2743
        }
2744
        else
2745
        #endif /* WOLFSSL_SMALL_STACK_CACHE */
2746
        #endif
2747
        {
2748
            NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2749
            NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2750
        #ifdef MP_INT_SIZE_CHECK_NULL
2751
            if (t1 == NULL || t2 == NULL) {
2752
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2753
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2754
                return MEMORY_E;
2755
            }
2756
        #endif
2757
        #ifdef ALT_ECC_SIZE
2758
            NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2759
            NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2760
            NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2761
        #ifdef MP_INT_SIZE_CHECK_NULL
2762
            if (rx == NULL || ry == NULL || rz == NULL) {
2763
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2764
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2765
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2766
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2767
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2768
                return MEMORY_E;
2769
            }
2770
        #endif
2771
        #endif
2772
        }
2773
2774
        err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2775
        if (err == MP_OKAY) {
2776
            err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2777
        }
2778
        if (err != MP_OKAY) {
2779
        #ifdef WOLFSSL_SMALL_STACK
2780
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2781
            if (P->key == NULL)
2782
        #endif
2783
        #endif
2784
            {
2785
            #ifdef ALT_ECC_SIZE
2786
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2787
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2788
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2789
            #endif
2790
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2791
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2792
            }
2793
            return MEMORY_E;
2794
        }
2795
2796
        #ifdef ALT_ECC_SIZE
2797
        /* Use local stack variable */
2798
        x = rx;
2799
        y = ry;
2800
        z = rz;
2801
2802
        err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2803
        if (err == MP_OKAY) {
2804
            err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2805
        }
2806
        if (err == MP_OKAY) {
2807
            err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2808
        }
2809
        if (err != MP_OKAY) {
2810
            goto done;
2811
        }
2812
2813
        if (err == MP_OKAY)
2814
            err = mp_copy(P->x, x);
2815
        if (err == MP_OKAY)
2816
            err = mp_copy(P->y, y);
2817
        if (err == MP_OKAY)
2818
            err = mp_copy(P->z, z);
2819
2820
        if (err != MP_OKAY) {
2821
            goto done;
2822
        }
2823
        #else
2824
        /* Use destination directly */
2825
        x = P->x;
2826
        y = P->y;
2827
        z = P->z;
2828
        #endif
2829
2830
        /* get 1/z */
2831
        if (err == MP_OKAY) {
2832
        #if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2833
                        defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2834
            if (ct) {
2835
                err = mp_invmod_mont_ct(z, modulus, t1, mp);
2836
                if (err == MP_OKAY)
2837
                    err = mp_montgomery_reduce(t1, modulus, mp);
2838
            }
2839
            else
2840
        #endif
2841
            {
2842
                /* first map z back to normal */
2843
                err = mp_montgomery_reduce(z, modulus, mp);
2844
                if (err == MP_OKAY)
2845
                    err = mp_invmod(z, modulus, t1);
2846
            }
2847
        }
2848
2849
        /* get 1/z^2 and 1/z^3 */
2850
        if (err == MP_OKAY)
2851
            err = mp_sqr(t1, t2);
2852
        if (err == MP_OKAY)
2853
            err = mp_mod(t2, modulus, t2);
2854
        if (err == MP_OKAY)
2855
            err = mp_mul(t1, t2, t1);
2856
        if (err == MP_OKAY)
2857
            err = mp_mod(t1, modulus, t1);
2858
2859
        /* multiply against x/y */
2860
        if (err == MP_OKAY)
2861
            err = mp_mul(x, t2, x);
2862
        if (err == MP_OKAY)
2863
            err = mp_montgomery_reduce(x, modulus, mp);
2864
        if (err == MP_OKAY)
2865
            err = mp_mul(y, t1, y);
2866
        if (err == MP_OKAY)
2867
            err = mp_montgomery_reduce(y, modulus, mp);
2868
2869
        if (err == MP_OKAY)
2870
            err = mp_set(z, 1);
2871
2872
        #ifdef ALT_ECC_SIZE
2873
        /* return result */
2874
        if (err == MP_OKAY)
2875
            err = mp_copy(x, P->x);
2876
        if (err == MP_OKAY)
2877
            err = mp_copy(y, P->y);
2878
        if (err == MP_OKAY)
2879
            err = mp_copy(z, P->z);
2880
2881
        done:
2882
        #endif
2883
2884
        /* clean up */
2885
        mp_clear(t1);
2886
        mp_clear(t2);
2887
2888
        #ifdef WOLFSSL_SMALL_STACK
2889
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2890
        if (P->key == NULL)
2891
        #endif
2892
        #endif
2893
        {
2894
        #ifdef ALT_ECC_SIZE
2895
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2896
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2897
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2898
        #endif
2899
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2900
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2901
        }
2902
2903
        return err;
2904
        /* end !defined(WOLFSSL_SP_MATH) */
2905
2906
        #else
2907
        /* begin defined(WOLFSSL_SP_MATH) */
2908
2.59k
        if (P == NULL || modulus == NULL)
2909
0
            return ECC_BAD_ARG_E;
2910
2911
2.59k
        (void)mp;
2912
2.59k
        (void)ct;
2913
2914
2.59k
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2915
2.59k
        if ((mp_count_bits(modulus) == 256) &&
2916
1.19k
            (!mp_is_bit_set(modulus, 224))) {
2917
547
            err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
2918
547
        }
2919
        #elif !defined(WOLFSSL_SP_NO_256)
2920
        if (mp_count_bits(modulus) == 256) {
2921
            err = sp_ecc_map_256(P->x, P->y, P->z);
2922
        }
2923
        #elif defined(WOLFSSL_SP_384)
2924
        if (mp_count_bits(modulus) == 384) {
2925
            err = sp_ecc_map_384(P->x, P->y, P->z);
2926
        }
2927
        #elif defined(WOLFSSL_SP_521)
2928
        if (mp_count_bits(modulus) == 521) {
2929
            err = sp_ecc_map_521(P->x, P->y, P->z);
2930
        }
2931
        #else
2932
        err = ECC_BAD_ARG_E;
2933
        #endif
2934
2935
2.59k
        WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
2936
2.59k
    return err;
2937
2.59k
#endif /* WOLFSSL_SP_MATH */
2938
2.59k
    }
2939
2.59k
}
2940
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2941
2942
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2943
20.7k
{
2944
20.7k
    return ecc_map_ex(P, modulus, mp, 0);
2945
20.7k
}
2946
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2947
2948
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2949
    !defined(WOLFSSL_CRYPTOCELL)
2950
#if !defined(WOLFSSL_SP_MATH)
2951
2952
#ifndef ECC_TIMING_RESISTANT
2953
2954
/* size of sliding window, don't change this! */
2955
#define WINSIZE  4
2956
#define M_POINTS 8
2957
2958
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2959
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2960
{
2961
   int      err = MP_OKAY;
2962
   int      i;
2963
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2964
   int      bitcnt = 0, mode = 0, digidx = 0;
2965
   mp_digit buf;
2966
   int      infinity;
2967
2968
   (void)rng;
2969
2970
   /* calc the M tab, which holds kG for k==8..15 */
2971
   /* M[0] == 8G */
2972
   if (err == MP_OKAY)
2973
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2974
   if (err == MP_OKAY)
2975
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2976
   if (err == MP_OKAY)
2977
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2978
2979
   /* now find (8+k)G for k=1..7 */
2980
   if (err == MP_OKAY)
2981
       for (j = 9; j < 16; j++) {
2982
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2983
                                                        modulus, mp, &infinity);
2984
           if (err != MP_OKAY) break;
2985
       }
2986
2987
   /* setup sliding window */
2988
   if (err == MP_OKAY) {
2989
       mode   = 0;
2990
       bitcnt = 1;
2991
       buf    = 0;
2992
       digidx = mp_get_digit_count(k) - 1;
2993
       bitcpy = bitbuf = 0;
2994
       first  = 1;
2995
2996
       /* perform ops */
2997
       for (;;) {
2998
           /* grab next digit as required */
2999
           if (--bitcnt == 0) {
3000
               if (digidx == -1) {
3001
                   break;
3002
               }
3003
               buf    = mp_get_digit(k, digidx);
3004
               bitcnt = (int) DIGIT_BIT;
3005
               --digidx;
3006
           }
3007
3008
           /* grab the next msb from the ltiplicand */
3009
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3010
           buf <<= 1;
3011
3012
           /* skip leading zero bits */
3013
           if (mode == 0 && i == 0)
3014
               continue;
3015
3016
           /* if the bit is zero and mode == 1 then we double */
3017
           if (mode == 1 && i == 0) {
3018
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3019
               if (err != MP_OKAY) break;
3020
               continue;
3021
           }
3022
3023
           /* else we add it to the window */
3024
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3025
           mode = 2;
3026
3027
           if (bitcpy == WINSIZE) {
3028
               /* if this is the first window we do a simple copy */
3029
               if (first == 1) {
3030
                   /* R = kG [k = first window] */
3031
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3032
                   if (err != MP_OKAY) break;
3033
3034
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3035
                   if (err != MP_OKAY) break;
3036
3037
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3038
                   first = 0;
3039
               } else {
3040
                   /* normal window */
3041
                   /* ok window is filled so double as required and add  */
3042
                   /* double first */
3043
                   for (j = 0; j < WINSIZE; j++) {
3044
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3045
                                                                            mp);
3046
                       if (err != MP_OKAY) break;
3047
                   }
3048
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3049
3050
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3051
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3052
                                                     a, modulus, mp, &infinity);
3053
               }
3054
               if (err != MP_OKAY) break;
3055
               /* empty window and reset */
3056
               bitcpy = bitbuf = 0;
3057
               mode = 1;
3058
           }
3059
       }
3060
   }
3061
3062
   /* if bits remain then double/add */
3063
   if (err == MP_OKAY) {
3064
       if (mode == 2 && bitcpy > 0) {
3065
           /* double then add */
3066
           for (j = 0; j < bitcpy; j++) {
3067
               /* only double if we have had at least one add first */
3068
               if (first == 0) {
3069
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3070
                   if (err != MP_OKAY) break;
3071
               }
3072
3073
               bitbuf <<= 1;
3074
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3075
                   if (first == 1) {
3076
                       /* first add, so copy */
3077
                       err = mp_copy(tG->x, R->x);
3078
                       if (err != MP_OKAY) break;
3079
3080
                       err = mp_copy(tG->y, R->y);
3081
                       if (err != MP_OKAY) break;
3082
3083
                       err = mp_copy(tG->z, R->z);
3084
                       if (err != MP_OKAY) break;
3085
                       first = 0;
3086
                   } else {
3087
                       /* then add */
3088
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3089
                                                                 mp, &infinity);
3090
                       if (err != MP_OKAY) break;
3091
                   }
3092
               }
3093
           }
3094
       }
3095
   }
3096
3097
   #undef WINSIZE
3098
3099
   return err;
3100
}
3101
3102
#else
3103
3104
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3105
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3106
{
3107
    int err = MP_OKAY;
3108
3109
    err = mp_montgomery_calc_normalization(mu, modulus);
3110
    /* Generate random value to multiply into p->z. */
3111
    if (err == MP_OKAY)
3112
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3113
    /* Convert to montogmery form. */
3114
    if (err == MP_OKAY)
3115
        err = mp_mulmod(ty, mu, modulus, ty);
3116
    /* Multiply random value into p->z. */
3117
    if (err == MP_OKAY)
3118
        err = mp_mul(p->z, ty, p->z);
3119
    if (err == MP_OKAY)
3120
        err = mp_montgomery_reduce(p->z, modulus, mp);
3121
    /* Square random value for X (X' = X / Z^2). */
3122
    if (err == MP_OKAY)
3123
        err = mp_sqr(ty, tx);
3124
    if (err == MP_OKAY)
3125
        err = mp_montgomery_reduce(tx, modulus, mp);
3126
    /* Multiply square of random by random value for Y. */
3127
    if (err == MP_OKAY)
3128
        err = mp_mul(ty, tx, ty);
3129
    if (err == MP_OKAY)
3130
        err = mp_montgomery_reduce(ty, modulus, mp);
3131
    /* Multiply square into X. */
3132
    if (err == MP_OKAY)
3133
        err = mp_mul(p->x, tx, p->x);
3134
    if (err == MP_OKAY)
3135
        err = mp_montgomery_reduce(p->x, modulus, mp);
3136
    /* Multiply cube into Y (Y' = Y / Z^3). */
3137
    if (err == MP_OKAY)
3138
        err = mp_mul(p->y, ty, p->y);
3139
    if (err == MP_OKAY)
3140
        err = mp_montgomery_reduce(p->y, modulus, mp);
3141
3142
    return err;
3143
}
3144
3145
#ifndef WC_PROTECT_ENCRYPTED_MEM
3146
#define M_POINTS 3
3147
3148
/* Joye double-add ladder.
3149
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3150
 * by Marc Joye (2007)
3151
 *
3152
 * Algorithm 1':
3153
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3154
 *   Output: Q = kP
3155
 *   1: R[0] = P; R[1] = P
3156
 *   2: for j = 1 to t-1 do
3157
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3158
 *   4: end for
3159
 *   5: b = k[0]; R[b] = R[b] - P
3160
 *   6: return R[0]
3161
 *
3162
 * Assumes: k < order.
3163
 */
3164
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3165
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3166
{
3167
    int      err = MP_OKAY;
3168
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3169
    int      i;
3170
    int      j = 1;
3171
    int      cnt = DIGIT_BIT;
3172
    int      t = 0;
3173
    mp_digit b;
3174
    mp_digit v = 0;
3175
    mp_int*  kt = R[2]->x;
3176
#ifndef WC_NO_CACHE_RESISTANT
3177
    /* First bit always 1 (fix at end) and swap equals first bit */
3178
    int      swap = 1;
3179
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3180
#endif
3181
    int      infinity;
3182
3183
#ifndef WC_NO_CACHE_RESISTANT
3184
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3185
    if (err == MP_OKAY)
3186
        err = mp_init(tmp);
3187
#endif
3188
3189
    /* Step 1: R[0] = P; R[1] = P */
3190
    /* R[0] = P */
3191
    if (err == MP_OKAY)
3192
        err = mp_copy(P->x, R[0]->x);
3193
    if (err == MP_OKAY)
3194
        err = mp_copy(P->y, R[0]->y);
3195
    if (err == MP_OKAY)
3196
        err = mp_copy(P->z, R[0]->z);
3197
3198
    /* R[1] = P */
3199
    if (err == MP_OKAY)
3200
        err = mp_copy(P->x, R[1]->x);
3201
    if (err == MP_OKAY)
3202
        err = mp_copy(P->y, R[1]->y);
3203
    if (err == MP_OKAY)
3204
        err = mp_copy(P->z, R[1]->z);
3205
3206
    /* Randomize z ordinates to obfuscate timing. */
3207
    if ((err == MP_OKAY) && (rng != NULL))
3208
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3209
    if ((err == MP_OKAY) && (rng != NULL))
3210
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3211
3212
    if (err == MP_OKAY) {
3213
        /* Order could be one greater than the size of the modulus. */
3214
        t = mp_count_bits(modulus) + 1;
3215
        v = k->dp[0] >> 1;
3216
        if (cnt > t) {
3217
            cnt = t;
3218
        }
3219
        err = mp_copy(k, kt);
3220
    }
3221
    if (err == MP_OKAY) {
3222
        err = mp_grow(kt, (int)modulus->used + 1);
3223
    }
3224
    /* Step 2: for j = 1 to t-1 do */
3225
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3226
        if (--cnt == 0) {
3227
            v = kt->dp[j++];
3228
            cnt = DIGIT_BIT;
3229
        }
3230
3231
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3232
        b = v & 1;
3233
        v >>= 1;
3234
#ifdef WC_NO_CACHE_RESISTANT
3235
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3236
        if (err == MP_OKAY) {
3237
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3238
                                                        modulus, mp, &infinity);
3239
        }
3240
#else
3241
        /* Swap R[0] and R[1] if other index is needed. */
3242
        swap ^= (int)b;
3243
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3244
            tmp);
3245
        if (err == MP_OKAY) {
3246
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3247
                tmp);
3248
        }
3249
        if (err == MP_OKAY) {
3250
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3251
                tmp);
3252
        }
3253
        swap = (int)b;
3254
3255
        if (err == MP_OKAY)
3256
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3257
        if (err == MP_OKAY) {
3258
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3259
                                                                 mp, &infinity);
3260
        }
3261
#endif /* WC_NO_CACHE_RESISTANT */
3262
    }
3263
    /* Step 4: end for */
3264
#ifndef WC_NO_CACHE_RESISTANT
3265
    /* Swap back if last bit is 0. */
3266
    swap ^= 1;
3267
    if (err == MP_OKAY) {
3268
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3269
            tmp);
3270
    }
3271
    if (err == MP_OKAY) {
3272
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3273
            tmp);
3274
    }
3275
    if (err == MP_OKAY) {
3276
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3277
            tmp);
3278
    }
3279
#endif
3280
3281
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3282
    /* R[2] = -P */
3283
    if (err == MP_OKAY)
3284
        err = mp_copy(P->x, R[2]->x);
3285
    if (err == MP_OKAY)
3286
        err = mp_sub(modulus, P->y, R[2]->y);
3287
    if (err == MP_OKAY)
3288
        err = mp_copy(P->z, R[2]->z);
3289
    /* Subtract point by adding negative. */
3290
    if (err == MP_OKAY) {
3291
        b = k->dp[0] & 1;
3292
#ifdef WC_NO_CACHE_RESISTANT
3293
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3294
                                                                     &infinity);
3295
#else
3296
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3297
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3298
            tmp);
3299
        if (err == MP_OKAY) {
3300
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3301
                (int)b, tmp);
3302
        }
3303
        if (err == MP_OKAY) {
3304
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3305
                (int)b, tmp);
3306
        }
3307
        if (err == MP_OKAY)
3308
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3309
                                                                 mp, &infinity);
3310
        /* Swap back if necessary. */
3311
        if (err == MP_OKAY) {
3312
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3313
                (int)b, tmp);
3314
        }
3315
        if (err == MP_OKAY) {
3316
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3317
                (int)b, tmp);
3318
        }
3319
        if (err == MP_OKAY) {
3320
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3321
                (int)b, tmp);
3322
        }
3323
#endif
3324
    }
3325
3326
    /* Step 6: return R[0] */
3327
    if (err == MP_OKAY)
3328
        err = mp_copy(R[0]->x, Q->x);
3329
    if (err == MP_OKAY)
3330
        err = mp_copy(R[0]->y, Q->y);
3331
    if (err == MP_OKAY)
3332
        err = mp_copy(R[0]->z, Q->z);
3333
3334
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3335
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3336
#endif
3337
3338
    return err;
3339
}
3340
3341
#else
3342
/* Number of points to allocate for use during scalar multiplication. */
3343
#define M_POINTS        5
3344
/* Last of the points is used as a temporary during calculations. */
3345
#define TMP_IDX         M_POINTS - 1
3346
3347
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3348
    int digits, int m)
3349
{
3350
    int i;
3351
3352
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3353
    /* Only using positive numbers in ECC operations. */
3354
    ra->sign = 0;
3355
    rb->sign = 0;
3356
#endif
3357
    /* Don't store 0 when mask is 0, it will be in a register. */
3358
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3359
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3360
    for (i = 0; i < digits; i++) {
3361
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3362
                    a->dp[i];
3363
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3364
                    b->dp[i];
3365
    }
3366
}
3367
3368
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3369
    ecc_point* b, int digits, int m)
3370
{
3371
    /* Conditionally swap each ordinate. */
3372
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3373
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3374
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3375
}
3376
3377
/* Joye double-add ladder.
3378
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3379
 * by Marc Joye (2007)
3380
 *
3381
 * Algorithm 1':
3382
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3383
 *   Output: Q = kP
3384
 *   1: R[0] = P; R[1] = P
3385
 *   2: for j = 1 to t-1 do
3386
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3387
 *   4: end for
3388
 *   5: b = k[0]; R[b] = R[b] - P
3389
 *   6: return R[0]
3390
 *
3391
 * Assumes: k < order.
3392
 */
3393
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3394
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3395
{
3396
    int          err = MP_OKAY;
3397
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3398
    int          i;
3399
    int          j = 1;
3400
    int          cnt;
3401
    int          t = 0;
3402
    mp_int*      kt = R[TMP_IDX]->x;
3403
    /* First bit always 1 (fix at end) and swap equals first bit */
3404
    register int swap = 1;
3405
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3406
    int          set = 0;
3407
    int          infinity;
3408
3409
    /* Step 1: R[0] = P; R[1] = P */
3410
    /* R[0] = P */
3411
    if (err == MP_OKAY)
3412
        err = mp_copy(P->x, R[0]->x);
3413
    if (err == MP_OKAY)
3414
        err = mp_copy(P->y, R[0]->y);
3415
    if (err == MP_OKAY)
3416
        err = mp_copy(P->z, R[0]->z);
3417
3418
    /* R[1] = P */
3419
    if (err == MP_OKAY)
3420
        err = mp_copy(P->x, R[1]->x);
3421
    if (err == MP_OKAY)
3422
        err = mp_copy(P->y, R[1]->y);
3423
    if (err == MP_OKAY)
3424
        err = mp_copy(P->z, R[1]->z);
3425
3426
    /* Randomize z ordinates to obfuscate timing. */
3427
    if ((err == MP_OKAY) && (rng != NULL))
3428
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3429
                           R[TMP_IDX]->y, kt);
3430
    if ((err == MP_OKAY) && (rng != NULL))
3431
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3432
                           R[TMP_IDX]->y, kt);
3433
3434
    if (err == MP_OKAY) {
3435
        /* Order could be one greater than the size of the modulus. */
3436
        t = mp_count_bits(modulus) + 1;
3437
        err = mp_copy(k, kt);
3438
    }
3439
    if (err == MP_OKAY) {
3440
        err = mp_grow(kt, modulus->used + 1);
3441
    }
3442
    /* Step 2: for j = 1 to t-1 do */
3443
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3444
        if (++cnt == DIGIT_BIT) {
3445
            j++;
3446
            cnt = 0;
3447
        }
3448
3449
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3450
        /* Swap R[0] and R[1] if other index is needed. */
3451
        /* Ensure 'swap' changes when shifted word is 0. */
3452
        swap += (kt->dp[j] >> cnt) + 2;
3453
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3454
                              R[set + 0], R[set + 1], modulus->used, swap);
3455
        /* Change to operate on set copied into. */
3456
        set = 2 - set;
3457
        /* Ensure 'swap' changes to a previously unseen value. */
3458
        swap += (kt->dp[j] >> cnt) + swap;
3459
3460
        /* R[0] = 2*R[0] */
3461
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3462
                                            mp);
3463
        if (err == MP_OKAY) {
3464
            /* R[0] = R[1] + R[0] */
3465
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3466
                                         R[set + 0], a, modulus, mp, &infinity);
3467
        }
3468
        /*  R[1]->z * 2 - same point. */
3469
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3470
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3471
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3472
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3473
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3474
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3475
    }
3476
    /* Step 4: end for */
3477
    /* Swap back if last bit is 0. */
3478
    /* Ensure 'swap' changes. */
3479
    swap += 1;
3480
    if (err == MP_OKAY) {
3481
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3482
                              R[set + 0], R[set + 1], modulus->used, swap);
3483
        set = 2 - set;
3484
    }
3485
3486
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3487
    /* R[TMP_IDX] = -P */
3488
    if (err == MP_OKAY)
3489
        err = mp_copy(P->x, R[TMP_IDX]->x);
3490
    if (err == MP_OKAY)
3491
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3492
    if (err == MP_OKAY)
3493
        err = mp_copy(P->z, R[TMP_IDX]->z);
3494
    /* Subtract point by adding negative. */
3495
    if (err == MP_OKAY) {
3496
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3497
         * Last bit of k->dp[0] is being used to make decision to swap.
3498
         */
3499
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3500
                              R[set + 0], R[set + 1], modulus->used,
3501
                              (int)k->dp[0]);
3502
        set = 2 - set;
3503
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3504
                                            a, modulus, mp, &infinity);
3505
        /* Swap back if necessary. */
3506
        if (err == MP_OKAY) {
3507
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3508
                                  R[set + 0], R[set + 1], modulus->used,
3509
                                  (int)k->dp[0]);
3510
            set = 2 - set;
3511
        }
3512
    }
3513
3514
    /* Step 6: return R[0] */
3515
    if (err == MP_OKAY)
3516
        err = mp_copy(R[set + 0]->x, Q->x);
3517
    if (err == MP_OKAY)
3518
        err = mp_copy(R[set + 0]->y, Q->y);
3519
    if (err == MP_OKAY)
3520
        err = mp_copy(R[set + 0]->z, Q->z);
3521
3522
    return err;
3523
}
3524
3525
#endif
3526
3527
#endif
3528
3529
/* Convert the point to montgomery form.
3530
 *
3531
 * @param  [in]   p        Point to convert.
3532
 * @param  [out]  r        Point in montgomery form.
3533
 * @param  [in]   modulus  Modulus of ordinates.
3534
 * @return  0 on success.
3535
 * @return  -ve on failure.
3536
 */
3537
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3538
                             void* heap)
3539
{
3540
   int err = MP_OKAY;
3541
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3542
3543
   (void)heap;
3544
3545
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3546
#ifdef MP_INT_SIZE_CHECK_NULL
3547
   if (mu == NULL)
3548
       err = MEMORY_E;
3549
#endif
3550
   if (err == MP_OKAY)
3551
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3552
   if (err == MP_OKAY) {
3553
       err = mp_montgomery_calc_normalization(mu, modulus);
3554
3555
       if (err == MP_OKAY) {
3556
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3557
               err = mp_copy(p->x, r->x);
3558
               if (err == MP_OKAY)
3559
                   err = mp_copy(p->y, r->y);
3560
               if (err == MP_OKAY)
3561
                   err = mp_copy(p->z, r->z);
3562
           }
3563
           else {
3564
               err = mp_mulmod(p->x, mu, modulus, r->x);
3565
               if (err == MP_OKAY)
3566
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3567
               if (err == MP_OKAY)
3568
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3569
           }
3570
       }
3571
3572
       mp_clear(mu);
3573
   }
3574
3575
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3576
   return err;
3577
}
3578
3579
#ifdef WOLFSSL_SMALL_STACK_CACHE
3580
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3581
{
3582
   int err = MP_OKAY;
3583
3584
   (void)heap;
3585
3586
   if (key == NULL) {
3587
       return ECC_BAD_ARG_E;
3588
   }
3589
3590
   XMEMSET(key, 0, sizeof(*key));
3591
3592
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3593
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3594
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3595
#ifdef ALT_ECC_SIZE
3596
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3597
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3598
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3599
#endif
3600
   if (key->t1 == NULL || key->t2 == NULL
3601
#ifdef ALT_ECC_SIZE
3602
      || key->x == NULL || key->y == NULL || key->z == NULL
3603
#endif
3604
   ) {
3605
       err = MEMORY_E;
3606
   }
3607
   if (err == 0) {
3608
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3609
   }
3610
   if (err == 0) {
3611
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3612
   }
3613
#ifdef ALT_ECC_SIZE
3614
   if (err == 0) {
3615
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3616
   }
3617
   if (err == 0) {
3618
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3619
   }
3620
   if (err == 0) {
3621
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3622
   }
3623
#endif
3624
#else
3625
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3626
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3627
#ifdef ALT_ECC_SIZE
3628
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3629
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3630
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3631
#endif
3632
   if (key->t1 == NULL || key->t2 == NULL
3633
#ifdef ALT_ECC_SIZE
3634
      || key->x == NULL || key->y == NULL || key->z == NULL
3635
#endif
3636
   ) {
3637
       err = MEMORY_E;
3638
   }
3639
#endif
3640
3641
   return err;
3642
}
3643
3644
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3645
{
3646
    (void)heap;
3647
3648
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3649
#ifdef ALT_ECC_SIZE
3650
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3651
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3652
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3653
#endif
3654
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3655
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3656
#else
3657
#ifdef ALT_ECC_SIZE
3658
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3659
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3660
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3661
#endif
3662
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3663
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3664
#endif
3665
}
3666
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3667
#endif /* !WOLFSSL_SP_MATH */
3668
3669
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3670
/**
3671
   Perform a point multiplication
3672
   k    The scalar to multiply by
3673
   G    The base point
3674
   R    [out] Destination for kG
3675
   a    ECC curve parameter a
3676
   modulus  The modulus of the field the ECC curve is in
3677
   map      Boolean whether to map back to affine or not
3678
                (1==map, 0 == leave in projective)
3679
   return MP_OKAY on success
3680
*/
3681
#ifdef FP_ECC
3682
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3683
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3684
                             void* heap)
3685
#else
3686
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3687
                     mp_int* modulus, int map, void* heap)
3688
#endif
3689
#if !defined(WOLFSSL_SP_MATH)
3690
{
3691
   ecc_point     *tG, *M[M_POINTS];
3692
#ifdef WOLFSSL_NO_MALLOC
3693
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3694
#endif
3695
   int           i, err;
3696
#ifdef WOLFSSL_SMALL_STACK_CACHE
3697
   ecc_key       *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3698
#endif
3699
   mp_digit      mp;
3700
3701
   /* init variables */
3702
   tG = NULL;
3703
   XMEMSET(M, 0, sizeof(M));
3704
3705
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3706
       err = ECC_BAD_ARG_E;
3707
       goto exit;
3708
   }
3709
3710
   /* k can't have more bits than modulus count plus 1 */
3711
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3712
       err = ECC_OUT_OF_RANGE_E;
3713
       goto exit;
3714
   }
3715
3716
#ifdef WOLFSSL_SMALL_STACK_CACHE
3717
   if (key == NULL) {
3718
       err = MP_MEM;
3719
       goto exit;
3720
   }
3721
   err = ecc_key_tmp_init(key, heap);
3722
   if (err != MP_OKAY)
3723
      goto exit;
3724
   R->key = key;
3725
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3726
3727
  /* alloc ram for window temps */
3728
  for (i = 0; i < M_POINTS; i++) {
3729
  #ifdef WOLFSSL_NO_MALLOC
3730
      M[i] = &lcl_M[i];
3731
  #endif
3732
      err = wc_ecc_new_point_ex(&M[i], heap);
3733
      if (err != MP_OKAY) {
3734
         goto exit;
3735
      }
3736
#ifdef WOLFSSL_SMALL_STACK_CACHE
3737
      M[i]->key = key;
3738
#endif
3739
  }
3740
3741
   /* make a copy of G in case R==G */
3742
#ifdef WOLFSSL_NO_MALLOC
3743
   tG = &lcl_tG;
3744
#endif
3745
   err = wc_ecc_new_point_ex(&tG, heap);
3746
   if (err != MP_OKAY) {
3747
       goto exit;
3748
   }
3749
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3750
       goto exit;
3751
   }
3752
3753
   /* init montgomery reduction */
3754
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3755
       goto exit;
3756
   }
3757
3758
#ifdef FP_ECC
3759
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3760
#else
3761
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3762
#endif
3763
   /* map R back from projective space */
3764
   if (err == MP_OKAY && map)
3765
       err = ecc_map(R, modulus, mp);
3766
3767
exit:
3768
3769
   /* done */
3770
   wc_ecc_del_point_ex(tG, heap);
3771
   for (i = 0; i < M_POINTS; i++) {
3772
       wc_ecc_del_point_ex(M[i], heap);
3773
   }
3774
3775
#ifdef WOLFSSL_SMALL_STACK_CACHE
3776
   if (key) {
3777
       if (R)
3778
           R->key = NULL;
3779
       if (err == MP_OKAY)
3780
           ecc_key_tmp_final(key, heap);
3781
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3782
   }
3783
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3784
3785
   return err;
3786
}
3787
#else
3788
640
{
3789
640
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3790
0
       return ECC_BAD_ARG_E;
3791
0
   }
3792
3793
640
   (void)a;
3794
3795
   /* For supported curves the order is the same length in bits as the modulus.
3796
    * Can't have more than order bits for the scalar.
3797
    */
3798
640
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3799
27
       return ECC_OUT_OF_RANGE_E;
3800
27
   }
3801
613
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3802
600
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3803
581
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3804
32
       return IS_POINT_E;
3805
32
   }
3806
3807
581
#ifdef WOLFSSL_HAVE_SP_ECC
3808
581
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3809
581
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3810
50
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3811
50
   }
3812
531
#endif
3813
531
#ifndef WOLFSSL_SP_NO_256
3814
531
   if (mp_count_bits(modulus) == 256) {
3815
160
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3816
160
   }
3817
371
#endif
3818
371
#ifdef WOLFSSL_SP_384
3819
371
   if (mp_count_bits(modulus) == 384) {
3820
99
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3821
99
   }
3822
272
#endif
3823
272
#ifdef WOLFSSL_SP_521
3824
272
   if (mp_count_bits(modulus) == 521) {
3825
272
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3826
272
   }
3827
0
#endif
3828
#else
3829
   (void)map;
3830
   (void)map;
3831
   (void)heap;
3832
#endif
3833
0
   return ECC_BAD_ARG_E;
3834
272
}
3835
#endif
3836
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3837
3838
#ifndef FP_ECC
3839
#if !defined(WOLFSSL_SP_MATH)
3840
#ifdef ECC_TIMING_RESISTANT
3841
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3842
   mp_int* modulus, mp_int* order)
3843
{
3844
    int err;
3845
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3846
3847
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3848
#ifdef MP_INT_SIZE_CHECK_NULL
3849
    if (t == NULL) {
3850
        err = MEMORY_E;
3851
    }
3852
    else
3853
#endif
3854
    {
3855
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3856
    }
3857
    if (err == MP_OKAY) {
3858
        /* Check for k == order - 1. Result will be 0 point which is not correct
3859
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3860
         * (with constant time implementation)
3861
         */
3862
        err = mp_sub_d(order, 1, t);
3863
        if (err == MP_OKAY) {
3864
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3865
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3866
            if (err == MP_OKAY) {
3867
                err = mp_sub(modulus, tG->y, t);
3868
            }
3869
            if (err == MP_OKAY) {
3870
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3871
            }
3872
            if (err == MP_OKAY) {
3873
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3874
            }
3875
        }
3876
3877
        mp_free(t);
3878
    }
3879
3880
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3881
    return err;
3882
}
3883
#endif /* ECC_TIMING_RESISTANT */
3884
#endif
3885
3886
/**
3887
   Perform a point multiplication
3888
   k    The scalar to multiply by
3889
   G    The base point
3890
   R    [out] Destination for kG
3891
   a    ECC curve parameter a
3892
   modulus  The modulus of the field the ECC curve is in
3893
   map      Boolean whether to map back to affine or not
3894
                (1==map, 0 == leave in projective)
3895
   return MP_OKAY on success
3896
*/
3897
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
3898
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3899
                      void* heap)
3900
#if !defined(WOLFSSL_SP_MATH)
3901
{
3902
   ecc_point     *tG, *M[M_POINTS];
3903
#ifdef WOLFSSL_NO_MALLOC
3904
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3905
#endif
3906
   int           i, err;
3907
#ifdef WOLFSSL_SMALL_STACK_CACHE
3908
   ecc_key       *key = NULL;
3909
#endif
3910
   mp_digit      mp;
3911
3912
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3913
      return ECC_BAD_ARG_E;
3914
   }
3915
3916
#ifdef HAVE_ECC_CDH
3917
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
3918
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
3919
          return ECC_OUT_OF_RANGE_E;
3920
      }
3921
   }
3922
   else
3923
#endif
3924
   /* k can't have more bits than order */
3925
   if (mp_count_bits(k) > mp_count_bits(order)) {
3926
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3927
      return ECC_OUT_OF_RANGE_E;
3928
   }
3929
3930
   /* init variables */
3931
   tG = NULL;
3932
   XMEMSET(M, 0, sizeof(M));
3933
3934
#ifdef WOLFSSL_SMALL_STACK_CACHE
3935
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3936
   if (key == NULL)
3937
       return MEMORY_E;
3938
   err = ecc_key_tmp_init(key, heap);
3939
   if (err != MP_OKAY)
3940
      goto exit;
3941
   R->key = key;
3942
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3943
3944
   /* alloc ram for window temps */
3945
   for (i = 0; i < M_POINTS; i++) {
3946
   #ifdef WOLFSSL_NO_MALLOC
3947
      M[i] = &lcl_M[i];
3948
   #endif
3949
      err = wc_ecc_new_point_ex(&M[i], heap);
3950
      if (err != MP_OKAY) {
3951
         goto exit;
3952
      }
3953
#ifdef WOLFSSL_SMALL_STACK_CACHE
3954
      M[i]->key = key;
3955
#endif
3956
  }
3957
3958
   /* make a copy of G in case R==G */
3959
#ifdef WOLFSSL_NO_MALLOC
3960
   tG = &lcl_tG;
3961
#endif
3962
   err = wc_ecc_new_point_ex(&tG, heap);
3963
   if (err != MP_OKAY) {
3964
       goto exit;
3965
   }
3966
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3967
       goto exit;
3968
   }
3969
3970
   /* init montgomery reduction */
3971
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3972
      goto exit;
3973
   }
3974
3975
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3976
#ifdef ECC_TIMING_RESISTANT
3977
   if (err == MP_OKAY) {
3978
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3979
   }
3980
#else
3981
   (void)order;
3982
#endif
3983
   /* map R back from projective space */
3984
   if (err == MP_OKAY && map)
3985
      err = ecc_map(R, modulus, mp);
3986
3987
exit:
3988
3989
   /* done */
3990
   wc_ecc_del_point_ex(tG, heap);
3991
   for (i = 0; i < M_POINTS; i++) {
3992
      wc_ecc_del_point_ex(M[i], heap);
3993
   }
3994
#ifdef WOLFSSL_SMALL_STACK_CACHE
3995
   R->key = NULL;
3996
   ecc_key_tmp_final(key, heap);
3997
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
3998
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3999
4000
   return err;
4001
}
4002
#else
4003
{
4004
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4005
       return ECC_BAD_ARG_E;
4006
   }
4007
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4008
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4009
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4010
       return IS_POINT_E;
4011
   }
4012
4013
   (void)a;
4014
   (void)order;
4015
   (void)rng;
4016
4017
#ifdef WOLFSSL_HAVE_SP_ECC
4018
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4019
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4020
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4021
   }
4022
#endif
4023
#ifndef WOLFSSL_SP_NO_256
4024
   if (mp_count_bits(modulus) == 256) {
4025
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4026
   }
4027
#endif
4028
#ifdef WOLFSSL_SP_384
4029
   if (mp_count_bits(modulus) == 384) {
4030
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4031
   }
4032
#endif
4033
#ifdef WOLFSSL_SP_521
4034
   if (mp_count_bits(modulus) == 521) {
4035
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4036
   }
4037
#endif
4038
#else
4039
   (void)map;
4040
   (void)heap;
4041
#endif
4042
   return ECC_BAD_ARG_E;
4043
}
4044
#endif /* !WOLFSSL_SP_MATH */
4045
#endif /* !FP_ECC */
4046
4047
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4048
4049
/** ECC Fixed Point mulmod global
4050
    k        The multiplicand
4051
    G        Base point to multiply
4052
    R        [out] Destination of product
4053
    a        ECC curve parameter a
4054
    modulus  The modulus for the curve
4055
    map      [boolean] If non-zero maps the point back to affine coordinates,
4056
             otherwise it's left in jacobian-montgomery form
4057
    return MP_OKAY if successful
4058
*/
4059
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4060
                  mp_int* modulus, int map)
4061
1.41k
{
4062
1.41k
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4063
10
        mp_zero(R->x);
4064
10
        mp_zero(R->y);
4065
10
        mp_set(R->z, 1);
4066
10
        return MP_OKAY;
4067
10
    }
4068
1.40k
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4069
1.41k
}
4070
4071
#endif
4072
4073
/**
4074
 * Allocate a new ECC point (if one not provided)
4075
 * use a heap hint when creating new ecc_point
4076
 * @return 0 on success
4077
 * @return BAD_FUNC_ARG for invalid arguments
4078
 * @return MEMORY_E on failure to allocate memory
4079
*/
4080
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4081
293k
{
4082
293k
   int err = MP_OKAY;
4083
293k
   ecc_point* p;
4084
4085
293k
   if (point == NULL) {
4086
0
       return BAD_FUNC_ARG;
4087
0
   }
4088
4089
293k
   p = *point;
4090
293k
   if (p == NULL) {
4091
293k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4092
293k
   }
4093
293k
   if (p == NULL) {
4094
1.67k
      return MEMORY_E;
4095
1.67k
   }
4096
291k
   XMEMSET(p, 0, sizeof(ecc_point));
4097
4098
291k
   if (*point == NULL)
4099
291k
       p->isAllocated = 1;
4100
4101
291k
#ifndef ALT_ECC_SIZE
4102
291k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4103
291k
   if (err != MP_OKAY) {
4104
0
      WOLFSSL_MSG("mp_init_multi failed.");
4105
0
      if (p->isAllocated)
4106
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4107
0
      p = NULL;
4108
0
   }
4109
#else
4110
   p->x = (mp_int*)&p->xyz[0];
4111
   p->y = (mp_int*)&p->xyz[1];
4112
   p->z = (mp_int*)&p->xyz[2];
4113
   alt_fp_init(p->x);
4114
   alt_fp_init(p->y);
4115
   alt_fp_init(p->z);
4116
#endif
4117
4118
291k
   *point = p;
4119
291k
   (void)heap;
4120
291k
   return err;
4121
293k
} /* wc_ecc_new_point_ex */
4122
4123
ecc_point* wc_ecc_new_point_h(void* heap)
4124
44.9k
{
4125
44.9k
    ecc_point* p = NULL;
4126
44.9k
    (void)wc_ecc_new_point_ex(&p, heap);
4127
44.9k
    return p;
4128
44.9k
}
4129
4130
ecc_point* wc_ecc_new_point(void)
4131
12.3k
{
4132
12.3k
   ecc_point* p = NULL;
4133
12.3k
   (void)wc_ecc_new_point_ex(&p, NULL);
4134
12.3k
   return p;
4135
12.3k
}
4136
4137
/** Free an ECC point from memory
4138
  p   The point to free
4139
*/
4140
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4141
351k
{
4142
351k
   if (p != NULL) {
4143
291k
      mp_clear(p->x);
4144
291k
      mp_clear(p->y);
4145
291k
      mp_clear(p->z);
4146
291k
      if (p->isAllocated)
4147
291k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4148
291k
   }
4149
351k
   (void)heap;
4150
351k
}
4151
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4152
416
{
4153
416
   wc_ecc_del_point_ex(p, heap);
4154
416
}
4155
void wc_ecc_del_point(ecc_point* p)
4156
113k
{
4157
113k
    wc_ecc_del_point_ex(p, NULL);
4158
113k
}
4159
4160
void wc_ecc_forcezero_point(ecc_point* p)
4161
0
{
4162
0
    if (p != NULL) {
4163
0
        mp_forcezero(p->x);
4164
0
        mp_forcezero(p->y);
4165
0
        mp_forcezero(p->z);
4166
0
    }
4167
0
}
4168
4169
4170
/** Copy the value of a point to an other one
4171
  p    The point to copy
4172
  r    The created point
4173
*/
4174
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4175
820k
{
4176
820k
    int ret;
4177
4178
    /* prevents null arguments */
4179
820k
    if (p == NULL || r == NULL)
4180
0
        return ECC_BAD_ARG_E;
4181
4182
820k
    ret = mp_copy(p->x, r->x);
4183
820k
    if (ret != MP_OKAY)
4184
3
        return ret;
4185
820k
    ret = mp_copy(p->y, r->y);
4186
820k
    if (ret != MP_OKAY)
4187
2
        return ret;
4188
820k
    ret = mp_copy(p->z, r->z);
4189
820k
    if (ret != MP_OKAY)
4190
3
        return ret;
4191
4192
820k
    return MP_OKAY;
4193
820k
}
4194
4195
/** Compare the value of a point with an other one
4196
 a    The point to compare
4197
 b    The other point to compare
4198
4199
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4200
 */
4201
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4202
3.05k
{
4203
3.05k
    int ret;
4204
4205
    /* prevents null arguments */
4206
3.05k
    if (a == NULL || b == NULL)
4207
0
        return BAD_FUNC_ARG;
4208
4209
3.05k
    ret = mp_cmp(a->x, b->x);
4210
3.05k
    if (ret != MP_EQ)
4211
2.28k
        return ret;
4212
772
    ret = mp_cmp(a->y, b->y);
4213
772
    if (ret != MP_EQ)
4214
410
        return ret;
4215
362
    ret = mp_cmp(a->z, b->z);
4216
362
    if (ret != MP_EQ)
4217
24
        return ret;
4218
4219
338
    return MP_EQ;
4220
362
}
4221
4222
4223
/** Returns whether an ECC idx is valid or not
4224
  n      The idx number to check
4225
  return 1 if valid, 0 if not
4226
*/
4227
int wc_ecc_is_valid_idx(int n)
4228
50.7k
{
4229
50.7k
   int x;
4230
4231
50.7k
   if (n >= (int)ECC_SET_COUNT)
4232
0
       return 0;
4233
4234
1.13M
   for (x = 0; ecc_sets[x].size != 0; x++)
4235
1.08M
       ;
4236
   /* -1 is a valid index --- indicating that the domain params
4237
      were supplied by the user */
4238
50.7k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4239
50.7k
      return 1;
4240
50.7k
   }
4241
4242
0
   return 0;
4243
50.7k
}
4244
4245
int wc_ecc_get_curve_idx(int curve_id)
4246
41.7k
{
4247
41.7k
    int curve_idx;
4248
524k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4249
524k
        if (curve_id == ecc_sets[curve_idx].id)
4250
41.6k
            break;
4251
524k
    }
4252
41.7k
    if (ecc_sets[curve_idx].size == 0) {
4253
117
        return ECC_CURVE_INVALID;
4254
117
    }
4255
41.6k
    return curve_idx;
4256
41.7k
}
4257
4258
int wc_ecc_get_curve_id(int curve_idx)
4259
1.92k
{
4260
1.92k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4261
1.92k
        return ecc_sets[curve_idx].id;
4262
1.92k
    }
4263
0
    return ECC_CURVE_INVALID;
4264
1.92k
}
4265
4266
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4267
 *
4268
 * id      curve id, from ecc_curve_id enum in ecc.h
4269
 * return  curve size, from ecc_sets[] on success, negative on error
4270
 */
4271
int wc_ecc_get_curve_size_from_id(int curve_id)
4272
1.77k
{
4273
1.77k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4274
1.77k
    if (curve_idx == ECC_CURVE_INVALID)
4275
0
        return ECC_BAD_ARG_E;
4276
1.77k
    return ecc_sets[curve_idx].size;
4277
1.77k
}
4278
4279
/* Returns the curve index that corresponds to a given curve name in
4280
 * ecc_sets[] of ecc.c
4281
 *
4282
 * name    curve name, from ecc_sets[].name in ecc.c
4283
 * return  curve index in ecc_sets[] on success, negative on error
4284
 */
4285
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4286
0
{
4287
0
    int curve_idx;
4288
4289
0
    if (curveName == NULL)
4290
0
        return BAD_FUNC_ARG;
4291
4292
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4293
0
        if (
4294
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4295
0
            ecc_sets[curve_idx].name &&
4296
0
        #endif
4297
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4298
0
            break;
4299
0
        }
4300
0
    }
4301
0
    if (ecc_sets[curve_idx].size == 0) {
4302
0
        WOLFSSL_MSG("ecc_set curve name not found");
4303
0
        return ECC_CURVE_INVALID;
4304
0
    }
4305
0
    return curve_idx;
4306
0
}
4307
4308
/* Returns the curve size that corresponds to a given curve name,
4309
 * as listed in ecc_sets[] of ecc.c.
4310
 *
4311
 * name    curve name, from ecc_sets[].name in ecc.c
4312
 * return  curve size, from ecc_sets[] on success, negative on error
4313
 */
4314
int wc_ecc_get_curve_size_from_name(const char* curveName)
4315
0
{
4316
0
    int curve_idx;
4317
4318
0
    if (curveName == NULL)
4319
0
        return BAD_FUNC_ARG;
4320
4321
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4322
0
    if (curve_idx < 0)
4323
0
        return curve_idx;
4324
4325
0
    return ecc_sets[curve_idx].size;
4326
0
}
4327
4328
/* Returns the curve id that corresponds to a given curve name,
4329
 * as listed in ecc_sets[] of ecc.c.
4330
 *
4331
 * name   curve name, from ecc_sets[].name in ecc.c
4332
 * return curve id, from ecc_sets[] on success, negative on error
4333
 */
4334
int wc_ecc_get_curve_id_from_name(const char* curveName)
4335
0
{
4336
0
    int curve_idx;
4337
4338
0
    if (curveName == NULL)
4339
0
        return BAD_FUNC_ARG;
4340
4341
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4342
0
    if (curve_idx < 0)
4343
0
        return curve_idx;
4344
4345
0
    return ecc_sets[curve_idx].id;
4346
0
}
4347
4348
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4349
 * parameter for equality.
4350
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4351
 * Returns MP_EQ on success, negative on error */
4352
static int wc_ecc_cmp_param(const char* curveParam,
4353
                            const byte* param, word32 paramSz, int encType)
4354
0
{
4355
0
    int err = MP_OKAY;
4356
0
#ifdef WOLFSSL_SMALL_STACK
4357
0
    mp_int* a = NULL;
4358
0
    mp_int* b = NULL;
4359
#else
4360
    mp_int  a[1], b[1];
4361
#endif
4362
4363
0
    if (param == NULL || curveParam == NULL)
4364
0
        return BAD_FUNC_ARG;
4365
4366
0
    if (encType == WC_TYPE_HEX_STR) {
4367
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4368
0
            return -1;
4369
0
        return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1;
4370
0
    }
4371
4372
0
#ifdef WOLFSSL_SMALL_STACK
4373
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4374
0
    if (a == NULL)
4375
0
        return MEMORY_E;
4376
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4377
0
    if (b == NULL) {
4378
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4379
0
        return MEMORY_E;
4380
0
    }
4381
0
#endif
4382
4383
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4384
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4385
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4386
0
        return err;
4387
0
    }
4388
4389
0
    if (err == MP_OKAY) {
4390
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4391
0
    }
4392
0
    if (err == MP_OKAY)
4393
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4394
4395
0
    if (err == MP_OKAY) {
4396
0
        if (mp_cmp(a, b) != MP_EQ) {
4397
0
            err = -1;
4398
0
        } else {
4399
0
            err = MP_EQ;
4400
0
        }
4401
0
    }
4402
4403
0
    mp_clear(a);
4404
0
    mp_clear(b);
4405
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4406
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4407
4408
0
    return err;
4409
0
}
4410
4411
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4412
 * curve parameters.
4413
 *
4414
 * fieldSize  the field size in bits
4415
 * prime      prime of the finite field
4416
 * primeSz    size of prime in octets
4417
 * Af         first coefficient a of the curve
4418
 * AfSz       size of Af in octets
4419
 * Bf         second coefficient b of the curve
4420
 * BfSz       size of Bf in octets
4421
 * order      curve order
4422
 * orderSz    size of curve in octets
4423
 * Gx         affine x coordinate of base point
4424
 * GxSz       size of Gx in octets
4425
 * Gy         affine y coordinate of base point
4426
 * GySz       size of Gy in octets
4427
 * cofactor   curve cofactor
4428
 *
4429
 * return curve id, from ecc_sets[] on success, negative on error
4430
 */
4431
int wc_ecc_get_curve_id_from_params(int fieldSize,
4432
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4433
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4434
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4435
0
{
4436
0
    int idx;
4437
0
    int curveSz;
4438
4439
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4440
0
        Gx == NULL || Gy == NULL)
4441
0
        return BAD_FUNC_ARG;
4442
4443
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4444
4445
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4446
0
        if (curveSz == ecc_sets[idx].size) {
4447
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4448
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4449
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4450
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4451
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4452
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4453
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4454
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4455
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4456
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4457
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4458
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4459
0
                (cofactor == ecc_sets[idx].cofactor)) {
4460
0
                    break;
4461
0
            }
4462
0
        }
4463
0
    }
4464
4465
0
    if (ecc_sets[idx].size == 0)
4466
0
        return ECC_CURVE_INVALID;
4467
4468
0
    return ecc_sets[idx].id;
4469
0
}
4470
4471
/* Returns the curve id in ecc_sets[] that corresponds
4472
 * to a given domain parameters pointer.
4473
 *
4474
 * dp   domain parameters pointer
4475
 *
4476
 * return curve id, from ecc_sets[] on success, negative on error
4477
 */
4478
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4479
0
{
4480
0
    int idx;
4481
4482
0
    if (dp == NULL
4483
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4484
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4485
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4486
0
    #endif
4487
0
    ) {
4488
0
        return BAD_FUNC_ARG;
4489
0
    }
4490
4491
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4492
0
        if (dp->size == ecc_sets[idx].size) {
4493
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4494
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4495
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4496
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4497
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4498
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4499
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4500
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4501
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4502
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4503
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4504
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4505
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4506
0
                    break;
4507
0
            }
4508
0
        }
4509
0
    }
4510
4511
0
    if (ecc_sets[idx].size == 0)
4512
0
        return ECC_CURVE_INVALID;
4513
4514
0
    return ecc_sets[idx].id;
4515
0
}
4516
4517
/* Returns the curve id that corresponds to a given OID,
4518
 * as listed in ecc_sets[] of ecc.c.
4519
 *
4520
 * oid   OID, from ecc_sets[].name in ecc.c
4521
 * len   OID len, from ecc_sets[].name in ecc.c
4522
 * return curve id, from ecc_sets[] on success, negative on error
4523
 */
4524
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4525
0
{
4526
0
    int curve_idx;
4527
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4528
    int ret;
4529
    #ifdef HAVE_OID_DECODING
4530
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4531
    #else
4532
    byte  decOid[MAX_OID_SZ];
4533
    #endif
4534
    word32 decOidSz;
4535
#endif
4536
4537
0
    if (oid == NULL)
4538
0
        return BAD_FUNC_ARG;
4539
4540
#ifdef HAVE_OID_DECODING
4541
    decOidSz = (word32)sizeof(decOid);
4542
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4543
    if (ret != 0) {
4544
        return ret;
4545
    }
4546
#endif
4547
4548
0
    if (len == 0) {
4549
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4550
0
        WOLFSSL_MSG("zero oidSz");
4551
0
        return ECC_CURVE_INVALID;
4552
0
    }
4553
4554
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4555
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4556
        decOidSz = (word32)sizeof(decOid);
4557
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4558
            decOid, &decOidSz);
4559
        if (ret != 0) {
4560
            continue;
4561
        }
4562
    #endif
4563
4564
0
        if (
4565
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4566
0
            ecc_sets[curve_idx].oid &&
4567
0
        #endif
4568
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4569
            decOidSz == len &&
4570
                XMEMCMP(decOid, oid, len) == 0
4571
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4572
            /* We double because decOidSz is a count of word16 elements. */
4573
            ecc_sets[curve_idx].oidSz == decOidSz &&
4574
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4575
        #else
4576
0
            ecc_sets[curve_idx].oidSz == len &&
4577
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4578
0
        #endif
4579
0
        ) {
4580
0
            break;
4581
0
        }
4582
0
    }
4583
0
    if (ecc_sets[curve_idx].size == 0) {
4584
0
        WOLFSSL_MSG("ecc_set curve name not found");
4585
0
        return ECC_CURVE_INVALID;
4586
0
    }
4587
4588
0
    return ecc_sets[curve_idx].id;
4589
0
}
4590
4591
/* Get curve parameters using curve index */
4592
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4593
29.6k
{
4594
29.6k
    const ecc_set_type* ecc_set = NULL;
4595
4596
29.6k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4597
29.6k
        ecc_set = &ecc_sets[curve_idx];
4598
29.6k
    }
4599
29.6k
    return ecc_set;
4600
29.6k
}
4601
4602
4603
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4604
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4605
{
4606
   if (key == NULL || mp == NULL)
4607
      return BAD_FUNC_ARG;
4608
   if (*mp == NULL) {
4609
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4610
      if (*mp == NULL) {
4611
         return MEMORY_E;
4612
      }
4613
      XMEMSET(*mp, 0, sizeof(mp_int));
4614
   }
4615
   return 0;
4616
}
4617
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4618
{
4619
   if (key && mp && *mp) {
4620
      mp_clear(*mp);
4621
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4622
      *mp = NULL;
4623
   }
4624
}
4625
4626
static int wc_ecc_alloc_async(ecc_key* key)
4627
{
4628
    int err = wc_ecc_alloc_mpint(key, &key->r);
4629
    if (err == 0)
4630
        err = wc_ecc_alloc_mpint(key, &key->s);
4631
    return err;
4632
}
4633
4634
static void wc_ecc_free_async(ecc_key* key)
4635
{
4636
    wc_ecc_free_mpint(key, &key->r);
4637
    wc_ecc_free_mpint(key, &key->s);
4638
#ifdef HAVE_CAVIUM_V
4639
    wc_ecc_free_mpint(key, &key->e);
4640
    wc_ecc_free_mpint(key, &key->signK);
4641
#endif /* HAVE_CAVIUM_V */
4642
}
4643
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4644
4645
4646
#ifdef HAVE_ECC_DHE
4647
/**
4648
  Create an ECC shared secret between two keys
4649
  private_key      The private ECC key (heap hint based off of private key)
4650
  public_key       The public key
4651
  out              [out] Destination of the shared secret
4652
                         Conforms to EC-DH from ANSI X9.63
4653
  outlen           [in/out] The max size and resulting size of the shared secret
4654
  return           MP_OKAY if successful
4655
*/
4656
WOLFSSL_ABI
4657
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4658
                      word32* outlen)
4659
952
{
4660
952
   int err = 0;
4661
4662
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4663
   !defined(WOLFSSL_ATECC608A)
4664
   CRYS_ECDH_TempData_t tempBuff;
4665
#endif
4666
4667
952
   (void)err;
4668
4669
952
   if (private_key == NULL || public_key == NULL || out == NULL ||
4670
952
                                                            outlen == NULL) {
4671
0
       return BAD_FUNC_ARG;
4672
0
   }
4673
4674
952
#ifdef WOLF_CRYPTO_CB
4675
952
    #ifndef WOLF_CRYPTO_CB_FIND
4676
952
    if (private_key->devId != INVALID_DEVID)
4677
0
    #endif
4678
0
    {
4679
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4680
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4681
0
            return err;
4682
        /* fall-through when unavailable */
4683
0
    }
4684
952
#endif
4685
4686
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4687
    return NO_VALID_DEVID;
4688
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4689
   /* type valid? */
4690
952
   if (private_key->type != ECC_PRIVATEKEY &&
4691
362
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4692
0
      return ECC_BAD_ARG_E;
4693
0
   }
4694
4695
   /* Verify domain params supplied */
4696
952
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4697
952
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4698
0
      return ECC_BAD_ARG_E;
4699
0
   }
4700
4701
   /* Verify curve id matches */
4702
952
   if (private_key->dp->id != public_key->dp->id) {
4703
0
      return ECC_BAD_ARG_E;
4704
0
   }
4705
4706
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4707
   /* For SECP256R1 use hardware */
4708
   if (private_key->dp->id == ECC_SECP256R1) {
4709
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4710
       *outlen = private_key->dp->size;
4711
   }
4712
   else {
4713
      err = NOT_COMPILED_IN;
4714
   }
4715
#elif defined(WOLFSSL_CRYPTOCELL)
4716
4717
    /* generate a secret*/
4718
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4719
                            &private_key->ctx.privKey,
4720
                            out,
4721
                            (uint32_t*)outlen,
4722
                            &tempBuff);
4723
4724
    if (err != SA_SILIB_RET_OK){
4725
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4726
        return err;
4727
    }
4728
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4729
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4730
#elif defined(WOLFSSL_KCAPI_ECC)
4731
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4732
#elif defined(WOLFSSL_SE050)
4733
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4734
#else
4735
952
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4736
952
#endif /* WOLFSSL_ATECC508A */
4737
952
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4738
4739
952
   return err;
4740
952
}
4741
4742
4743
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4744
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4745
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4746
4747
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4748
                               byte* out, word32* outlen)
4749
108
{
4750
108
    int err = MP_OKAY;
4751
108
    mp_int* k = ecc_get_k(private_key);
4752
#ifdef HAVE_ECC_CDH
4753
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
4754
#endif
4755
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4756
    defined(WC_ECC_NONBLOCK_ONLY)
4757
    ecc_nb_ctx_t nb_ctx;
4758
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4759
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4760
4761
#ifdef HAVE_ECC_CDH
4762
    /* if cofactor flag has been set */
4763
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4764
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4765
        /* only perform cofactor calc if not equal to 1 */
4766
        if (cofactor != 1) {
4767
#ifdef WOLFSSL_SMALL_STACK
4768
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4769
                return MEMORY_E;
4770
#endif
4771
            k = k_lcl;
4772
            if (mp_init(k) != MP_OKAY) {
4773
                err = MEMORY_E;
4774
                goto errout;
4775
            }
4776
            /* multiply cofactor times private key "k" */
4777
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4778
            if (err != MP_OKAY)
4779
                goto errout;
4780
        }
4781
    }
4782
#endif
4783
4784
108
#ifdef WOLFSSL_HAVE_SP_ECC
4785
4786
108
#ifndef WOLFSSL_SP_NO_256
4787
108
    if (private_key->idx != ECC_CUSTOM_IDX &&
4788
108
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4789
44
    #ifndef WC_ECC_NONBLOCK
4790
44
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4791
    #else
4792
        if (private_key->nb_ctx) {
4793
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4794
                                           point, out, outlen,
4795
                                           private_key->heap);
4796
        }
4797
        else {
4798
        #ifdef WC_ECC_NONBLOCK_ONLY
4799
            do { /* perform blocking call to non-blocking function */
4800
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4801
                                               outlen, private_key->heap);
4802
            } while (err == FP_WOULDBLOCK);
4803
        #else
4804
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4805
                                        private_key->heap);
4806
        #endif /* WC_ECC_NONBLOCK_ONLY */
4807
        }
4808
    #endif /* !WC_ECC_NONBLOCK */
4809
44
    }
4810
64
    else
4811
64
#endif /* ! WOLFSSL_SP_NO_256 */
4812
64
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4813
64
    if (private_key->idx != ECC_CUSTOM_IDX &&
4814
64
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4815
18
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4816
18
                                                             private_key->heap);
4817
18
    }
4818
46
    else
4819
46
#endif
4820
46
#ifdef WOLFSSL_SP_384
4821
46
    if (private_key->idx != ECC_CUSTOM_IDX &&
4822
46
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4823
35
    #ifndef WC_ECC_NONBLOCK
4824
35
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4825
    #else
4826
        if (private_key->nb_ctx) {
4827
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4828
                                           point, out, outlen,
4829
                                           private_key->heap);
4830
        }
4831
        else {
4832
        #ifdef WC_ECC_NONBLOCK_ONLY
4833
            do { /* perform blocking call to non-blocking function */
4834
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4835
                                               outlen, private_key->heap);
4836
            } while (err == FP_WOULDBLOCK);
4837
        #else
4838
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4839
                                        private_key->heap);
4840
        #endif /* WC_ECC_NONBLOCK_ONLY */
4841
        }
4842
    #endif /* !WC_ECC_NONBLOCK */
4843
35
    }
4844
11
    else
4845
11
#endif /* WOLFSSL_SP_384 */
4846
11
#ifdef WOLFSSL_SP_521
4847
11
    if (private_key->idx != ECC_CUSTOM_IDX &&
4848
11
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4849
11
    #ifndef WC_ECC_NONBLOCK
4850
11
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4851
    #else
4852
        if (private_key->nb_ctx) {
4853
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4854
                                           point, out, outlen,
4855
                                           private_key->heap);
4856
        }
4857
        else {
4858
        #ifdef WC_ECC_NONBLOCK_ONLY
4859
            do { /* perform blocking call to non-blocking function */
4860
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4861
                                               outlen, private_key->heap);
4862
            } while (err == FP_WOULDBLOCK);
4863
        #else
4864
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4865
                                        private_key->heap);
4866
        #endif /* WC_ECC_NONBLOCK_ONLY */
4867
        }
4868
    #endif /* !WC_ECC_NONBLOCK */
4869
11
    }
4870
0
    else
4871
0
#endif /* WOLFSSL_SP_521 */
4872
#else
4873
    (void)point;
4874
    (void)out;
4875
    (void)outlen;
4876
    (void)k;
4877
#endif
4878
0
#if defined(WOLFSSL_SP_MATH)
4879
0
    {
4880
0
        err = WC_KEY_SIZE_E;
4881
0
        goto errout;
4882
0
    }
4883
#else
4884
    {
4885
        ecc_point* result = NULL;
4886
        #ifdef WOLFSSL_NO_MALLOC
4887
        ecc_point  lcl_result;
4888
        #endif
4889
        int x = 0;
4890
        mp_digit mp = 0;
4891
        DECLARE_CURVE_SPECS(3);
4892
4893
        /* load curve info */
4894
        ALLOC_CURVE_SPECS(3, err);
4895
        if (err == MP_OKAY) {
4896
            err = wc_ecc_curve_load(private_key->dp, &curve,
4897
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4898
                 ECC_CURVE_FIELD_ORDER));
4899
        }
4900
4901
        if (err != MP_OKAY) {
4902
            FREE_CURVE_SPECS();
4903
            goto errout;
4904
        }
4905
4906
        /* make new point */
4907
    #ifdef WOLFSSL_NO_MALLOC
4908
        result = &lcl_result;
4909
    #endif
4910
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4911
        if (err != MP_OKAY) {
4912
            wc_ecc_curve_free(curve);
4913
            FREE_CURVE_SPECS();
4914
            goto errout;
4915
        }
4916
4917
#ifdef ECC_TIMING_RESISTANT
4918
        if (private_key->rng == NULL) {
4919
            err = MISSING_RNG_E;
4920
        }
4921
#endif
4922
4923
        if (err == MP_OKAY) {
4924
            /* Map in a separate call as this should be constant time */
4925
#ifdef ECC_TIMING_RESISTANT
4926
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4927
                                              curve->order, private_key->rng, 0,
4928
                                              private_key->heap);
4929
#else
4930
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4931
                                      curve->order, NULL, 0, private_key->heap);
4932
#endif
4933
        }
4934
        if (err == MP_OKAY) {
4935
        #ifdef WOLFSSL_CHECK_MEM_ZERO
4936
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
4937
                result->x);
4938
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
4939
                result->y);
4940
        #endif
4941
            err = mp_montgomery_setup(curve->prime, &mp);
4942
        }
4943
        if (err == MP_OKAY) {
4944
            /* Use constant time map if compiled in */
4945
            err = ecc_map_ex(result, curve->prime, mp, 1);
4946
        }
4947
        if (err == MP_OKAY) {
4948
            x = mp_unsigned_bin_size(curve->prime);
4949
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4950
                err = BUFFER_E;
4951
            }
4952
        }
4953
4954
        if (err == MP_OKAY) {
4955
            XMEMSET(out, 0, (size_t)x);
4956
            err = mp_to_unsigned_bin(result->x, out +
4957
                                     (x - mp_unsigned_bin_size(result->x)));
4958
        }
4959
        *outlen = (word32)x;
4960
4961
        mp_forcezero(result->x);
4962
        mp_forcezero(result->y);
4963
        wc_ecc_del_point_ex(result, private_key->heap);
4964
4965
        wc_ecc_curve_free(curve);
4966
        FREE_CURVE_SPECS();
4967
    }
4968
#endif
4969
4970
108
  errout:
4971
4972
#ifdef HAVE_ECC_CDH
4973
    if (k == k_lcl)
4974
        mp_clear(k);
4975
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
4976
#endif
4977
4978
108
    return err;
4979
108
}
4980
4981
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4982
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
4983
            ecc_point* point, byte* out, word32 *outlen)
4984
{
4985
    int err = 0;
4986
4987
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
4988
    DECLARE_CURVE_SPECS(3);
4989
4990
    /* load curve info */
4991
    ALLOC_CURVE_SPECS(3, err);
4992
    if (err == MP_OKAY) {
4993
        err = wc_ecc_curve_load(private_key->dp, &curve,
4994
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4995
             ECC_CURVE_FIELD_ORDER));
4996
    }
4997
4998
    if (err != MP_OKAY) {
4999
        FREE_CURVE_SPECS();
5000
        return err;
5001
    }
5002
5003
    if (private_key->dp
5004
    #ifdef WOLFSSL_CUSTOM_CURVES
5005
        && private_key->dp->id != ECC_CURVE_CUSTOM
5006
    #endif
5007
    #ifdef HAVE_CAVIUM_V
5008
        /* verify the curve is supported by hardware */
5009
        && NitroxEccIsCurveSupported(private_key)
5010
    #endif
5011
    ) {
5012
        word32 keySz = private_key->dp->size;
5013
5014
        /* sync public key x/y */
5015
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5016
            &ecc_get_k(private_key)->raw, keySz);
5017
        if (err == MP_OKAY)
5018
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5019
        if (err == MP_OKAY)
5020
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5021
    #ifdef HAVE_CAVIUM_V
5022
        /* allocate buffer for output */
5023
        if (err == MP_OKAY)
5024
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5025
        if (err == MP_OKAY)
5026
            err = wc_bigint_alloc(&private_key->e->raw,
5027
                NitroxEccGetSize(private_key)*2);
5028
        if (err == MP_OKAY)
5029
            err = NitroxEcdh(private_key,
5030
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5031
                private_key->e->raw.buf, &private_key->e->raw.len,
5032
                &curve->prime->raw);
5033
    #else
5034
        if (err == MP_OKAY)
5035
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5036
        if (err == MP_OKAY)
5037
            err = IntelQaEcdh(&private_key->asyncDev,
5038
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5039
                out, outlen,
5040
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5041
                private_key->dp->cofactor);
5042
    #endif
5043
    }
5044
    else
5045
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5046
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5047
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5048
        sw->eccSharedSec.private_key = private_key;
5049
        sw->eccSharedSec.public_point = point;
5050
        sw->eccSharedSec.out = out;
5051
        sw->eccSharedSec.outLen = outlen;
5052
        err = WC_PENDING_E;
5053
    }
5054
    else
5055
#endif
5056
    {
5057
        /* use sync in other cases */
5058
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5059
    }
5060
5061
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5062
        private_key->state++;
5063
    }
5064
5065
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5066
    wc_ecc_curve_free(curve);
5067
    FREE_CURVE_SPECS();
5068
#endif
5069
5070
    return err;
5071
}
5072
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5073
5074
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5075
/**
5076
 Create an ECC shared secret between private key and public point
5077
 private_key      The private ECC key (heap hint based on private key)
5078
 point            The point to use (public key)
5079
 out              [out] Destination of the shared secret
5080
                        Conforms to EC-DH from ANSI X9.63
5081
 outlen           [in/out] The max size and resulting size of the shared secret
5082
 return           MP_OKAY if successful
5083
*/
5084
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5085
                            byte* out, word32 *outlen)
5086
1.54k
{
5087
1.54k
    int err;
5088
5089
1.54k
    if (private_key == NULL || point == NULL || out == NULL ||
5090
1.54k
                                                            outlen == NULL) {
5091
0
        return BAD_FUNC_ARG;
5092
0
    }
5093
5094
    /* type valid? */
5095
1.54k
    if (private_key->type != ECC_PRIVATEKEY &&
5096
362
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5097
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5098
0
        return ECC_BAD_ARG_E;
5099
0
    }
5100
5101
    /* Verify domain params supplied */
5102
1.54k
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5103
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5104
0
        return ECC_BAD_ARG_E;
5105
0
    }
5106
5107
1.54k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5108
5109
1.54k
    switch (private_key->state) {
5110
1.54k
        case ECC_STATE_NONE:
5111
1.54k
        case ECC_STATE_SHARED_SEC_GEN:
5112
1.54k
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5113
5114
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5115
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5116
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5117
                    out, outlen);
5118
            }
5119
            else
5120
        #endif
5121
1.54k
            {
5122
1.54k
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5123
1.54k
                    out, outlen);
5124
1.54k
            }
5125
1.54k
            if (err < 0) {
5126
81
                break;
5127
81
            }
5128
1.46k
            FALL_THROUGH;
5129
5130
1.46k
        case ECC_STATE_SHARED_SEC_RES:
5131
1.46k
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5132
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5133
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5134
            #ifdef HAVE_CAVIUM_V
5135
                /* verify the curve is supported by hardware */
5136
                if (NitroxEccIsCurveSupported(private_key)) {
5137
                    /* copy output */
5138
                    *outlen = private_key->dp->size;
5139
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5140
                }
5141
            #endif /* HAVE_CAVIUM_V */
5142
            }
5143
        #endif /* WOLFSSL_ASYNC_CRYPT */
5144
1.46k
            err = 0;
5145
1.46k
            break;
5146
5147
0
        default:
5148
0
            err = BAD_STATE_E;
5149
1.54k
    } /* switch */
5150
5151
1.54k
    RESTORE_VECTOR_REGISTERS();
5152
5153
    /* if async pending then return and skip done cleanup below */
5154
1.54k
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5155
0
        return err;
5156
0
    }
5157
5158
    /* cleanup */
5159
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5160
    wc_ecc_free_async(private_key);
5161
#endif
5162
1.54k
    private_key->state = ECC_STATE_NONE;
5163
5164
1.54k
    return err;
5165
1.54k
}
5166
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5167
#elif defined(WOLFSSL_KCAPI_ECC)
5168
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5169
                            byte* out, word32 *outlen)
5170
{
5171
    int err;
5172
    ecc_key public_key;
5173
5174
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
5175
    if (err == MP_OKAY) {
5176
        #if FIPS_VERSION3_GE(6,0,0)
5177
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5178
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5179
         * keysize here when relying on default selection */
5180
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5181
            if (private_key->dp->size == 0 &&
5182
                (private_key->dp->id == ECC_SECP256R1 ||
5183
                private_key->dp->id == ECC_SECP224R1 ||
5184
                private_key->dp->id == ECC_SECP384R1 ||
5185
                private_key->dp->id == ECC_SECP521R1)) {
5186
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5187
                err = 0;
5188
            } else {
5189
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5190
                err = ECC_CURVE_OID_E;
5191
            }
5192
        }
5193
        if (err == 0) { /* FIPS specific check */
5194
        #endif
5195
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
5196
                               private_key->dp->id);
5197
        if (err == MP_OKAY) {
5198
            err = mp_copy(point->x, public_key.pubkey.x);
5199
        }
5200
        #if FIPS_VERSION3_GE(6,0,0)
5201
        } /* end FIPS specific check */
5202
        #endif
5203
        if (err == MP_OKAY) {
5204
            err = mp_copy(point->y, public_key.pubkey.y);
5205
        }
5206
        if (err == MP_OKAY) {
5207
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
5208
        }
5209
5210
        wc_ecc_free(&public_key);
5211
    }
5212
5213
    return err;
5214
}
5215
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5216
#endif /* HAVE_ECC_DHE */
5217
5218
#ifdef USE_ECC_B_PARAM
5219
/* Checks if a point p lies on the curve with index curve_idx */
5220
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5221
6.68k
{
5222
6.68k
    int err = MP_OKAY;
5223
6.68k
    DECLARE_CURVE_SPECS(3);
5224
5225
6.68k
    if (p == NULL)
5226
0
        return BAD_FUNC_ARG;
5227
5228
    /* is the IDX valid ?  */
5229
6.68k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5230
0
       return ECC_BAD_ARG_E;
5231
0
    }
5232
5233
6.68k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5234
5235
6.68k
    ALLOC_CURVE_SPECS(3, err);
5236
6.68k
    if (err == MP_OKAY) {
5237
6.47k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5238
6.47k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5239
6.47k
                                ECC_CURVE_FIELD_BF);
5240
6.47k
    }
5241
5242
6.68k
    if (err == MP_OKAY) {
5243
6.43k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5244
6.43k
    }
5245
5246
6.68k
    wc_ecc_curve_free(curve);
5247
6.68k
    FREE_CURVE_SPECS();
5248
5249
6.68k
    RESTORE_VECTOR_REGISTERS();
5250
5251
6.68k
    return err;
5252
6.68k
}
5253
#endif /* USE_ECC_B_PARAM */
5254
5255
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5256
    !defined(WOLFSSL_CRYPTOCELL) && \
5257
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5258
      defined(WOLFSSL_IMXRT1170_CAAM))
5259
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5260
int wc_ecc_point_is_at_infinity(ecc_point* p)
5261
12.0k
{
5262
12.0k
    if (p == NULL)
5263
0
        return BAD_FUNC_ARG;
5264
12.0k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5265
3.59k
        return 1;
5266
5267
8.48k
    return 0;
5268
12.0k
}
5269
#endif
5270
5271
/* generate random and ensure its greater than 0 and less than order */
5272
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5273
46.6k
{
5274
46.6k
#ifndef WC_NO_RNG
5275
46.6k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5276
46.6k
    int err;
5277
46.6k
    byte buf[ECC_MAXSIZE_GEN];
5278
5279
46.6k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5280
46.6k
                                                                order == NULL) {
5281
0
        return BAD_FUNC_ARG;
5282
0
    }
5283
5284
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5285
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5286
46.6k
    size += 8;
5287
5288
    /* make up random string */
5289
46.6k
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5290
#ifdef WOLFSSL_CHECK_MEM_ZERO
5291
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5292
#endif
5293
5294
    /* load random buffer data into k */
5295
46.6k
    if (err == 0)
5296
46.3k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5297
5298
    /* the key should be smaller than the order of base point */
5299
46.6k
    if (err == MP_OKAY) {
5300
46.3k
        if (mp_cmp(k, order) != MP_LT) {
5301
46.0k
            err = mp_mod(k, order, k);
5302
46.0k
        }
5303
46.3k
    }
5304
5305
    /* quick sanity check to make sure we're not dealing with a 0 key */
5306
46.6k
    if (err == MP_OKAY) {
5307
46.2k
        if (mp_iszero(k) == MP_YES)
5308
255
          err = MP_ZERO_E;
5309
46.2k
    }
5310
5311
46.6k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5312
#ifdef WOLFSSL_CHECK_MEM_ZERO
5313
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5314
#endif
5315
5316
46.6k
    return err;
5317
#else
5318
    int err;
5319
    byte buf[ECC_MAXSIZE_GEN];
5320
    int bits;
5321
5322
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5323
            (k == NULL) || (order == NULL)) {
5324
        return BAD_FUNC_ARG;
5325
    }
5326
5327
    /* Get actual bit count of order. */
5328
    bits = mp_count_bits(order);
5329
    size = (bits + 7) >> 3;
5330
5331
    /* generate number in range of order through rejection sampling. */
5332
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5333
    do {
5334
        /* A.2.2 step 3: make up random string */
5335
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5336
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5337
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5338
    #endif
5339
        /* Generated multiple of 8 bits but now make it size of order. */
5340
        if ((bits & 0x7) > 0) {
5341
            buf[0] &= (1 << (bits & 0x7)) - 1;
5342
        }
5343
5344
        /* A.2.2 step 4: convert to integer. */
5345
        /* A.4.2 step 3: Convert the bit string to integer x. */
5346
        if (err == 0) {
5347
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5348
        }
5349
5350
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5351
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5352
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5353
            break;
5354
        }
5355
    }
5356
    while (err == MP_OKAY);
5357
5358
    ForceZero(buf, ECC_MAXSIZE_GEN);
5359
#ifdef WOLFSSL_CHECK_MEM_ZERO
5360
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5361
#endif
5362
5363
    return err;
5364
#endif
5365
#else
5366
    (void)rng;
5367
    (void)size;
5368
    (void)k;
5369
    (void)order;
5370
    return NOT_COMPILED_IN;
5371
#endif /* !WC_NO_RNG */
5372
46.6k
}
5373
5374
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5375
52.5k
{
5376
    /* make sure required key variables are reset */
5377
52.5k
    key->state = ECC_STATE_NONE;
5378
52.5k
}
5379
5380
5381
/* create the public ECC key from a private key
5382
 *
5383
 * key     an initialized private key to generate public part from
5384
 * curve   [in]curve for key, cannot be NULL
5385
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5386
 *         is cached in key instead.
5387
 *
5388
 * Note this function is local to the file because of the argument type
5389
 *      ecc_curve_spec. Having this argument allows for not having to load the
5390
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5391
 * For async the results are placed directly into pubOut, so this function
5392
 *      does not need to be called again
5393
 *
5394
 * returns MP_OKAY on success
5395
 */
5396
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5397
        ecc_point* pubOut, WC_RNG* rng)
5398
3.72k
{
5399
3.72k
    int err = MP_OKAY;
5400
3.72k
#ifdef HAVE_ECC_MAKE_PUB
5401
3.72k
    ecc_point* pub;
5402
3.72k
#endif /* HAVE_ECC_MAKE_PUB */
5403
5404
3.72k
    (void)rng;
5405
5406
3.72k
    if (key == NULL) {
5407
0
        return BAD_FUNC_ARG;
5408
0
    }
5409
5410
3.72k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5411
5412
3.72k
#ifdef HAVE_ECC_MAKE_PUB
5413
    /* if ecc_point passed in then use it as output for public key point */
5414
3.72k
    if (pubOut != NULL) {
5415
2.12k
        pub = pubOut;
5416
2.12k
    }
5417
1.59k
    else {
5418
        /* caching public key making it a ECC_PRIVATEKEY instead of
5419
           ECC_PRIVATEKEY_ONLY */
5420
1.59k
        pub = &key->pubkey;
5421
1.59k
        key->type = ECC_PRIVATEKEY_ONLY;
5422
1.59k
    }
5423
5424
3.72k
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5425
3.72k
            mp_isneg(ecc_get_k(key)) ||
5426
3.72k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5427
39
        err = ECC_PRIV_KEY_E;
5428
39
    }
5429
5430
3.72k
    if (err == MP_OKAY) {
5431
3.68k
    #ifndef ALT_ECC_SIZE
5432
3.68k
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5433
    #else
5434
        pub->x = (mp_int*)&pub->xyz[0];
5435
        pub->y = (mp_int*)&pub->xyz[1];
5436
        pub->z = (mp_int*)&pub->xyz[2];
5437
        alt_fp_init(pub->x);
5438
        alt_fp_init(pub->y);
5439
        alt_fp_init(pub->z);
5440
    #endif
5441
3.68k
    }
5442
5443
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5444
    defined(HAVE_INTEL_QA)
5445
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5446
        word32 keySz = key->dp->size;
5447
        /* sync private key to raw */
5448
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5449
        if (err == MP_OKAY) {
5450
            err = IntelQaEccPointMul(&key->asyncDev,
5451
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5452
                &curve->Gx->raw, &curve->Gy->raw,
5453
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5454
                key->dp->cofactor);
5455
        }
5456
    }
5457
    else
5458
#endif
5459
3.72k
    { /* BEGIN: Software Crypto */
5460
3.72k
#ifdef WOLFSSL_HAVE_SP_ECC
5461
    /* Single-Precision Math (optimized for specific curves) */
5462
3.72k
    if (err != MP_OKAY) {
5463
39
    }
5464
3.68k
    else
5465
3.68k
#ifndef WOLFSSL_SP_NO_256
5466
3.68k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5467
975
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5468
975
    }
5469
2.70k
    else
5470
2.70k
#endif /* WOLFSSL_SP_NO_256 */
5471
2.70k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5472
2.70k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5473
580
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5474
580
    }
5475
2.12k
    else
5476
2.12k
#endif
5477
2.12k
#ifdef WOLFSSL_SP_384
5478
2.12k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5479
753
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5480
753
    }
5481
1.37k
    else
5482
1.37k
#endif
5483
1.37k
#ifdef WOLFSSL_SP_521
5484
1.37k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5485
1.37k
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5486
1.37k
    }
5487
0
    else
5488
0
#endif
5489
0
#endif /* WOLFSSL_HAVE_SP_ECC */
5490
5491
0
#if defined(WOLFSSL_SP_MATH)
5492
0
        err = WC_KEY_SIZE_E;
5493
#else
5494
    if (err == MP_OKAY) {
5495
        /* Multi-Precision Math: compute public curve */
5496
        mp_digit mp = 0;
5497
        ecc_point* base = NULL;
5498
    #ifdef WOLFSSL_NO_MALLOC
5499
        ecc_point  lcl_base;
5500
        base = &lcl_base;
5501
    #endif
5502
        err = wc_ecc_new_point_ex(&base, key->heap);
5503
5504
        /* read in the x/y for this key */
5505
        if (err == MP_OKAY)
5506
            err = mp_copy(curve->Gx, base->x);
5507
        if (err == MP_OKAY)
5508
            err = mp_copy(curve->Gy, base->y);
5509
        if (err == MP_OKAY)
5510
            err = mp_montgomery_setup(curve->prime, &mp);
5511
        if (err == MP_OKAY)
5512
            err = mp_set(base->z, 1);
5513
5514
        /* make the public key */
5515
        if (err == MP_OKAY) {
5516
            /* Map in a separate call as this should be constant time */
5517
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5518
                                 curve->prime, curve->order, rng, 0, key->heap);
5519
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5520
               err = MEMORY_E;
5521
            }
5522
        }
5523
        if (err == MP_OKAY) {
5524
            /* Use constant time map if compiled in */
5525
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5526
        }
5527
5528
        wc_ecc_del_point_ex(base, key->heap);
5529
    }
5530
#endif /* WOLFSSL_SP_MATH */
5531
3.72k
    } /* END: Software Crypto */
5532
5533
3.72k
    if (err != MP_OKAY
5534
    #ifdef WOLFSSL_ASYNC_CRYPT
5535
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5536
    #endif
5537
3.72k
    ) {
5538
        /* clean up if failed */
5539
82
    #ifndef ALT_ECC_SIZE
5540
82
        mp_clear(pub->x);
5541
82
        mp_clear(pub->y);
5542
82
        mp_clear(pub->z);
5543
82
    #endif
5544
82
    }
5545
5546
#else
5547
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5548
    (void)curve;
5549
    err = NOT_COMPILED_IN;
5550
#endif /* HAVE_ECC_MAKE_PUB */
5551
5552
    /* change key state if public part is cached */
5553
3.72k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5554
1.59k
        key->type = ECC_PRIVATEKEY;
5555
1.59k
    }
5556
5557
3.72k
    RESTORE_VECTOR_REGISTERS();
5558
5559
3.72k
    return err;
5560
3.72k
}
5561
5562
5563
/* create the public ECC key from a private key
5564
 *
5565
 * key     an initialized private key to generate public part from
5566
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5567
 *         is cached in key instead.
5568
 *
5569
 *
5570
 * returns MP_OKAY on success
5571
 */
5572
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5573
5.75k
{
5574
5.75k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5575
5576
5.75k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5577
5.75k
}
5578
5579
/* create the public ECC key from a private key - mask timing use random z
5580
 *
5581
 * key     an initialized private key to generate public part from
5582
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5583
 *         is cached in key instead.
5584
 *
5585
 *
5586
 * returns MP_OKAY on success
5587
 */
5588
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5589
3.58k
{
5590
3.58k
    int err = MP_OKAY;
5591
3.58k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5592
5593
3.58k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5594
5595
3.58k
    if (key == NULL) {
5596
0
        return BAD_FUNC_ARG;
5597
0
    }
5598
5599
    /* load curve info */
5600
3.58k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5601
3.58k
    if (err == MP_OKAY) {
5602
3.56k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5603
3.56k
    }
5604
3.58k
    if (err == MP_OKAY) {
5605
3.56k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5606
3.56k
    }
5607
5608
3.58k
    wc_ecc_curve_free(curve);
5609
3.58k
    FREE_CURVE_SPECS();
5610
5611
3.58k
    return err;
5612
3.58k
}
5613
5614
5615
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5616
        int curve_id, int flags)
5617
913
{
5618
913
    int err = 0;
5619
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5620
    !defined(WOLFSSL_ATECC608A)
5621
    const CRYS_ECPKI_Domain_t*  pDomain;
5622
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5623
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5624
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5625
    word32 raw_size = 0;
5626
#endif
5627
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5628
    defined(WC_ECC_NONBLOCK_ONLY)
5629
    ecc_nb_ctx_t nb_ctx;
5630
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5631
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5632
5633
913
    if (key == NULL || rng == NULL) {
5634
0
        return BAD_FUNC_ARG;
5635
0
    }
5636
5637
    /* make sure required variables are reset */
5638
913
    wc_ecc_reset(key);
5639
5640
    #if FIPS_VERSION3_GE(6,0,0)
5641
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5642
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5643
     * keysize here when relying on default selection */
5644
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5645
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5646
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5647
             curve_id == ECC_SECP521R1)) {
5648
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5649
            err = 0;
5650
        } else {
5651
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5652
            err = ECC_CURVE_OID_E;
5653
        }
5654
    }
5655
    if (err == 0) { /* FIPS specific check */
5656
    #endif
5657
913
    err = wc_ecc_set_curve(key, keysize, curve_id);
5658
913
    if (err != 0) {
5659
47
        return err;
5660
47
    }
5661
    #if FIPS_VERSION3_GE(6,0,0)
5662
    } /* end FIPS specific check */
5663
    #endif
5664
866
    key->flags = (byte)flags;
5665
5666
866
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5667
866
    #ifndef WOLF_CRYPTO_CB_FIND
5668
866
    if (key->devId != INVALID_DEVID)
5669
0
    #endif
5670
0
    {
5671
0
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5672
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5673
0
            return err;
5674
        /* fall-through when unavailable */
5675
0
    }
5676
866
#endif
5677
5678
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5679
    return NO_VALID_DEVID;
5680
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5681
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5682
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5683
    #ifdef HAVE_CAVIUM
5684
        /* TODO: Not implemented */
5685
    #elif defined(HAVE_INTEL_QA)
5686
        /* Implemented in ecc_make_pub_ex for the pub calc */
5687
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5688
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5689
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5690
            sw->eccMake.rng = rng;
5691
            sw->eccMake.key = key;
5692
            sw->eccMake.size = keysize;
5693
            sw->eccMake.curve_id = curve_id;
5694
            return WC_PENDING_E;
5695
        }
5696
    #endif
5697
    }
5698
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5699
5700
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5701
   if (key->dp->id == ECC_SECP256R1) {
5702
       key->type = ECC_PRIVATEKEY;
5703
       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5704
       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
5705
5706
       /* populate key->pubkey */
5707
       if (err == 0
5708
       #ifdef ALT_ECC_SIZE
5709
          && key->pubkey.x
5710
       #endif
5711
       ) {
5712
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5713
                                      ECC_MAX_CRYPTO_HW_SIZE);
5714
       }
5715
       if (err == 0
5716
       #ifdef ALT_ECC_SIZE
5717
          && key->pubkey.y
5718
       #endif
5719
       ) {
5720
           err = mp_read_unsigned_bin(key->pubkey.y,
5721
                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
5722
                                      ECC_MAX_CRYPTO_HW_SIZE);
5723
       }
5724
   }
5725
   else {
5726
      err = NOT_COMPILED_IN;
5727
   }
5728
#elif defined(WOLFSSL_SE050)
5729
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5730
    key->type = ECC_PRIVATEKEY;
5731
#elif defined(WOLFSSL_CRYPTOCELL)
5732
5733
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5734
    raw_size = (word32)(key->dp->size)*2 + 1;
5735
5736
    /* generate first key pair */
5737
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5738
                                wc_rndGenVectFunc,
5739
                                pDomain,
5740
                                &key->ctx.privKey,
5741
                                &key->ctx.pubKey,
5742
                                &tempBuff,
5743
                                &fipsCtx);
5744
5745
    if (err != SA_SILIB_RET_OK){
5746
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5747
        return err;
5748
    }
5749
    key->type = ECC_PRIVATEKEY;
5750
5751
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5752
                                   CRYS_EC_PointUncompressed,
5753
                                   &ucompressed_key[0],
5754
                                   (uint32_t*)&raw_size);
5755
5756
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5757
        err = mp_read_unsigned_bin(key->pubkey.x,
5758
                                   &ucompressed_key[1], key->dp->size);
5759
        if (err == MP_OKAY) {
5760
            err = mp_read_unsigned_bin(key->pubkey.y,
5761
                            &ucompressed_key[1+key->dp->size],key->dp->size);
5762
        }
5763
    }
5764
    raw_size = key->dp->size;
5765
    if (err == MP_OKAY) {
5766
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
5767
                                       ucompressed_key,
5768
                                       (uint32_t*)&raw_size);
5769
    }
5770
5771
    if (err == SA_SILIB_RET_OK) {
5772
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
5773
#ifdef WOLFSSL_ECC_BLIND_K
5774
        if (err == MP_OKAY) {
5775
            err = ecc_blind_k_rng(key, rng);
5776
        }
5777
#endif
5778
    }
5779
5780
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5781
    return silabs_ecc_make_key(key, keysize);
5782
#elif defined(WOLFSSL_KCAPI_ECC)
5783
5784
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
5785
    (void)rng;
5786
5787
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
5788
    if (xil_curve_type[key->dp->id] == 0)
5789
        return ECC_CURVE_OID_E;
5790
5791
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
5792
    if (err)
5793
        return err;
5794
    /* Make sure that private key is max. 521 bits */
5795
    if (key->dp->size == 66)
5796
        key->privKey[65] &= 0x1U;
5797
5798
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
5799
5800
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5801
                                        2 * key->dp->size);
5802
5803
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
5804
                                      xil_curve_type[key->dp->id],
5805
                                      XIL_CAST_U64(key->privKey),
5806
                                      XIL_CAST_U64(key->keyRaw));
5807
    if (err != XST_SUCCESS) {
5808
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
5809
        err = WC_HW_E;
5810
    }
5811
5812
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5813
                                        2 * key->dp->size);
5814
5815
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
5816
    if (err == 0)
5817
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
5818
                                          xil_curve_type[key->dp->id],
5819
                                          XIL_CAST_U64(key->keyRaw));
5820
#endif
5821
5822
    if (err == 0)
5823
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
5824
                             key->heap);
5825
    if (err == 0)
5826
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
5827
                             key->dp->size, key->heap);
5828
    if (err == 0)
5829
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
5830
                             key->heap);
5831
#ifdef WOLFSSL_ECC_BLIND_K
5832
    if (err == 0)
5833
        err = ecc_blind_k_rng(key, rng);
5834
#endif
5835
    if (err == 0)
5836
        err = mp_set(key->pubkey.z, 1);
5837
    if (err) {
5838
        key->privKey = NULL;
5839
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
5840
        return err;
5841
    }
5842
5843
    key->type = ECC_PRIVATEKEY;
5844
5845
#else
5846
5847
866
#ifdef WOLFSSL_HAVE_SP_ECC
5848
5849
866
#ifndef WOLFSSL_SP_NO_256
5850
866
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5851
230
    #ifndef WC_ECC_NONBLOCK
5852
230
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5853
    #else
5854
        if (key->nb_ctx) {
5855
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5856
                                         &key->pubkey, key->heap);
5857
        }
5858
        else {
5859
        #ifdef WC_ECC_NONBLOCK_ONLY
5860
            do { /* perform blocking call to non-blocking function */
5861
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
5862
                                             &key->pubkey, key->heap);
5863
            } while (err == FP_WOULDBLOCK);
5864
        #else
5865
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5866
        #endif /* WC_ECC_NONBLOCK_ONLY */
5867
        }
5868
    #endif /* !WC_ECC_NONBLOCK */
5869
5870
230
        if (err == MP_OKAY) {
5871
197
            key->type = ECC_PRIVATEKEY;
5872
197
        }
5873
230
    }
5874
636
    else
5875
636
#endif /* !WOLFSSL_SP_NO_256 */
5876
636
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5877
636
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5878
161
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
5879
161
        if (err == MP_OKAY) {
5880
130
            key->type = ECC_PRIVATEKEY;
5881
130
        }
5882
161
    }
5883
475
    else
5884
475
#endif
5885
475
#ifdef WOLFSSL_SP_384
5886
475
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5887
240
    #ifndef WC_ECC_NONBLOCK
5888
240
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5889
    #else
5890
        if (key->nb_ctx) {
5891
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5892
                                         &key->pubkey, key->heap);
5893
        }
5894
        else {
5895
        #ifdef WC_ECC_NONBLOCK_ONLY
5896
            do { /* perform blocking call to non-blocking function */
5897
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
5898
                                             &key->pubkey, key->heap);
5899
            } while (err == FP_WOULDBLOCK);
5900
        #else
5901
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5902
        #endif /* WC_ECC_NONBLOCK_ONLY */
5903
        }
5904
    #endif /* !WC_ECC_NONBLOCK */
5905
5906
240
        if (err == MP_OKAY) {
5907
210
            key->type = ECC_PRIVATEKEY;
5908
210
        }
5909
240
    }
5910
235
    else
5911
235
#endif /* WOLFSSL_SP_384 */
5912
235
#ifdef WOLFSSL_SP_521
5913
235
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5914
235
    #ifndef WC_ECC_NONBLOCK
5915
235
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5916
    #else
5917
        if (key->nb_ctx) {
5918
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5919
                                         &key->pubkey, key->heap);
5920
        }
5921
        else {
5922
        #ifdef WC_ECC_NONBLOCK_ONLY
5923
            do { /* perform blocking call to non-blocking function */
5924
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
5925
                                             &key->pubkey, key->heap);
5926
            } while (err == FP_WOULDBLOCK);
5927
        #else
5928
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5929
        #endif /* WC_ECC_NONBLOCK_ONLY */
5930
        }
5931
    #endif /* !WC_ECC_NONBLOCK */
5932
5933
235
        if (err == MP_OKAY) {
5934
199
            key->type = ECC_PRIVATEKEY;
5935
199
        }
5936
235
    }
5937
0
    else
5938
0
#endif /* WOLFSSL_SP_521 */
5939
0
#endif /* WOLFSSL_HAVE_SP_ECC */
5940
5941
0
   { /* software key gen */
5942
0
#if defined(WOLFSSL_SP_MATH)
5943
0
        err = WC_KEY_SIZE_E;
5944
#else
5945
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5946
5947
        /* setup the key variables */
5948
#ifndef ALT_ECC_SIZE
5949
        err = mp_init(key->k);
5950
#else
5951
        err = 0;
5952
        key->k = (mp_int*)key->ka;
5953
        alt_fp_init(key->k);
5954
#endif
5955
5956
        /* load curve info */
5957
        if (err == MP_OKAY) {
5958
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5959
            if (err != MP_OKAY) {
5960
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5961
            }
5962
        }
5963
5964
        if (err == MP_OKAY) {
5965
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5966
            if (err != MP_OKAY) {
5967
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5968
            }
5969
        }
5970
5971
        /* generate k */
5972
        if (err == MP_OKAY) {
5973
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5974
            if (err != MP_OKAY) {
5975
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5976
            }
5977
        }
5978
5979
        /* generate public key from k */
5980
        if (err == MP_OKAY) {
5981
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5982
            if (err != MP_OKAY) {
5983
                WOLFSSL_MSG("ecc_make_pub_ex failed");
5984
            }
5985
        }
5986
5987
        if (err == MP_OKAY
5988
        #ifdef WOLFSSL_ASYNC_CRYPT
5989
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
5990
        #endif
5991
        ) {
5992
            key->type = ECC_PRIVATEKEY;
5993
        }
5994
        else {
5995
            /* cleanup these on failure case only */
5996
            mp_forcezero(key->k);
5997
        }
5998
5999
        /* cleanup allocations */
6000
        wc_ecc_curve_free(curve);
6001
        FREE_CURVE_SPECS();
6002
#endif /* WOLFSSL_SP_MATH */
6003
0
    }
6004
6005
#ifdef HAVE_WOLF_BIGINT
6006
    if (err == MP_OKAY)
6007
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6008
    if (err == MP_OKAY)
6009
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6010
    if (err == MP_OKAY)
6011
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6012
    if (err == MP_OKAY)
6013
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6014
#endif
6015
6016
#ifdef WOLFSSL_ECC_BLIND_K
6017
    if (err == MP_OKAY)
6018
        err = ecc_blind_k_rng(key, rng);
6019
#endif
6020
6021
866
#endif /* HAVE_ECC_MAKE_PUB */
6022
6023
866
    return err;
6024
866
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6025
866
}
6026
6027
6028
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6029
                        int flags)
6030
14.5k
{
6031
14.5k
    int err;
6032
6033
14.5k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6034
6035
14.5k
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6036
6037
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6038
    !defined(WOLFSSL_KCAPI_ECC)
6039
    if (err == MP_OKAY) {
6040
        err = _ecc_validate_public_key(key, 0, 0);
6041
    }
6042
    if (err == MP_OKAY
6043
#if defined(WOLF_CRYPTO_CB)
6044
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6045
        && key->devId == INVALID_DEVID
6046
#endif
6047
        ) {
6048
        err = _ecc_pairwise_consistency_test(key, rng);
6049
    }
6050
#endif
6051
6052
14.5k
    RESTORE_VECTOR_REGISTERS();
6053
6054
14.5k
    return err;
6055
14.5k
}
6056
6057
WOLFSSL_ABI
6058
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6059
14.5k
{
6060
14.5k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6061
14.5k
}
6062
6063
#ifdef ECC_DUMP_OID
6064
/* Optional dump of encoded OID for adding new curves */
6065
static int mOidDumpDone;
6066
static void wc_ecc_dump_oids(void)
6067
{
6068
    int x;
6069
6070
    if (mOidDumpDone) {
6071
        return;
6072
    }
6073
6074
    /* find matching OID sum (based on encoded value) */
6075
    for (x = 0; ecc_sets[x].size != 0; x++) {
6076
        int i;
6077
        byte* oid;
6078
        word32 oidSz, sum = 0;
6079
6080
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6081
6082
    #ifdef HAVE_OID_ENCODING
6083
        byte oidEnc[ECC_MAX_OID_LEN];
6084
6085
        oid = oidEnc;
6086
        oidSz = ECC_MAX_OID_LEN;
6087
6088
        printf("OID: ");
6089
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6090
            printf("%d.", ecc_sets[x].oid[i]);
6091
        }
6092
        printf("\n");
6093
6094
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6095
    #else
6096
        oid = (byte*)ecc_sets[x].oid;
6097
        oidSz = ecc_sets[x].oidSz;
6098
    #endif
6099
6100
        printf("OID Encoded: ");
6101
        for (i = 0; i < (int)oidSz; i++) {
6102
            printf("0x%02X,", oid[i]);
6103
        }
6104
        printf("\n");
6105
6106
        for (i = 0; i < (int)oidSz; i++) {
6107
            sum += oid[i];
6108
        }
6109
        printf("Sum: %u\n", sum);
6110
6111
        /* validate sum */
6112
        if (ecc_sets[x].oidSum != sum) {
6113
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6114
        }
6115
    }
6116
    mOidDumpDone = 1;
6117
}
6118
#endif /* ECC_DUMP_OID */
6119
6120
6121
WOLFSSL_ABI
6122
ecc_key* wc_ecc_key_new(void* heap)
6123
38.2k
{
6124
38.2k
    int devId = INVALID_DEVID;
6125
38.2k
    ecc_key* key;
6126
6127
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6128
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6129
    devId = WOLFSSL_CAAM_DEVID;
6130
#endif
6131
38.2k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6132
38.2k
    if (key) {
6133
34.1k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6134
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6135
0
            key = NULL;
6136
0
        }
6137
34.1k
    }
6138
6139
38.2k
    return key;
6140
38.2k
}
6141
6142
6143
WOLFSSL_ABI
6144
void wc_ecc_key_free(ecc_key* key)
6145
104k
{
6146
104k
    if (key) {
6147
34.1k
        void* heap = key->heap;
6148
6149
34.1k
        wc_ecc_free(key);
6150
34.1k
        ForceZero(key, sizeof(ecc_key));
6151
34.1k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6152
34.1k
        (void)heap;
6153
34.1k
    }
6154
104k
}
6155
6156
6157
/**
6158
 Make a new ECC key
6159
 rng          An active RNG state
6160
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6161
 key          [out] Destination of the newly created key
6162
 return       MP_OKAY if successful,
6163
 upon error all allocated memory will be freed
6164
 */
6165
WOLFSSL_ABI
6166
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6167
0
{
6168
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6169
0
}
6170
6171
/* Setup dynamic pointers if using normal math for proper freeing */
6172
WOLFSSL_ABI
6173
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6174
59.2k
{
6175
59.2k
    int ret      = 0;
6176
6177
59.2k
    if (key == NULL) {
6178
0
        return BAD_FUNC_ARG;
6179
0
    }
6180
6181
#ifdef ECC_DUMP_OID
6182
    wc_ecc_dump_oids();
6183
#endif
6184
6185
59.2k
    XMEMSET(key, 0, sizeof(ecc_key));
6186
59.2k
    key->state = ECC_STATE_NONE;
6187
6188
59.2k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6189
59.2k
    key->devId = devId;
6190
#else
6191
    (void)devId;
6192
#endif
6193
6194
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6195
    key->slot = ATECC_INVALID_SLOT;
6196
#else
6197
#if defined(WOLFSSL_KCAPI_ECC)
6198
    key->handle = NULL;
6199
#endif
6200
#ifdef ALT_ECC_SIZE
6201
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6202
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6203
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6204
    alt_fp_init(key->pubkey.x);
6205
    alt_fp_init(key->pubkey.y);
6206
    alt_fp_init(key->pubkey.z);
6207
    key->k = (mp_int*)key->ka;
6208
    alt_fp_init(key->k);
6209
#ifdef WOLFSSL_ECC_BLIND_K
6210
    key->kb = (mp_int*)key->kba;
6211
    key->ku = (mp_int*)key->kia;
6212
    alt_fp_init(key->kb);
6213
    alt_fp_init(key->ku);
6214
#endif
6215
#else
6216
59.2k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6217
59.2k
#ifndef WOLFSSL_ECC_BLIND_K
6218
59.2k
                                                                      NULL, NULL
6219
#else
6220
                                                                key->kb, key->ku
6221
#endif
6222
59.2k
                        );
6223
59.2k
    if (ret != MP_OKAY) {
6224
0
        return MEMORY_E;
6225
0
    }
6226
59.2k
#endif /* ALT_ECC_SIZE */
6227
#ifdef WOLFSSL_ECC_BLIND_K
6228
    mp_forcezero(key->kb);
6229
#endif
6230
59.2k
#endif /* WOLFSSL_ATECC508A */
6231
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6232
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6233
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6234
     defined(WOLFSSL_NO_MALLOC)
6235
    ret = mp_init(key->sign_k);
6236
    if (ret != MP_OKAY) {
6237
        return MEMORY_E;
6238
    }
6239
#endif
6240
6241
#ifdef WOLFSSL_HEAP_TEST
6242
    (void)heap;
6243
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6244
#else
6245
59.2k
    key->heap = heap;
6246
59.2k
#endif
6247
6248
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6249
    #ifdef WOLF_CRYPTO_CB
6250
    /* prefer crypto callback */
6251
    if (key->devId != INVALID_DEVID)
6252
    #endif
6253
    {
6254
        /* handle as async */
6255
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6256
                                                        key->heap, devId);
6257
    }
6258
    if (ret != 0)
6259
        return ret;
6260
#endif
6261
6262
#if defined(WOLFSSL_DSP)
6263
    key->handle = -1;
6264
#endif
6265
6266
#ifdef WOLFSSL_SE050
6267
    key->keyId = 0;
6268
    key->keyIdSet = 0;
6269
#endif
6270
6271
#ifdef WOLFSSL_CHECK_MEM_ZERO
6272
    mp_memzero_add("ECC k", key->k);
6273
#ifdef WOLFSSL_ECC_BLIND_K
6274
    mp_memzero_add("ECC kb", key->kb);
6275
    mp_memzero_add("ECC ku", key->ku);
6276
#endif
6277
#endif
6278
6279
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6280
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6281
6282
    if (wc_InitXsecure(&(key->xSec))) {
6283
        WOLFSSL_MSG("Can't initialize Xsecure");
6284
        return WC_HW_E;
6285
    }
6286
#endif
6287
6288
59.2k
    return ret;
6289
59.2k
}
6290
6291
WOLFSSL_ABI
6292
int wc_ecc_init(ecc_key* key)
6293
2.87k
{
6294
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6295
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6296
#else
6297
2.87k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6298
2.87k
#endif
6299
2.87k
}
6300
6301
#ifdef WOLF_PRIVATE_KEY_ID
6302
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6303
                   int devId)
6304
0
{
6305
0
    int ret = 0;
6306
#ifdef WOLFSSL_SE050
6307
    /* SE050 TLS users store a word32 at id, need to cast back */
6308
    word32* keyPtr = NULL;
6309
#endif
6310
6311
0
    if (key == NULL)
6312
0
        ret = BAD_FUNC_ARG;
6313
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6314
0
        ret = BUFFER_E;
6315
0
    if (ret == 0)
6316
0
        ret = wc_ecc_init_ex(key, heap, devId);
6317
0
    if (ret == 0 && id != NULL && len != 0) {
6318
0
        XMEMCPY(key->id, id, (size_t)len);
6319
0
        key->idLen = len;
6320
    #ifdef WOLFSSL_SE050
6321
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6322
        if (len == (int)sizeof(word32)) {
6323
            keyPtr = (word32*)key->id;
6324
            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
6325
        }
6326
    #endif
6327
0
    }
6328
6329
0
    return ret;
6330
0
}
6331
6332
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6333
0
{
6334
0
    int ret = 0;
6335
0
    int labelLen = 0;
6336
6337
0
    if (key == NULL || label == NULL)
6338
0
        ret = BAD_FUNC_ARG;
6339
0
    if (ret == 0) {
6340
0
        labelLen = (int)XSTRLEN(label);
6341
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6342
0
            ret = BUFFER_E;
6343
0
    }
6344
0
    if (ret == 0)
6345
0
        ret = wc_ecc_init_ex(key, heap, devId);
6346
0
    if (ret == 0) {
6347
0
        XMEMCPY(key->label, label, (size_t)labelLen);
6348
0
        key->labelLen = labelLen;
6349
0
    }
6350
6351
0
    return ret;
6352
0
}
6353
#endif /* WOLF_PRIVATE_KEY_ID */
6354
6355
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6356
639
{
6357
639
    if (key == NULL) {
6358
0
        return BAD_FUNC_ARG;
6359
0
    }
6360
639
    key->flags |= flags;
6361
639
    return 0;
6362
639
}
6363
6364
6365
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6366
{
6367
    int err = MP_OKAY;
6368
    int orderBits;
6369
    DECLARE_CURVE_SPECS(1);
6370
6371
    ALLOC_CURVE_SPECS(1, err);
6372
    if (err == MP_OKAY) {
6373
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6374
    }
6375
6376
    if (err != 0) {
6377
       FREE_CURVE_SPECS();
6378
       return err;
6379
    }
6380
    orderBits = mp_count_bits(curve->order);
6381
6382
    wc_ecc_curve_free(curve);
6383
    FREE_CURVE_SPECS();
6384
    return orderBits;
6385
}
6386
6387
#ifdef HAVE_ECC_SIGN
6388
6389
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6390
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6391
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6392
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6393
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6394
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6395
    ecc_key* key)
6396
{
6397
    int err;
6398
#ifdef PLUTON_CRYPTO_ECC
6399
    if (key->devId != INVALID_DEVID) /* use hardware */
6400
#endif
6401
    {
6402
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6403
        !defined(WOLFSSL_ATECC608A)
6404
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6405
        word32 raw_sig_size = *outlen;
6406
        word32 msgLenInBytes = inlen;
6407
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6408
    #endif
6409
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6410
#ifdef WOLFSSL_SMALL_STACK
6411
        byte* K = NULL;
6412
        byte* incopy = NULL;
6413
#else
6414
        byte K[MAX_ECC_BYTES] = {0};
6415
        byte incopy[MAX_ECC_BYTES] = {0};
6416
#endif
6417
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6418
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6419
        word32 Ksize;
6420
#endif
6421
#endif
6422
        word32 keysize = (word32)key->dp->size;
6423
    #ifdef PLUTON_CRYPTO_ECC
6424
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6425
    #endif
6426
6427
    #ifndef WOLFSSL_KCAPI_ECC
6428
        /* Check args */
6429
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6430
            return ECC_BAD_ARG_E;
6431
        }
6432
    #endif
6433
6434
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6435
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6436
        err = atmel_ecc_sign(key->slot, in, out);
6437
        if (err != 0) {
6438
           return err;
6439
        }
6440
    #elif defined(PLUTON_CRYPTO_ECC)
6441
        {
6442
            /* if the input is larger than curve order, we must truncate */
6443
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6444
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6445
            }
6446
6447
            /* perform ECC sign */
6448
            word32 raw_sig_size = *outlen;
6449
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6450
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6451
               return BAD_COND_E;
6452
            }
6453
        }
6454
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6455
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6456
        if (err != 0) {
6457
               return WC_HW_E;
6458
        }
6459
    #elif defined(WOLFSSL_CRYPTOCELL)
6460
        /* truncate if hash is longer than key size */
6461
        if (msgLenInBytes > keysize) {
6462
            msgLenInBytes = keysize;
6463
        }
6464
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6465
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6466
            (void)cc310_hashModeECC(keysize);
6467
            /* Ignoring returned value */
6468
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6469
6470
        }
6471
6472
        /* create signature from an input buffer using a private key*/
6473
        err = CRYS_ECDSA_Sign(&wc_rndState,
6474
                               wc_rndGenVectFunc,
6475
                               &sigCtxTemp,
6476
                               &key->ctx.privKey,
6477
                               hash_mode,
6478
                               (byte*)in,
6479
                               msgLenInBytes,
6480
                               out,
6481
                               (uint32_t*)&raw_sig_size);
6482
6483
        if (err != SA_SILIB_RET_OK){
6484
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6485
            return err;
6486
        }
6487
    #elif defined(WOLFSSL_KCAPI_ECC)
6488
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6489
        if (err != MP_OKAY) {
6490
            return err;
6491
        }
6492
        (void)rng;
6493
    #elif defined(WOLFSSL_SE050)
6494
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6495
        if (err != MP_OKAY) {
6496
            return err;
6497
        }
6498
        (void)rng;
6499
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6500
6501
#ifdef WOLFSSL_SMALL_STACK
6502
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6503
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6504
        if (K == NULL || incopy == NULL) {
6505
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6506
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6507
            return MEMORY_E;
6508
        }
6509
#else
6510
        if (inlen > sizeof(incopy))
6511
            return ECC_BAD_ARG_E;
6512
#endif
6513
6514
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6515
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6516
        err = deterministic_sign_helper(in, inlen, key);
6517
        if (err)
6518
            return err;
6519
        Ksize = mp_unsigned_bin_size(key->sign_k);
6520
        if (Ksize > keysize) {
6521
            err = BUFFER_E;
6522
            goto error_out;
6523
        }
6524
        err = mp_to_unsigned_bin(key->sign_k, K);
6525
        if (err)
6526
            goto error_out;
6527
        mp_reverse(K, Ksize);
6528
#else
6529
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6530
        if (err)
6531
            goto error_out;
6532
        /* Make sure that K is max. 521 bits */
6533
        if (keysize == 66)
6534
            K[65] &= 0x1;
6535
#endif
6536
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6537
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6538
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6539
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6540
6541
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6542
6543
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6544
                                           xil_curve_type[key->dp->id],
6545
                                           XIL_CAST_U64(incopy), keysize,
6546
                                           XIL_CAST_U64(key->privKey),
6547
                                           XIL_CAST_U64(K),
6548
                                           XIL_CAST_U64(out));
6549
        if (err) {
6550
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6551
            err = WC_HW_E;
6552
        }
6553
6554
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6555
        mp_reverse(&out[0], keysize);
6556
        mp_reverse(&out[keysize], keysize);
6557
6558
error_out:
6559
        ForceZero(K, MAX_ECC_BYTES);
6560
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6561
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6562
        if (err) {
6563
            ForceZero(out, keysize * 2);
6564
            return err;
6565
        }
6566
    #endif /* HW-specific #if-#elif chain */
6567
6568
    #ifndef WOLFSSL_SE050
6569
        /* Load R and S, SE050 does this in port layer */
6570
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6571
        if (err != MP_OKAY) {
6572
            return err;
6573
        }
6574
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6575
        if (err != MP_OKAY) {
6576
            return err;
6577
        }
6578
    #endif
6579
6580
        /* Check for zeros */
6581
        if (mp_iszero(r) || mp_iszero(s)) {
6582
            return MP_ZERO_E;
6583
        }
6584
    }
6585
#ifdef PLUTON_CRYPTO_ECC
6586
    else {
6587
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6588
    }
6589
#endif
6590
    (void)rng;
6591
6592
    return err;
6593
}
6594
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6595
6596
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6597
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6598
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6599
{
6600
    int err;
6601
    mp_int *r = NULL, *s = NULL;
6602
6603
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6604
                                                                rng == NULL) {
6605
        return ECC_BAD_ARG_E;
6606
    }
6607
6608
    err = wc_ecc_alloc_async(key);
6609
    if (err != 0) {
6610
        return err;
6611
    }
6612
    r = key->r;
6613
    s = key->s;
6614
6615
    switch (key->state) {
6616
        case ECC_STATE_NONE:
6617
        case ECC_STATE_SIGN_DO:
6618
            key->state = ECC_STATE_SIGN_DO;
6619
6620
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6621
                break;
6622
            }
6623
6624
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6625
            if (err < 0) {
6626
                break;
6627
            }
6628
6629
            FALL_THROUGH;
6630
6631
        case ECC_STATE_SIGN_ENCODE:
6632
            key->state = ECC_STATE_SIGN_ENCODE;
6633
6634
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6635
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6636
                    DECLARE_CURVE_SPECS(1);
6637
                    ALLOC_CURVE_SPECS(1, err);
6638
                    if (err != MP_OKAY) {
6639
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6640
                        break;
6641
                    }
6642
6643
                    /* get curve order */
6644
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6645
                #endif
6646
6647
                #ifdef HAVE_CAVIUM_V
6648
                    /* Nitrox requires r and s in sep buffer, so split it */
6649
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6650
                #endif
6651
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6652
                    /* only do this if not software, since it overwrites result */
6653
                    wc_bigint_to_mp(&r->raw, r);
6654
                    wc_bigint_to_mp(&s->raw, s);
6655
6656
                /* if using a curve with cofactor != 1 then reduce by mod order */
6657
                #ifdef HAVE_ECC_CDH
6658
                    /* if r is not less than order than reduce */
6659
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6660
                        err = mp_mod(r, curve->order, r);
6661
                    }
6662
                    wc_ecc_curve_free(curve);
6663
                    FREE_CURVE_SPECS();
6664
                #endif
6665
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6666
            }
6667
6668
            /* encoded with DSA header */
6669
            if (err == 0) {
6670
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6671
            }
6672
6673
            /* done with R/S */
6674
            mp_clear(r);
6675
            mp_clear(s);
6676
            break;
6677
6678
        default:
6679
            err = BAD_STATE_E;
6680
            break;
6681
    }
6682
6683
    /* if async pending then return and skip done cleanup below */
6684
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6685
        key->state++;
6686
        return err;
6687
    }
6688
6689
    /* cleanup */
6690
    wc_ecc_free_async(key);
6691
    key->state = ECC_STATE_NONE;
6692
6693
    return err;
6694
}
6695
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6696
6697
/**
6698
 Sign a message digest
6699
 in        The message digest to sign
6700
 inlen     The length of the digest
6701
 out       [out] The destination for the signature
6702
 outlen    [in/out] The max size and resulting size of the signature
6703
 key       A private ECC key
6704
 return    MP_OKAY if successful
6705
 */
6706
WOLFSSL_ABI
6707
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6708
                     WC_RNG* rng, ecc_key* key)
6709
3.76k
{
6710
3.76k
    int err;
6711
3.76k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6712
3.76k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6713
3.76k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6714
3.76k
#endif
6715
#ifdef NO_ASN
6716
    word32 keySz;
6717
#endif
6718
6719
3.76k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6720
172
        return ECC_BAD_ARG_E;
6721
172
    }
6722
3.59k
    if (inlen > WC_MAX_DIGEST_SIZE) {
6723
120
        return BAD_LENGTH_E;
6724
120
    }
6725
6726
3.47k
#ifdef WOLF_CRYPTO_CB
6727
3.47k
    #ifndef WOLF_CRYPTO_CB_FIND
6728
3.47k
    if (key->devId != INVALID_DEVID)
6729
0
    #endif
6730
0
    {
6731
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
6732
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6733
0
            return err;
6734
        /* fall-through when unavailable */
6735
0
    }
6736
3.47k
#endif
6737
6738
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6739
    (void)rng;
6740
    (void)inlen;
6741
    (void)s;
6742
    (void)r;
6743
    (void)err;
6744
    return NO_VALID_DEVID;
6745
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6746
3.47k
    if (rng == NULL) {
6747
0
        WOLFSSL_MSG("ECC sign RNG missing");
6748
0
        return ECC_BAD_ARG_E;
6749
0
    }
6750
6751
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6752
    /* handle async cases */
6753
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
6754
#else
6755
6756
3.47k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6757
3.47k
    #ifdef MP_INT_SIZE_CHECK_NULL
6758
3.47k
    if (r == NULL)
6759
5
        return MEMORY_E;
6760
3.46k
    #endif
6761
3.46k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6762
3.46k
    #ifdef MP_INT_SIZE_CHECK_NULL
6763
3.46k
    if (s == NULL) {
6764
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6765
5
        return MEMORY_E;
6766
5
    }
6767
3.46k
    #endif
6768
6769
3.46k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6770
3.46k
    if (err != 0) {
6771
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6772
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6773
0
        return err;
6774
0
    }
6775
3.46k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6776
3.46k
    if (err != 0) {
6777
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6778
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6779
0
        return err;
6780
0
    }
6781
6782
/* hardware crypto */
6783
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6784
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6785
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6786
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6787
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
6788
#else
6789
3.46k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6790
3.46k
#endif
6791
3.46k
    if (err < 0) {
6792
135
        mp_clear(r);
6793
135
        mp_clear(s);
6794
135
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6795
135
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6796
135
        return err;
6797
135
    }
6798
6799
3.32k
#ifndef NO_ASN
6800
    /* encoded with DSA header */
6801
3.32k
    err = StoreECC_DSA_Sig(out, outlen, r, s);
6802
#else
6803
    /* No support for DSA ASN.1 header.
6804
     * Signature will be r+s directly. */
6805
    keySz = 0;
6806
    if (key->dp != NULL) {
6807
        keySz = (word32)key->dp->size;
6808
    }
6809
    if (keySz <= 0) {
6810
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
6811
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
6812
    }
6813
    *outlen = keySz * 2;
6814
6815
    /* Export signature into r,s */
6816
    mp_to_unsigned_bin_len(r, out, keySz);
6817
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
6818
#endif /* !NO_ASN */
6819
6820
    /* cleanup */
6821
3.32k
    mp_clear(r);
6822
3.32k
    mp_clear(s);
6823
6824
3.32k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6825
3.32k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6826
3.32k
#endif /* WOLFSSL_ASYNC_CRYPT */
6827
3.32k
    return err;
6828
3.46k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6829
3.46k
}
6830
6831
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6832
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6833
/* returns MP_OKAY on success */
6834
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
6835
{
6836
    int err = MP_OKAY;
6837
    DECLARE_CURVE_SPECS(1);
6838
    ALLOC_CURVE_SPECS(1, err);
6839
6840
    /* get curve order */
6841
    if (err == MP_OKAY) {
6842
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6843
    }
6844
6845
    if (err == MP_OKAY) {
6846
    #ifndef WOLFSSL_NO_MALLOC
6847
        /* if key->sign_k is NULL then create a buffer for the mp_int
6848
         * if not NULL then assume the user correctly set deterministic flag and
6849
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
6850
        if (key->sign_k == NULL) {
6851
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6852
                                                            DYNAMIC_TYPE_ECC);
6853
            if (key->sign_k != NULL) {
6854
                err = mp_init(key->sign_k);
6855
                if (err != MP_OKAY) {
6856
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6857
                    key->sign_k = NULL;
6858
                }
6859
            }
6860
        }
6861
        if (key->sign_k != NULL) {
6862
            if (wc_ecc_gen_deterministic_k(in, inlen,
6863
                        key->hashType, ecc_get_k(key), key->sign_k,
6864
                        curve->order, key->heap) != 0) {
6865
                mp_free(key->sign_k);
6866
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6867
                key->sign_k = NULL;
6868
                err = ECC_PRIV_KEY_E;
6869
            }
6870
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6871
            else {
6872
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
6873
            }
6874
        #endif
6875
        }
6876
        else {
6877
            err = MEMORY_E;
6878
        }
6879
    #else
6880
        key->sign_k_set = 0;
6881
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
6882
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
6883
            err = ECC_PRIV_KEY_E;
6884
        }
6885
        else {
6886
            key->sign_k_set = 1;
6887
        }
6888
    #endif
6889
    }
6890
6891
    wc_ecc_curve_free(curve);
6892
    FREE_CURVE_SPECS();
6893
    return err;
6894
}
6895
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
6896
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
6897
6898
#if defined(WOLFSSL_STM32_PKA)
6899
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6900
                     ecc_key* key, mp_int *r, mp_int *s)
6901
{
6902
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6903
}
6904
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6905
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
6906
#ifndef WOLFSSL_SP_MATH
6907
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
6908
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
6909
                            mp_int* s)
6910
{
6911
    int err = MP_OKAY;
6912
    int loop_check = 0;
6913
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6914
6915
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6916
#ifdef MP_INT_SIZE_CHECK_NULL
6917
    if (b == NULL)
6918
        err = MEMORY_E;
6919
#endif
6920
6921
    if (err == MP_OKAY) {
6922
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6923
    }
6924
6925
#ifdef WOLFSSL_CUSTOM_CURVES
6926
    /* if custom curve, apply params to pubkey */
6927
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6928
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6929
    }
6930
#endif
6931
6932
    if (err == MP_OKAY) {
6933
        /* Generate blinding value - non-zero value. */
6934
        do {
6935
            if (++loop_check > 64) {
6936
                 err = RNG_FAILURE_E;
6937
                 break;
6938
            }
6939
6940
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6941
        }
6942
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6943
        loop_check = 0;
6944
    }
6945
#ifdef WOLFSSL_CHECK_MEM_ZERO
6946
    if (err == MP_OKAY) {
6947
        mp_memzero_add("ecc_sign_hash_sw b", b);
6948
    }
6949
#endif
6950
6951
    for (; err == MP_OKAY;) {
6952
        if (++loop_check > 64) {
6953
             err = RNG_FAILURE_E;
6954
             break;
6955
        }
6956
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6957
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6958
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6959
#ifndef WOLFSSL_NO_MALLOC
6960
        if (key->sign_k != NULL)
6961
#else
6962
        if (key->sign_k_set)
6963
#endif
6964
        {
6965
            if (loop_check > 1) {
6966
               err = RNG_FAILURE_E;
6967
               break;
6968
            }
6969
6970
            /* use provided sign_k */
6971
            err = mp_copy(key->sign_k, pubkey->k);
6972
            if (err != MP_OKAY) break;
6973
6974
            /* free sign_k, so only used once */
6975
            mp_forcezero(key->sign_k);
6976
#ifndef WOLFSSL_NO_MALLOC
6977
            mp_free(key->sign_k);
6978
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6979
            key->sign_k = NULL;
6980
#else
6981
            key->sign_k_set = 0;
6982
#endif
6983
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6984
            loop_check = 64;
6985
    #endif
6986
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6987
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6988
            if (key->deterministic == 1) {
6989
                /* sign_k generated earlier in function for SP calls.
6990
                 * Only go through the loop once and fail if error */
6991
                loop_check = 64;
6992
            }
6993
    #endif
6994
6995
            /* compute public key based on provided "k" */
6996
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6997
        }
6998
        else
6999
#endif
7000
        {
7001
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
7002
                    WC_ECC_FLAG_NONE);
7003
        }
7004
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7005
        if (err == MP_OKAY) {
7006
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7007
        }
7008
    #endif
7009
    #ifdef WOLFSSL_ASYNC_CRYPT
7010
        /* for async do blocking wait here */
7011
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7012
    #endif
7013
        if (err != MP_OKAY) break;
7014
7015
        /* find r = x1 mod n */
7016
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7017
        if (err != MP_OKAY) break;
7018
7019
        if (mp_iszero(r) == MP_NO) {
7020
            mp_int* kp = ecc_get_k(pubkey);
7021
            mp_int* ep = kp;
7022
            mp_int* x  = ecc_get_k(key);
7023
7024
            /* Blind after getting. */
7025
            ecc_blind_k(key, b);
7026
7027
            /* find s = (e + xr)/k
7028
                      = b.(e/k.b + x.r/k.b) */
7029
7030
            /* k' = k.b */
7031
            err = mp_mulmod(kp, b, curve->order, kp);
7032
            if (err != MP_OKAY) break;
7033
7034
            /* k' = 1/k.b
7035
                  = 1/k' */
7036
            err = mp_invmod(kp, curve->order, kp);
7037
            if (err != MP_OKAY) break;
7038
7039
            /* s = x.r */
7040
            err = mp_mulmod(x, r, curve->order, s);
7041
            if (err != MP_OKAY) break;
7042
7043
            /* s = x.r/k.b
7044
                 = k'.s */
7045
            err = mp_mulmod(kp, s, curve->order, s);
7046
            if (err != MP_OKAY) break;
7047
7048
            /* e' = e/k.b
7049
                  = e.k' */
7050
            err = mp_mulmod(kp, e, curve->order, ep);
7051
            if (err != MP_OKAY) break;
7052
7053
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7054
                 = e' + s */
7055
            err = mp_addmod_ct(ep, s, curve->order, s);
7056
            if (err != MP_OKAY) break;
7057
7058
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7059
                 = b.s */
7060
            err = mp_mulmod(s, b, curve->order, s);
7061
            if (err != MP_OKAY) break;
7062
7063
            if (mp_iszero(s) == MP_NO) {
7064
                /* sign successful */
7065
                break;
7066
            }
7067
         }
7068
     #ifndef ALT_ECC_SIZE
7069
         mp_clear(pubkey->pubkey.x);
7070
         mp_clear(pubkey->pubkey.y);
7071
         mp_clear(pubkey->pubkey.z);
7072
     #endif
7073
         mp_forcezero(pubkey->k);
7074
    }
7075
    mp_forcezero(b);
7076
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7077
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7078
    mp_memzero_check(b);
7079
#endif
7080
7081
    return err;
7082
}
7083
#endif
7084
7085
#ifdef WOLFSSL_HAVE_SP_ECC
7086
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7087
    ecc_key* key, mp_int *r, mp_int *s)
7088
1.68k
{
7089
1.68k
    if (key->idx != ECC_CUSTOM_IDX) {
7090
1.68k
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7091
1.68k
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7092
1.68k
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7093
1.68k
        mp_int* sign_k = key->sign_k;
7094
    #else
7095
        mp_int* sign_k = NULL;
7096
    #endif
7097
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7098
        /* perform blocking call to non-blocking function */
7099
        ecc_nb_ctx_t nb_ctx;
7100
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7101
    #endif
7102
1.68k
    #ifndef WOLFSSL_SP_NO_256
7103
1.68k
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7104
        #ifdef WC_ECC_NONBLOCK
7105
            #ifdef WC_ECC_NONBLOCK_ONLY
7106
            int err;
7107
            #endif
7108
            if (key->nb_ctx) {
7109
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7110
                    ecc_get_k(key), r, s, sign_k, key->heap);
7111
            }
7112
            #ifdef WC_ECC_NONBLOCK_ONLY
7113
            do { /* perform blocking call to non-blocking function */
7114
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7115
                    ecc_get_k(key), r, s, sign_k, key->heap);
7116
            } while (err == FP_WOULDBLOCK);
7117
            return err;
7118
            #endif
7119
        #endif /* WC_ECC_NONBLOCK */
7120
373
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7121
373
            {
7122
373
                int ret;
7123
373
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7124
373
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7125
373
                                      sign_k, key->heap);
7126
373
                RESTORE_VECTOR_REGISTERS();
7127
373
                return ret;
7128
373
            }
7129
373
        #endif
7130
373
        }
7131
1.31k
    #endif
7132
1.31k
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7133
1.31k
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7134
309
            int ret;
7135
309
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
7136
309
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7137
309
                                      sign_k, key->heap);
7138
309
            RESTORE_VECTOR_REGISTERS();
7139
309
            return ret;
7140
309
        }
7141
1.00k
    #endif
7142
1.00k
    #ifdef WOLFSSL_SP_384
7143
1.00k
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7144
        #ifdef WC_ECC_NONBLOCK
7145
            #ifdef WC_ECC_NONBLOCK_ONLY
7146
            int err;
7147
            #endif
7148
            if (key->nb_ctx) {
7149
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7150
                    ecc_get_k(key), r, s, sign_k, key->heap);
7151
            }
7152
            #ifdef WC_ECC_NONBLOCK_ONLY
7153
            do { /* perform blocking call to non-blocking function */
7154
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7155
                    ecc_get_k(key), r, s, sign_k, key->heap);
7156
            } while (err == FP_WOULDBLOCK);
7157
            return err;
7158
            #endif
7159
        #endif /* WC_ECC_NONBLOCK */
7160
346
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7161
346
            {
7162
346
                int ret;
7163
346
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7164
346
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7165
346
                                      sign_k, key->heap);
7166
346
                RESTORE_VECTOR_REGISTERS();
7167
346
                return ret;
7168
346
            }
7169
346
        #endif
7170
346
        }
7171
657
    #endif
7172
657
    #ifdef WOLFSSL_SP_521
7173
657
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7174
        #ifdef WC_ECC_NONBLOCK
7175
            #ifdef WC_ECC_NONBLOCK_ONLY
7176
            int err;
7177
            #endif
7178
            if (key->nb_ctx) {
7179
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7180
                    ecc_get_k(key), r, s, sign_k, key->heap);
7181
            }
7182
            #ifdef WC_ECC_NONBLOCK_ONLY
7183
            do { /* perform blocking call to non-blocking function */
7184
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7185
                    ecc_get_k(key), r, s, sign_k, key->heap);
7186
            } while (err == FP_WOULDBLOCK);
7187
            return err;
7188
            #endif
7189
        #endif /* WC_ECC_NONBLOCK */
7190
657
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7191
657
            {
7192
657
                int ret;
7193
657
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7194
657
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7195
657
                                      sign_k, key->heap);
7196
657
                RESTORE_VECTOR_REGISTERS();
7197
657
                return ret;
7198
657
            }
7199
657
        #endif
7200
657
        }
7201
0
    #endif
7202
0
        (void)sign_k;
7203
0
    }
7204
7205
    /* SP doesn't support curve. */
7206
0
    return WC_KEY_SIZE_E;
7207
1.68k
}
7208
#endif
7209
7210
/**
7211
  Sign a message digest
7212
  in        The message digest to sign
7213
  inlen     The length of the digest
7214
  key       A private ECC key
7215
  r         [out] The destination for r component of the signature
7216
  s         [out] The destination for s component of the signature
7217
  return    MP_OKAY if successful
7218
*/
7219
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7220
                     ecc_key* key, mp_int *r, mp_int *s)
7221
1.68k
{
7222
1.68k
   int    err = 0;
7223
#if !defined(WOLFSSL_SP_MATH)
7224
   mp_int* e;
7225
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7226
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7227
#endif
7228
7229
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7230
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7231
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7232
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7233
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7234
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7235
#else
7236
   DECLARE_CURVE_SPECS(1);
7237
#endif
7238
#endif /* !WOLFSSL_SP_MATH */
7239
7240
1.68k
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7241
0
       return ECC_BAD_ARG_E;
7242
0
   }
7243
7244
   /* is this a private key? */
7245
1.68k
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7246
0
      return ECC_BAD_ARG_E;
7247
0
   }
7248
7249
   /* is the IDX valid ?  */
7250
1.68k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7251
0
      return ECC_BAD_ARG_E;
7252
0
   }
7253
7254
1.68k
#if defined(WOLFSSL_SP_MATH)
7255
1.68k
    if (key->idx == ECC_CUSTOM_IDX || (1
7256
1.68k
    #ifndef WOLFSSL_SP_NO_256
7257
1.68k
         && ecc_sets[key->idx].id != ECC_SECP256R1
7258
1.31k
    #endif
7259
1.31k
    #ifdef WOLFSSL_SP_SM2
7260
1.31k
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7261
1.00k
    #endif
7262
1.00k
    #ifdef WOLFSSL_SP_384
7263
1.00k
         && ecc_sets[key->idx].id != ECC_SECP384R1
7264
657
    #endif
7265
657
    #ifdef WOLFSSL_SP_521
7266
657
         && ecc_sets[key->idx].id != ECC_SECP521R1
7267
1.68k
    #endif
7268
1.68k
        )) {
7269
0
        return WC_KEY_SIZE_E;
7270
0
    }
7271
1.68k
#endif
7272
7273
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7274
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7275
    /* generate deterministic 'k' value to be used either with SP or normal */
7276
    if (key->deterministic == 1) {
7277
        if (deterministic_sign_helper(in, inlen, key)) {
7278
            WOLFSSL_MSG("Error generating deterministic k to sign");
7279
            return ECC_PRIV_KEY_E;
7280
        }
7281
    }
7282
#endif
7283
7284
7285
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7286
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7287
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7288
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7289
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7290
            sw->eccSign.in = in;
7291
            sw->eccSign.inSz = inlen;
7292
            sw->eccSign.rng = rng;
7293
            sw->eccSign.key = key;
7294
            sw->eccSign.r = r;
7295
            sw->eccSign.s = s;
7296
            return WC_PENDING_E;
7297
        }
7298
    }
7299
#endif
7300
7301
1.68k
#if defined(WOLFSSL_HAVE_SP_ECC)
7302
1.68k
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7303
1.68k
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7304
1.68k
       return err;
7305
1.68k
   }
7306
#else
7307
   (void)inlen;
7308
#endif
7309
7310
#if !defined(WOLFSSL_SP_MATH)
7311
7312
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7313
   err = wc_ecc_alloc_mpint(key, &key->e);
7314
   if (err != 0) {
7315
      return err;
7316
   }
7317
   e = key->e;
7318
#else
7319
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7320
#ifdef MP_INT_SIZE_CHECK_NULL
7321
   if (e_lcl == NULL) {
7322
      return MEMORY_E;
7323
   }
7324
#endif
7325
   e = e_lcl;
7326
#endif
7327
7328
   /* get the hash and load it as a bignum into 'e' */
7329
   /* init the bignums */
7330
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7331
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7332
      return err;
7333
   }
7334
7335
   /* load curve info */
7336
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7337
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7338
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7339
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7340
    if (err == MP_OKAY)
7341
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7342
#else
7343
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7344
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7345
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7346
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7347
        if (err == MP_OKAY)
7348
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7349
    }
7350
    else
7351
    #endif
7352
    {
7353
        ALLOC_CURVE_SPECS(1, err);
7354
        if (err == MP_OKAY)
7355
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7356
    }
7357
#endif
7358
7359
   /* load digest into e */
7360
   if (err == MP_OKAY) {
7361
       /* we may need to truncate if hash is longer than key size */
7362
       word32 orderBits = (word32)mp_count_bits(curve->order);
7363
7364
       /* truncate down to byte size, may be all that's needed */
7365
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7366
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7367
       err = mp_read_unsigned_bin(e, in, inlen);
7368
7369
       /* may still need bit truncation too */
7370
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7371
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7372
   }
7373
7374
   /* make up a key and export the public copy */
7375
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7376
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7377
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7378
   #ifdef HAVE_CAVIUM_V
7379
       if (NitroxEccIsCurveSupported(key))
7380
   #endif
7381
       {
7382
           word32 keySz = key->dp->size;
7383
           mp_int* k;
7384
       #ifdef HAVE_CAVIUM_V
7385
           err = wc_ecc_alloc_mpint(key, &key->signK);
7386
           if (err != 0)
7387
              return err;
7388
           k = key->signK;
7389
       #else
7390
           mp_int k_lcl;
7391
           k = &k_lcl;
7392
       #endif
7393
7394
           err = mp_init(k);
7395
7396
            /* make sure r and s are allocated */
7397
       #ifdef HAVE_CAVIUM_V
7398
           /* Nitrox V needs single buffer for R and S */
7399
           if (err == MP_OKAY)
7400
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7401
           /* Nitrox V only needs Prime and Order */
7402
           if (err == MP_OKAY)
7403
               err = wc_ecc_curve_load(key->dp, &curve,
7404
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7405
       #else
7406
           if (err == MP_OKAY)
7407
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7408
           if (err == MP_OKAY)
7409
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7410
       #endif
7411
           if (err == MP_OKAY)
7412
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7413
7414
           /* load e and k */
7415
           if (err == MP_OKAY)
7416
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7417
           if (err == MP_OKAY)
7418
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7419
                  keySz);
7420
           if (err == MP_OKAY)
7421
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7422
           if (err == MP_OKAY)
7423
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7424
7425
       #ifdef HAVE_CAVIUM_V
7426
           if (err == MP_OKAY)
7427
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7428
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7429
                  &curve->order->raw);
7430
       #else
7431
           if (err == MP_OKAY)
7432
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7433
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7434
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7435
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7436
       #endif
7437
7438
       #ifndef HAVE_CAVIUM_V
7439
           mp_clear(e);
7440
           mp_clear(k);
7441
       #endif
7442
           wc_ecc_curve_free(curve);
7443
           FREE_CURVE_SPECS();
7444
7445
           return err;
7446
       }
7447
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7448
   }
7449
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7450
7451
   if (err == MP_OKAY) {
7452
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7453
7454
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7455
           err=MEMORY_E);
7456
       if (WC_VAR_OK(pubkey))
7457
       {
7458
       /* don't use async for key, since we don't support async return here */
7459
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7460
           if (err == MP_OKAY) {
7461
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7462
              wc_ecc_free(pubkey);
7463
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7464
           }
7465
       }
7466
   }
7467
7468
   mp_clear(e);
7469
   wc_ecc_curve_free(curve);
7470
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7471
   FREE_CURVE_SPECS();
7472
#endif /* !WOLFSSL_SP_MATH */
7473
7474
0
   return err;
7475
1.68k
}
7476
7477
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7478
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7479
/* helper function to do HMAC operations
7480
 * returns 0 on success and updates "out" buffer
7481
 */
7482
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7483
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7484
        byte* out, enum wc_HashType hashType, void* heap)
7485
{
7486
    Hmac hmac;
7487
    int  ret, init;
7488
7489
    ret = init = wc_HmacInit(&hmac, heap, INVALID_DEVID);
7490
    if (ret == 0)
7491
        ret = wc_HmacSetKey(&hmac, (int)hashType, K, KSz);
7492
7493
    if (ret == 0)
7494
        ret = wc_HmacUpdate(&hmac, V, VSz);
7495
7496
    if (ret == 0 && oct != NULL)
7497
        ret = wc_HmacUpdate(&hmac, oct, 1);
7498
7499
    if (ret == 0)
7500
        ret = wc_HmacUpdate(&hmac, x, xSz);
7501
7502
    if (ret == 0)
7503
        ret = wc_HmacUpdate(&hmac, h1, h1Sz);
7504
7505
    if (ret == 0)
7506
        ret = wc_HmacFinal(&hmac, out);
7507
7508
    if (init == 0)
7509
        wc_HmacFree(&hmac);
7510
7511
    return ret;
7512
}
7513
7514
7515
/* Generates a deterministic key based of the message using RFC6979
7516
 * @param  [in]   hash     Hash value to sign
7517
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7518
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7519
 *                WC_HASH_TYPE_SHA256
7520
 * @param  [in]   priv     Current ECC private key set
7521
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7522
 * @param  [in]   order    ECC order parameter to use with generation
7523
 * @return  0 on success.
7524
 */
7525
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7526
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7527
        void* heap)
7528
{
7529
    int ret = 0;
7530
#ifndef WOLFSSL_SMALL_STACK
7531
    byte h1[MAX_ECC_BYTES];
7532
    byte V[WC_MAX_DIGEST_SIZE];
7533
    byte K[WC_MAX_DIGEST_SIZE];
7534
    byte x[MAX_ECC_BYTES];
7535
    mp_int z1[1];
7536
#else
7537
    byte *h1 = NULL;
7538
    byte *V  = NULL;
7539
    byte *K  = NULL;
7540
    byte *x  = NULL;
7541
    mp_int *z1 = NULL;
7542
#endif
7543
    word32 xSz, VSz, KSz, h1len, qLen;
7544
    byte intOct;
7545
    int qbits = 0;
7546
7547
    if (hash == NULL || k == NULL || order == NULL) {
7548
        return BAD_FUNC_ARG;
7549
    }
7550
7551
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7552
        WOLFSSL_MSG("hash size was too large!");
7553
        return BAD_FUNC_ARG;
7554
    }
7555
7556
    /* if none is provided then detect has type based on hash size */
7557
    if (hashType == WC_HASH_TYPE_NONE) {
7558
        if (hashSz == 64) {
7559
            hashType = WC_HASH_TYPE_SHA512;
7560
        }
7561
        else if (hashSz == 48) {
7562
            hashType = WC_HASH_TYPE_SHA384;
7563
        }
7564
        else if (hashSz == 32) {
7565
            hashType = WC_HASH_TYPE_SHA256;
7566
        }
7567
        else {
7568
            return BAD_FUNC_ARG;
7569
        }
7570
    }
7571
7572
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
7573
        WOLFSSL_MSG("private key larger than max expected!");
7574
        return BAD_FUNC_ARG;
7575
    }
7576
7577
#ifdef WOLFSSL_SMALL_STACK
7578
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
7579
    if (h1 == NULL) {
7580
        ret = MEMORY_E;
7581
    }
7582
7583
    if (ret == 0) {
7584
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7585
        if (V == NULL)
7586
            ret = MEMORY_E;
7587
    }
7588
7589
    if (ret == 0) {
7590
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7591
        if (K == NULL)
7592
            ret = MEMORY_E;
7593
    }
7594
7595
    if (ret == 0) {
7596
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7597
        if (x == NULL)
7598
            ret = MEMORY_E;
7599
    }
7600
7601
    if (ret == 0) {
7602
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
7603
        if (z1 == NULL)
7604
            ret = MEMORY_E;
7605
    }
7606
7607
    /* bail out if any error has been hit at this point */
7608
    if (ret != 0) {
7609
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7610
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7611
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7612
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7613
        return ret;
7614
    }
7615
#endif
7616
7617
    VSz = KSz = hashSz;
7618
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
7619
7620
    /* 3.2 b. Set V = 0x01 0x01 ... */
7621
    XMEMSET(V, 0x01, VSz);
7622
7623
    /* 3.2 c. Set K = 0x00 0x00 ... */
7624
    XMEMSET(K, 0x00, KSz);
7625
7626
    if (ret == 0) {
7627
        ret = mp_init(z1); /* always init z1 and free z1 */
7628
    }
7629
    if (ret == 0) {
7630
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
7631
    }
7632
    if (ret == 0) {
7633
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7634
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
7635
    #endif
7636
        qbits = mp_count_bits(order);
7637
        if (qbits < 0)
7638
            ret = MP_VAL;
7639
    }
7640
7641
    if (ret == 0) {
7642
         /* hash truncate if too long */
7643
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
7644
            /* calculate truncated hash size using bits rounded up byte */
7645
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
7646
        }
7647
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
7648
    }
7649
7650
    /* bits2octets on h1 */
7651
    if (ret == 0) {
7652
        XMEMSET(h1, 0, MAX_ECC_BYTES);
7653
7654
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7655
        /* mod reduce by order using conditional subtract
7656
         * RFC6979 lists a variant that uses the hash directly instead of
7657
         * doing bits2octets(H(m)), when variant macro is used avoid this
7658
         * bits2octets operation */
7659
        if (mp_cmp(z1, order) == MP_GT) {
7660
            int z1Sz;
7661
7662
            mp_sub(z1, order, z1);
7663
            z1Sz = mp_unsigned_bin_size(z1);
7664
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
7665
                ret = BUFFER_E;
7666
            }
7667
            else {
7668
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7669
            }
7670
        }
7671
        else
7672
    #endif
7673
        {
7674
            /* use original hash and keep leading 0's */
7675
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7676
        }
7677
    }
7678
    mp_free(z1);
7679
7680
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
7681
    if (ret == 0) {
7682
        intOct = 0x00;
7683
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
7684
                hashType, heap);
7685
    }
7686
7687
    /* 3.2 step e. V = HMAC_K(V) */
7688
    if (ret == 0) {
7689
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7690
                heap);
7691
    }
7692
7693
7694
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
7695
    if (ret == 0) {
7696
        intOct = 0x01;
7697
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
7698
                heap);
7699
    }
7700
7701
    /* 3.2 step g. V = HMAC_K(V) */
7702
    if (ret == 0) {
7703
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7704
                heap);
7705
    }
7706
7707
    /* 3.2 step h. loop through the next steps until a valid value is found */
7708
    if (ret == 0 ) {
7709
        int err;
7710
7711
        intOct = 0x00;
7712
        do {
7713
            xSz = 0; /* used as tLen */
7714
            err = 0; /* start as good until generated k is tested */
7715
7716
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
7717
            while (xSz < qLen) {
7718
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7719
                        hashType, heap);
7720
                if (ret == 0) {
7721
                    int sz;
7722
7723
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
7724
                    XMEMCPY(x + xSz, V, (size_t)sz);
7725
                    xSz += (word32)sz;
7726
                }
7727
                else {
7728
                    break; /* error case */
7729
                }
7730
            }
7731
7732
            if (ret == 0) {
7733
                mp_clear(k); /* 3.2 step h.1 clear T */
7734
                ret = mp_read_unsigned_bin(k, x, xSz);
7735
            }
7736
7737
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
7738
                /* handle odd case where shift of 'k' is needed with RFC 6979
7739
                 *  k = bits2int(T) in section 3.2 h.3 */
7740
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
7741
            }
7742
7743
            /* 3.2 step h.3 the key should be smaller than the order of base
7744
             * point */
7745
            if (ret == 0) {
7746
                if (mp_cmp(k, order) != MP_LT) {
7747
                    err = MP_VAL;
7748
                } else if (mp_iszero(k) == MP_YES) {
7749
                    /* no 0 key's */
7750
                    err = MP_ZERO_E;
7751
                }
7752
            }
7753
7754
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
7755
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
7756
            if (ret == 0 && err != 0) {
7757
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
7758
                    hashType, heap);
7759
                if (ret == 0) {
7760
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7761
                    hashType, heap);
7762
                }
7763
            }
7764
        } while (ret == 0 && err != 0);
7765
    }
7766
7767
    ForceZero(x, MAX_ECC_BYTES);
7768
#ifdef WOLFSSL_SMALL_STACK
7769
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
7770
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7771
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7772
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7773
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7774
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
7775
    wc_MemZero_Check(x, MAX_ECC_BYTES);
7776
#endif
7777
7778
    return ret;
7779
}
7780
7781
7782
/* Sets the deterministic flag for 'k' generation with sign.
7783
 * returns 0 on success
7784
 */
7785
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
7786
                                enum wc_HashType hashType)
7787
{
7788
    if (key == NULL) {
7789
        return BAD_FUNC_ARG;
7790
    }
7791
7792
    key->deterministic = flag ? 1 : 0;
7793
    key->hashType = hashType;
7794
    return 0;
7795
}
7796
7797
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
7798
{
7799
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
7800
}
7801
7802
#endif /* end sign_ex and deterministic sign */
7803
7804
7805
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
7806
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
7807
730
{
7808
730
    int ret = MP_OKAY;
7809
730
    DECLARE_CURVE_SPECS(1);
7810
7811
730
    if (k == NULL || klen == 0 || key == NULL) {
7812
23
        return BAD_FUNC_ARG;
7813
23
    }
7814
7815
707
    ALLOC_CURVE_SPECS(1, ret);
7816
707
    if (ret == MP_OKAY) {
7817
697
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7818
697
    }
7819
7820
707
    if (ret != 0) {
7821
13
        FREE_CURVE_SPECS();
7822
13
        return ret;
7823
13
    }
7824
7825
694
#ifndef WOLFSSL_NO_MALLOC
7826
694
    if (key->sign_k == NULL) {
7827
694
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7828
694
                                                            DYNAMIC_TYPE_ECC);
7829
694
        if (key->sign_k) {
7830
684
            ret = mp_init(key->sign_k);
7831
684
        }
7832
10
        else {
7833
10
            ret = MEMORY_E;
7834
10
        }
7835
694
    }
7836
694
#endif
7837
7838
694
    if (ret == 0) {
7839
684
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7840
684
    }
7841
694
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7842
45
        ret = MP_VAL;
7843
45
    }
7844
#ifdef WOLFSSL_NO_MALLOC
7845
    if (ret == 0) {
7846
        key->sign_k_set = 1;
7847
    }
7848
#endif
7849
7850
694
    wc_ecc_curve_free(curve);
7851
694
    FREE_CURVE_SPECS();
7852
694
    return ret;
7853
707
}
7854
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
7855
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
7856
7857
#endif /* !HAVE_ECC_SIGN */
7858
7859
#ifdef WOLFSSL_CUSTOM_CURVES
7860
void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
7861
{
7862
#ifndef WOLFSSL_ECC_CURVE_STATIC
7863
    if (curve->prime != NULL)
7864
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7865
    if (curve->Af != NULL)
7866
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7867
    if (curve->Bf != NULL)
7868
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7869
    if (curve->order != NULL)
7870
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7871
    if (curve->Gx != NULL)
7872
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7873
    if (curve->Gy != NULL)
7874
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7875
#endif
7876
7877
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7878
7879
    (void)heap;
7880
}
7881
#endif /* WOLFSSL_CUSTOM_CURVES */
7882
7883
/**
7884
  Free an ECC key from memory
7885
  key   The key you wish to free
7886
*/
7887
WOLFSSL_ABI
7888
int wc_ecc_free(ecc_key* key)
7889
9.40k
{
7890
9.40k
    if (key == NULL) {
7891
3
        return 0;
7892
3
    }
7893
7894
9.40k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7895
9.40k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7896
9.40k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7897
9.40k
#ifndef WOLFSSL_NO_MALLOC
7898
9.40k
    if (key->sign_k != NULL)
7899
388
#endif
7900
388
    {
7901
388
        mp_forcezero(key->sign_k);
7902
388
        mp_free(key->sign_k);
7903
388
#ifndef WOLFSSL_NO_MALLOC
7904
388
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7905
388
#endif
7906
388
    }
7907
9.40k
#endif
7908
7909
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7910
    #ifdef WC_ASYNC_ENABLE_ECC
7911
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
7912
    #endif
7913
    wc_ecc_free_async(key);
7914
#endif
7915
7916
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
7917
    /* free secure memory */
7918
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
7919
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
7920
       caamFreePart(key->partNum);
7921
    }
7922
#endif
7923
7924
#ifdef WOLFSSL_SE050
7925
#ifdef WOLFSSL_SE050_AUTO_ERASE
7926
    wc_se050_erase_object(key->keyId);
7927
#endif
7928
    se050_ecc_free_key(key);
7929
#endif
7930
7931
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7932
    atmel_ecc_free(key->slot);
7933
    key->slot = ATECC_INVALID_SLOT;
7934
#endif /* WOLFSSL_ATECC508A */
7935
7936
#ifdef WOLFSSL_KCAPI_ECC
7937
    KcapiEcc_Free(key);
7938
#endif
7939
7940
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7941
    key->privKey = NULL;
7942
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
7943
    ForceZero(&key->xSec, sizeof(key->xSec));
7944
#endif
7945
7946
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
7947
    wc_MAXQ10XX_EccFree(key);
7948
#endif
7949
7950
9.40k
    mp_clear(key->pubkey.x);
7951
9.40k
    mp_clear(key->pubkey.y);
7952
9.40k
    mp_clear(key->pubkey.z);
7953
7954
#ifdef ALT_ECC_SIZE
7955
    if (key->k)
7956
#endif
7957
9.40k
        mp_forcezero(key->k);
7958
#ifdef WOLFSSL_ECC_BLIND_K
7959
#ifdef ALT_ECC_SIZE
7960
    if (key->kb)
7961
#endif
7962
        mp_forcezero(key->kb);
7963
#ifdef ALT_ECC_SIZE
7964
    if (key->ku)
7965
#endif
7966
        mp_forcezero(key->ku);
7967
#endif
7968
7969
#ifdef WOLFSSL_CUSTOM_CURVES
7970
    if (key->deallocSet && key->dp != NULL)
7971
        wc_ecc_free_curve(key->dp, key->heap);
7972
#endif
7973
7974
#ifdef WOLFSSL_CHECK_MEM_ZERO
7975
    wc_MemZero_Check(key, sizeof(ecc_key));
7976
#endif
7977
7978
9.40k
    return 0;
7979
9.40k
}
7980
7981
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7982
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
7983
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
7984
      defined(WOLFSSL_IMXRT1170_CAAM))
7985
7986
/* Handles add failure cases:
7987
 *
7988
 * Before add:
7989
 *   Case 1: A is infinity
7990
 *        -> Copy B into result.
7991
 *   Case 2: B is infinity
7992
 *        -> Copy A into result.
7993
 *   Case 3: x and z are the same in A and B (same x value in affine)
7994
 *     Case 3a: y values the same - same point
7995
 *           -> Double instead of add.
7996
 *     Case 3b: y values different - negative of the other when points on curve
7997
 *           -> Need to set result to infinity.
7998
 *
7999
 * After add:
8000
 *   Case 1: A and B are the same point (maybe different z)
8001
 *           (Result was: x == y == z == 0)
8002
 *        -> Need to double instead.
8003
 *
8004
 *   Case 2: A + B = <infinity> = 0.
8005
 *           (Result was: z == 0, x and/or y not 0)
8006
 *        -> Need to set result to infinity.
8007
 */
8008
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8009
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8010
{
8011
    int err;
8012
8013
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8014
        /* A is infinity. */
8015
        err = wc_ecc_copy_point(B, R);
8016
    }
8017
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8018
        /* B is infinity. */
8019
        err = wc_ecc_copy_point(A, R);
8020
    }
8021
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8022
        /* x ordinattes the same. */
8023
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8024
            /* A = B */
8025
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8026
        }
8027
        else {
8028
            /* A = -B */
8029
            err = mp_set(R->x, 0);
8030
            if (err == MP_OKAY)
8031
                err = mp_set(R->y, 0);
8032
            if (err == MP_OKAY)
8033
                err = mp_set(R->z, 1);
8034
            if ((err == MP_OKAY) && (infinity != NULL))
8035
                *infinity = 1;
8036
        }
8037
    }
8038
    else {
8039
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8040
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8041
            /* When all zero then should have done a double */
8042
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8043
                if (mp_iszero(B->z)) {
8044
                    err = wc_ecc_copy_point(B, R);
8045
                    if (err == MP_OKAY) {
8046
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8047
                    }
8048
                    if (err == MP_OKAY) {
8049
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8050
                    }
8051
                }
8052
                else {
8053
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8054
                }
8055
            }
8056
            /* When only Z zero then result is infinity */
8057
            else {
8058
                err = mp_set(R->x, 0);
8059
                if (err == MP_OKAY)
8060
                    err = mp_set(R->y, 0);
8061
                if (err == MP_OKAY)
8062
                    err = mp_set(R->z, 1);
8063
                if ((err == MP_OKAY) && (infinity != NULL))
8064
                    *infinity = 1;
8065
            }
8066
        }
8067
    }
8068
8069
    return err;
8070
}
8071
8072
/* Handles when P is the infinity point.
8073
 *
8074
 * Double infinity -> infinity.
8075
 * Otherwise do normal double - which can't lead to infinity as odd order.
8076
 */
8077
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8078
                                  mp_int* modulus, mp_digit mp)
8079
{
8080
    int err;
8081
8082
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8083
        /* P is infinity. */
8084
        err = wc_ecc_copy_point(P, R);
8085
    }
8086
    else {
8087
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8088
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8089
           err = mp_set(R->x, 0);
8090
           if (err == MP_OKAY)
8091
               err = mp_set(R->y, 0);
8092
           if (err == MP_OKAY)
8093
               err = mp_set(R->z, 1);
8094
        }
8095
    }
8096
8097
    return err;
8098
}
8099
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8100
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8101
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8102
            (WOLFSSL_IMXRT1170_CAAM))
8103
        */
8104
8105
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8106
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \
8107
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8108
#ifdef ECC_SHAMIR
8109
8110
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8111
    ecc_point* Bm, mp_int* modulus, void* heap)
8112
{
8113
    int err = MP_OKAY;
8114
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8115
8116
    (void)heap;
8117
8118
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8119
#ifdef MP_INT_SIZE_CHECK_NULL
8120
    if (mu == NULL)
8121
       err = MEMORY_E;
8122
#endif
8123
    if (err == MP_OKAY) {
8124
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8125
    }
8126
    if (err == MP_OKAY) {
8127
        err = mp_montgomery_calc_normalization(mu, modulus);
8128
8129
        if (err == MP_OKAY) {
8130
            /* copy ones ... */
8131
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8132
        }
8133
8134
        if (err == MP_OKAY)
8135
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8136
        if (err == MP_OKAY)
8137
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8138
8139
        if (err == MP_OKAY)
8140
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8141
        if (err == MP_OKAY)
8142
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8143
        if (err == MP_OKAY)
8144
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8145
8146
        /* done with mu */
8147
        mp_clear(mu);
8148
    }
8149
8150
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8151
8152
    return err;
8153
}
8154
8155
/** Computes kA*A + kB*B = C using Shamir's Trick
8156
  A        First point to multiply
8157
  kA       What to multiple A by
8158
  B        Second point to multiply
8159
  kB       What to multiple B by
8160
  C        [out] Destination point (can overlap with A or B)
8161
  a        ECC curve parameter a
8162
  modulus  Modulus for curve
8163
  return MP_OKAY on success
8164
*/
8165
#ifdef FP_ECC
8166
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8167
                             ecc_point* B, mp_int* kB,
8168
                             ecc_point* C, mp_int* a, mp_int* modulus,
8169
                             void* heap)
8170
#else
8171
int ecc_mul2add(ecc_point* A, mp_int* kA,
8172
                    ecc_point* B, mp_int* kB,
8173
                    ecc_point* C, mp_int* a, mp_int* modulus,
8174
                    void* heap)
8175
#endif
8176
{
8177
#ifdef WOLFSSL_SMALL_STACK_CACHE
8178
  ecc_key        *key = NULL;
8179
#endif
8180
#ifdef WOLFSSL_SMALL_STACK
8181
  ecc_point**    precomp = NULL;
8182
#else
8183
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8184
  #ifdef WOLFSSL_NO_MALLOC
8185
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8186
  #endif
8187
#endif
8188
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8189
#ifdef WOLFSSL_NO_MALLOC
8190
  unsigned char tA[ECC_BUFSIZE];
8191
  unsigned char tB[ECC_BUFSIZE];
8192
#else
8193
  unsigned char* tA = NULL;
8194
  unsigned char* tB = NULL;
8195
#endif
8196
  int            err = MP_OKAY, first, x, y;
8197
  mp_digit       mp = 0;
8198
8199
  /* argchks */
8200
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8201
                                                         modulus == NULL) {
8202
     return ECC_BAD_ARG_E;
8203
  }
8204
8205
#ifndef WOLFSSL_NO_MALLOC
8206
  /* allocate memory */
8207
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8208
  if (tA == NULL) {
8209
     return MP_MEM;
8210
  }
8211
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8212
  if (tB == NULL) {
8213
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8214
     return MP_MEM;
8215
  }
8216
#endif
8217
8218
#ifdef WOLFSSL_SMALL_STACK_CACHE
8219
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8220
  if (key == NULL) {
8221
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8222
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8223
     return MP_MEM;
8224
  }
8225
#endif
8226
#ifdef WOLFSSL_SMALL_STACK
8227
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8228
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8229
  if (precomp == NULL) {
8230
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8231
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8232
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8233
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8234
  #endif
8235
     return MP_MEM;
8236
  }
8237
#endif
8238
#ifdef WOLFSSL_SMALL_STACK_CACHE
8239
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8240
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8241
#ifdef ALT_ECC_SIZE
8242
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8243
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8244
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8245
#endif
8246
8247
  if (key->t1 == NULL || key->t2 == NULL
8248
#ifdef ALT_ECC_SIZE
8249
     || key->x == NULL || key->y == NULL || key->z == NULL
8250
#endif
8251
  ) {
8252
#ifdef ALT_ECC_SIZE
8253
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8254
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8255
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8256
#endif
8257
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8258
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8259
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8260
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8261
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8262
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8263
      return MEMORY_E;
8264
  }
8265
  C->key = key;
8266
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8267
8268
  /* init variables */
8269
  XMEMSET(tA, 0, ECC_BUFSIZE);
8270
  XMEMSET(tB, 0, ECC_BUFSIZE);
8271
#ifndef WOLFSSL_SMALL_STACK
8272
  XMEMSET(precomp, 0, sizeof(precomp));
8273
#else
8274
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8275
#endif
8276
#ifdef WOLFSSL_CHECK_MEM_ZERO
8277
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8278
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8279
#endif
8280
8281
  /* get sizes */
8282
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8283
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8284
  len  = MAX(lenA, lenB);
8285
8286
  /* sanity check */
8287
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8288
    err = BAD_FUNC_ARG;
8289
  }
8290
8291
  if (err == MP_OKAY) {
8292
    /* extract and justify kA */
8293
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8294
8295
    /* extract and justify kB */
8296
    if (err == MP_OKAY)
8297
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8298
8299
    /* allocate the table */
8300
    if (err == MP_OKAY) {
8301
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8302
        #ifdef WOLFSSL_NO_MALLOC
8303
            precomp[x] = &lcl_precomp[x];
8304
        #endif
8305
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8306
            if (err != MP_OKAY)
8307
                break;
8308
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8309
            precomp[x]->key = key;
8310
        #endif
8311
        }
8312
    }
8313
  }
8314
8315
  if (err == MP_OKAY)
8316
    /* init montgomery reduction */
8317
    err = mp_montgomery_setup(modulus, &mp);
8318
8319
  if (err == MP_OKAY) {
8320
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8321
  }
8322
8323
  if (err == MP_OKAY) {
8324
    /* precomp [i,0](A + B) table */
8325
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8326
  }
8327
  if (err == MP_OKAY) {
8328
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8329
                                                          a, modulus, mp, NULL);
8330
  }
8331
8332
  if (err == MP_OKAY) {
8333
    /* precomp [0,i](A + B) table */
8334
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8335
  }
8336
  if (err == MP_OKAY) {
8337
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8338
                                                             modulus, mp, NULL);
8339
  }
8340
8341
  if (err == MP_OKAY) {
8342
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8343
    for (x = 1; x < 4; x++) {
8344
      for (y = 1; y < 4; y++) {
8345
        if (err == MP_OKAY) {
8346
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8347
                                                  precomp[x+(y<<2)], a, modulus,
8348
                                                  mp, NULL);
8349
        }
8350
      }
8351
    }
8352
  }
8353
8354
  if (err == MP_OKAY) {
8355
    nibble  = 3;
8356
    first   = 1;
8357
    bitbufA = tA[0];
8358
    bitbufB = tB[0];
8359
8360
    /* for every byte of the multiplicands */
8361
    for (x = 0; x < (int)len || nibble != 3; ) {
8362
        /* grab a nibble */
8363
        if (++nibble == 4) {
8364
            if (x == (int)len) break;
8365
            bitbufA = tA[x];
8366
            bitbufB = tB[x];
8367
            nibble  = 0;
8368
            x++;
8369
        }
8370
8371
        /* extract two bits from both, shift/update */
8372
        nA = (bitbufA >> 6) & 0x03;
8373
        nB = (bitbufB >> 6) & 0x03;
8374
        bitbufA = (bitbufA << 2) & 0xFF;
8375
        bitbufB = (bitbufB << 2) & 0xFF;
8376
8377
        /* if both zero, if first, continue */
8378
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8379
            continue;
8380
        }
8381
8382
        /* double twice, only if this isn't the first */
8383
        if (first == 0) {
8384
            /* double twice */
8385
            if (err == MP_OKAY)
8386
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8387
            if (err == MP_OKAY)
8388
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8389
            else
8390
                break;
8391
        }
8392
8393
        /* if not both zero */
8394
        if ((nA != 0) || (nB != 0)) {
8395
            unsigned int i = nA + (nB<<2);
8396
            if (first == 1) {
8397
                /* if first, copy from table */
8398
                first = 0;
8399
                if (err == MP_OKAY)
8400
                    err = mp_copy(precomp[i]->x, C->x);
8401
8402
                if (err == MP_OKAY)
8403
                    err = mp_copy(precomp[i]->y, C->y);
8404
8405
                if (err == MP_OKAY)
8406
                    err = mp_copy(precomp[i]->z, C->z);
8407
                else
8408
                    break;
8409
            } else {
8410
                /* if not first, add from table */
8411
                if (err == MP_OKAY)
8412
                    err = ecc_projective_add_point_safe(C, precomp[i],
8413
                                                        C, a, modulus, mp,
8414
                                                        &first);
8415
                if (err != MP_OKAY)
8416
                    break;
8417
            }
8418
        }
8419
    }
8420
  }
8421
8422
  /* reduce to affine */
8423
  if (err == MP_OKAY)
8424
    err = ecc_map(C, modulus, mp);
8425
8426
  /* clean up */
8427
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8428
     wc_ecc_del_point_ex(precomp[x], heap);
8429
  }
8430
8431
  ForceZero(tA, ECC_BUFSIZE);
8432
  ForceZero(tB, ECC_BUFSIZE);
8433
#ifdef WOLFSSL_SMALL_STACK_CACHE
8434
#ifdef ALT_ECC_SIZE
8435
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8436
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8437
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8438
#endif
8439
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8440
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8441
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8442
  C->key = NULL;
8443
#endif
8444
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8445
#ifndef WOLFSSL_NO_MALLOC
8446
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8447
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8448
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8449
  wc_MemZero_Check(tB, ECC_BUFSIZE);
8450
  wc_MemZero_Check(tA, ECC_BUFSIZE);
8451
#endif
8452
  return err;
8453
}
8454
8455
#endif /* ECC_SHAMIR */
8456
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
8457
        * !WOLFSSL_CRYPTOCEL */
8458
8459
8460
#ifdef HAVE_ECC_VERIFY
8461
/* verify
8462
 *
8463
 * w  = s^-1 mod n
8464
 * u1 = xw
8465
 * u2 = rw
8466
 * X = u1*G + u2*Q
8467
 * v = X_x1 mod n
8468
 * accept if v == r
8469
 */
8470
8471
/**
8472
 Verify an ECC signature
8473
 sig         The signature to verify
8474
 siglen      The length of the signature (octets)
8475
 hash        The hash (message digest) that was signed
8476
 hashlen     The length of the hash (octets)
8477
 res         Result of signature, 1==valid, 0==invalid
8478
 key         The corresponding public ECC key
8479
 return      MP_OKAY if successful (even if the signature is not valid)
8480
             Caller should check the *res value to determine if the signature
8481
             is valid or invalid. Other negative values are returned on error.
8482
 */
8483
WOLFSSL_ABI
8484
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
8485
                       word32 hashlen, int* res, ecc_key* key)
8486
6.06k
{
8487
6.06k
    int err;
8488
8489
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8490
    mp_int *r = NULL, *s = NULL;
8491
#else
8492
6.06k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8493
6.06k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8494
6.06k
#endif
8495
#ifdef WOLFSSL_ASYNC_CRYPT
8496
    int isPrivateKeyOnly = 0;
8497
#endif
8498
#ifdef NO_ASN
8499
    word32 keySz;
8500
#endif
8501
8502
6.06k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8503
55
        return ECC_BAD_ARG_E;
8504
55
    }
8505
6.01k
    if (hashlen > WC_MAX_DIGEST_SIZE) {
8506
75
        return BAD_LENGTH_E;
8507
75
    }
8508
8509
5.93k
#ifdef WOLF_CRYPTO_CB
8510
5.93k
    #ifndef WOLF_CRYPTO_CB_FIND
8511
5.93k
    if (key->devId != INVALID_DEVID)
8512
0
    #endif
8513
0
    {
8514
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
8515
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8516
0
            return err;
8517
        /* fall-through when unavailable */
8518
0
    }
8519
5.93k
#endif
8520
8521
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
8522
    (void)siglen;
8523
    (void)hashlen;
8524
    (void)s;
8525
    (void)r;
8526
    (void)err;
8527
    return NO_VALID_DEVID;
8528
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
8529
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8530
    err = wc_ecc_alloc_async(key);
8531
    if (err != 0)
8532
        return err;
8533
    r = key->r;
8534
    s = key->s;
8535
#else
8536
5.93k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8537
5.93k
        DYNAMIC_TYPE_ECC);
8538
5.93k
    #ifdef MP_INT_SIZE_CHECK_NULL
8539
5.93k
    if (r == NULL)
8540
12
        return MEMORY_E;
8541
5.92k
    #endif
8542
5.92k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8543
5.92k
        DYNAMIC_TYPE_ECC);
8544
5.92k
    #ifdef MP_INT_SIZE_CHECK_NULL
8545
5.92k
    if (s == NULL) {
8546
5
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8547
5
        return MEMORY_E;
8548
5
    }
8549
5.91k
    #endif
8550
5.91k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8551
5.91k
    if (err != 0) {
8552
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8553
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8554
0
        return err;
8555
0
    }
8556
5.91k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8557
5.91k
    if (err != 0) {
8558
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8559
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8560
0
        return err;
8561
0
    }
8562
5.91k
#endif /* WOLFSSL_ASYNC_CRYPT */
8563
8564
5.91k
    switch (key->state) {
8565
5.91k
        case ECC_STATE_NONE:
8566
5.91k
        case ECC_STATE_VERIFY_DECODE:
8567
5.91k
            key->state = ECC_STATE_VERIFY_DECODE;
8568
8569
            /* default to invalid signature */
8570
5.91k
            *res = 0;
8571
8572
5.91k
    #ifndef NO_ASN
8573
            /* Decode ASN.1 ECDSA signature. */
8574
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8575
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
8576
             * If either of those don't allocate correctly, none of
8577
             * the rest of this function will execute, and everything
8578
             * gets cleaned up at the end. */
8579
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
8580
        #else
8581
            /* r and s are initialized. */
8582
5.91k
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8583
5.91k
        #endif
8584
5.91k
            if (err < 0) {
8585
64
                break;
8586
64
            }
8587
    #else
8588
            /* No support for DSA ASN.1 header.
8589
             * Signature must be r+s directly. */
8590
            keySz = 0;
8591
            if (key->dp != NULL) {
8592
                keySz = (word32)key->dp->size;
8593
            }
8594
            if (siglen != keySz * 2) {
8595
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
8596
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
8597
            }
8598
8599
            /* Import signature into r,s */
8600
            mp_init(r);
8601
            mp_init(s);
8602
            mp_read_unsigned_bin(r, sig, keySz);
8603
            mp_read_unsigned_bin(s, sig + keySz, keySz);
8604
    #endif /* !NO_ASN */
8605
5.85k
            FALL_THROUGH;
8606
8607
5.85k
        case ECC_STATE_VERIFY_DO:
8608
5.85k
            key->state = ECC_STATE_VERIFY_DO;
8609
        #ifdef WOLFSSL_ASYNC_CRYPT
8610
            if (key->type == ECC_PRIVATEKEY_ONLY) {
8611
                isPrivateKeyOnly = 1;
8612
            }
8613
        #endif
8614
5.85k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8615
8616
5.85k
        #ifndef WOLFSSL_ASYNC_CRYPT
8617
            /* done with R/S */
8618
5.85k
            mp_clear(r);
8619
5.85k
            mp_clear(s);
8620
5.85k
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8621
5.85k
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8622
5.85k
        #ifdef MP_INT_SIZE_CHECK_NULL
8623
5.85k
            r = NULL;
8624
5.85k
            s = NULL;
8625
5.85k
        #endif
8626
5.85k
        #endif
8627
8628
5.85k
            if (err < 0) {
8629
219
                break;
8630
219
            }
8631
5.63k
            FALL_THROUGH;
8632
8633
5.63k
        case ECC_STATE_VERIFY_RES:
8634
5.63k
            key->state = ECC_STATE_VERIFY_RES;
8635
5.63k
            err = 0;
8636
5.63k
            break;
8637
8638
0
        default:
8639
0
            err = BAD_STATE_E;
8640
5.91k
    }
8641
8642
#ifdef WOLFSSL_ASYNC_CRYPT
8643
    /* if async pending then return and skip done cleanup below */
8644
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8645
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
8646
            key->state++;
8647
        return err;
8648
    }
8649
#endif
8650
8651
    /* cleanup */
8652
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8653
    wc_ecc_free_async(key);
8654
#else
8655
5.91k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8656
5.91k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8657
5.91k
#endif
8658
8659
    /* make sure required variables are reset */
8660
5.91k
    wc_ecc_reset(key);
8661
5.91k
    return err;
8662
5.91k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8663
5.91k
}
8664
8665
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
8666
8667
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
8668
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8669
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
8670
3.29k
{
8671
3.29k
    int err = MP_OKAY;
8672
3.29k
    DECLARE_CURVE_SPECS(1);
8673
8674
3.29k
    ALLOC_CURVE_SPECS(1, err);
8675
3.29k
    if (err == MP_OKAY) {
8676
3.29k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8677
3.29k
    }
8678
3.29k
    if (err != 0) {
8679
4
        FREE_CURVE_SPECS();
8680
4
        return err;
8681
4
    }
8682
8683
3.29k
    if (mp_iszero(r) || mp_iszero(s)) {
8684
0
        err = MP_ZERO_E;
8685
0
    }
8686
3.29k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8687
8
        err = MP_VAL;
8688
8
    }
8689
3.29k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8690
11
        err = MP_VAL;
8691
11
    }
8692
8693
3.29k
    wc_ecc_curve_free(curve);
8694
3.29k
    FREE_CURVE_SPECS();
8695
3.29k
    return err;
8696
3.29k
}
8697
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
8698
8699
#ifdef HAVE_ECC_VERIFY_HELPER
8700
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
8701
    word32 hashlen, int* res, ecc_key* key)
8702
3.26k
{
8703
3.26k
    (void)r;
8704
3.26k
    (void)s;
8705
3.26k
    (void)hash;
8706
3.26k
    (void)hashlen;
8707
3.26k
    (void)res;
8708
3.26k
    (void)key;
8709
8710
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
8711
  if (key->handle != -1) {
8712
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
8713
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8714
  }
8715
  if (wolfSSL_GetHandleCbSet() == 1) {
8716
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
8717
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8718
  }
8719
#endif
8720
8721
3.26k
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
8722
3.26k
    if (key->idx == ECC_CUSTOM_IDX || (1
8723
3.26k
    #ifndef WOLFSSL_SP_NO_256
8724
3.26k
         && ecc_sets[key->idx].id != ECC_SECP256R1
8725
2.52k
    #endif
8726
2.52k
    #ifdef WOLFSSL_SP_SM2
8727
2.52k
         && ecc_sets[key->idx].id != ECC_SM2P256V1
8728
1.97k
    #endif
8729
1.97k
    #ifdef WOLFSSL_SP_384
8730
1.97k
         && ecc_sets[key->idx].id != ECC_SECP384R1
8731
1.27k
    #endif
8732
1.27k
    #ifdef WOLFSSL_SP_521
8733
1.27k
         && ecc_sets[key->idx].id != ECC_SECP521R1
8734
3.26k
    #endif
8735
3.26k
        )) {
8736
0
        return WC_KEY_SIZE_E;
8737
0
    }
8738
3.26k
#endif
8739
8740
3.26k
#if defined(WOLFSSL_HAVE_SP_ECC)
8741
3.26k
    if (key->idx != ECC_CUSTOM_IDX) {
8742
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
8743
        /* perform blocking call to non-blocking function */
8744
        ecc_nb_ctx_t nb_ctx;
8745
        int err;
8746
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
8747
        err = NOT_COMPILED_IN; /* set default error */
8748
    #endif
8749
3.26k
    #ifndef WOLFSSL_SP_NO_256
8750
3.26k
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
8751
        #ifdef WC_ECC_NONBLOCK
8752
            if (key->nb_ctx) {
8753
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8754
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8755
                    key->heap);
8756
            }
8757
            #ifdef WC_ECC_NONBLOCK_ONLY
8758
            do { /* perform blocking call to non-blocking function */
8759
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
8760
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8761
                    key->heap);
8762
            } while (err == FP_WOULDBLOCK);
8763
            return err;
8764
            #endif
8765
        #endif /* WC_ECC_NONBLOCK */
8766
741
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8767
741
            {
8768
741
                int ret;
8769
741
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8770
741
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
8771
741
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8772
741
                RESTORE_VECTOR_REGISTERS();
8773
741
                return ret;
8774
741
            }
8775
741
        #endif
8776
741
        }
8777
2.52k
    #endif
8778
2.52k
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
8779
2.52k
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
8780
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
8781
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
8782
                key->pubkey.y, key->pubkey.z, r, s, res,
8783
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
8784
                                          key->fpIdx, key->fpBuild, key->heap),
8785
                key->heap);
8786
            #endif
8787
551
            #if !defined(FP_ECC_CONTROL)
8788
551
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
8789
551
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8790
551
            #endif
8791
551
        }
8792
1.97k
    #endif
8793
1.97k
    #ifdef WOLFSSL_SP_384
8794
1.97k
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
8795
        #ifdef WC_ECC_NONBLOCK
8796
            if (key->nb_ctx) {
8797
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8798
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8799
                    key->heap);
8800
            }
8801
            #ifdef WC_ECC_NONBLOCK_ONLY
8802
            do { /* perform blocking call to non-blocking function */
8803
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
8804
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8805
                    key->heap);
8806
            } while (err == FP_WOULDBLOCK);
8807
            return err;
8808
            #endif
8809
        #endif /* WC_ECC_NONBLOCK */
8810
696
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8811
696
            {
8812
696
                int ret;
8813
696
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8814
696
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
8815
696
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8816
696
                RESTORE_VECTOR_REGISTERS();
8817
696
                return ret;
8818
696
            }
8819
696
        #endif
8820
696
        }
8821
1.27k
    #endif
8822
1.27k
    #ifdef WOLFSSL_SP_521
8823
1.27k
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
8824
        #ifdef WC_ECC_NONBLOCK
8825
            if (key->nb_ctx) {
8826
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8827
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8828
                    key->heap);
8829
            }
8830
            #ifdef WC_ECC_NONBLOCK_ONLY
8831
            do { /* perform blocking call to non-blocking function */
8832
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
8833
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8834
                    key->heap);
8835
            } while (err == FP_WOULDBLOCK);
8836
            return err;
8837
            #endif
8838
        #endif /* WC_ECC_NONBLOCK */
8839
1.27k
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8840
1.27k
            {
8841
1.27k
                int ret;
8842
1.27k
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8843
1.27k
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
8844
1.27k
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8845
1.27k
                RESTORE_VECTOR_REGISTERS();
8846
1.27k
                return ret;
8847
1.27k
            }
8848
1.27k
        #endif
8849
1.27k
        }
8850
1.27k
    #endif
8851
1.27k
    }
8852
0
#endif
8853
8854
0
    return NOT_COMPILED_IN;
8855
3.26k
}
8856
8857
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
8858
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
8859
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
8860
{
8861
   int        err;
8862
   ecc_point* mG = NULL;
8863
   ecc_point* mQ = NULL;
8864
#ifdef WOLFSSL_NO_MALLOC
8865
   ecc_point  lcl_mG;
8866
   ecc_point  lcl_mQ;
8867
#endif
8868
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8869
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8870
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8871
#endif
8872
   mp_int*    e;
8873
   mp_int*    v = NULL;      /* Will be w. */
8874
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
8875
   mp_int     u1tmp[1];
8876
   mp_int     u2tmp[1];
8877
#endif
8878
   mp_int*    u1 = NULL;     /* Will be e. */
8879
   mp_int*    u2 = NULL;     /* Will be w. */
8880
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
8881
   err = wc_ecc_alloc_mpint(key, &key->e);
8882
   if (err != 0) {
8883
      return err;
8884
   }
8885
   e = key->e;
8886
8887
   err = mp_init(e);
8888
#else
8889
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8890
#ifdef MP_INT_SIZE_CHECK_NULL
8891
   if (e_lcl == NULL) {
8892
       return MEMORY_E;
8893
   }
8894
#endif
8895
   e = e_lcl;
8896
8897
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8898
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8899
   if (err != MP_OKAY) {
8900
#ifdef WOLFSSL_SMALL_STACK
8901
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8902
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8903
   #endif
8904
#endif
8905
      return MEMORY_E;
8906
   }
8907
8908
   /* read hash */
8909
   if (err == MP_OKAY) {
8910
       /* we may need to truncate if hash is longer than key size */
8911
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
8912
8913
       /* truncate down to byte size, may be all that's needed */
8914
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8915
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8916
       err = mp_read_unsigned_bin(e, hash, hashlen);
8917
8918
       /* may still need bit truncation too */
8919
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8920
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8921
   }
8922
8923
   /* check for async hardware acceleration */
8924
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8925
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8926
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8927
   #ifdef HAVE_CAVIUM_V
8928
      if (NitroxEccIsCurveSupported(key))
8929
   #endif
8930
      {
8931
          word32 keySz = (word32)key->dp->size;
8932
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8933
          if (err == MP_OKAY)
8934
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
8935
          if (err == MP_OKAY)
8936
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
8937
          if (err == MP_OKAY)
8938
          #ifdef HAVE_CAVIUM_V
8939
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
8940
                    &key->pubkey.y->raw, &r->raw, &s->raw,
8941
                    &curve->prime->raw, &curve->order->raw, res);
8942
          #else
8943
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
8944
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
8945
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
8946
                    &curve->Gx->raw, &curve->Gy->raw, res);
8947
          #endif
8948
8949
      #ifndef HAVE_CAVIUM_V
8950
          mp_clear(e);
8951
      #endif
8952
8953
          return err;
8954
      }
8955
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8956
   }
8957
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8958
8959
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8960
#ifdef MP_INT_SIZE_CHECK_NULL
8961
   if (w == NULL) {
8962
       err = MEMORY_E;
8963
   }
8964
#endif
8965
8966
   if (err == MP_OKAY) {
8967
#ifdef WOLFSSL_CHECK_VER_FAULTS
8968
    #ifndef WOLFSSL_NO_MALLOC
8969
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8970
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8971
       if (u1 == NULL || u2 == NULL)
8972
            err = MEMORY_E;
8973
    #else
8974
        u1 = u1tmp;
8975
        u2 = u2tmp;
8976
    #endif
8977
#else
8978
       u1 = e;
8979
       u2 = w;
8980
#endif
8981
       v = w;
8982
   }
8983
   if (err == MP_OKAY) {
8984
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8985
   }
8986
#ifdef WOLFSSL_CHECK_VER_FAULTS
8987
   if (err == MP_OKAY) {
8988
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8989
   }
8990
   if (err == MP_OKAY) {
8991
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8992
   }
8993
#endif
8994
8995
   /* allocate points */
8996
   if (err == MP_OKAY) {
8997
   #ifdef WOLFSSL_NO_MALLOC
8998
       mG = &lcl_mG;
8999
   #endif
9000
       err = wc_ecc_new_point_ex(&mG, key->heap);
9001
   }
9002
   if (err == MP_OKAY) {
9003
   #ifdef WOLFSSL_NO_MALLOC
9004
       mQ = &lcl_mQ;
9005
   #endif
9006
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9007
   }
9008
9009
   /*  w  = s^-1 mod n */
9010
   if (err == MP_OKAY)
9011
       err = mp_invmod(s, curve->order, w);
9012
9013
   /* u1 = ew */
9014
   if (err == MP_OKAY)
9015
       err = mp_mulmod(e, w, curve->order, u1);
9016
9017
#ifdef WOLFSSL_CHECK_VER_FAULTS
9018
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9019
        err = BAD_STATE_E;
9020
    }
9021
#endif
9022
9023
   /* u2 = rw */
9024
   if (err == MP_OKAY)
9025
       err = mp_mulmod(r, w, curve->order, u2);
9026
9027
#ifdef WOLFSSL_CHECK_VER_FAULTS
9028
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9029
        err = BAD_STATE_E;
9030
    }
9031
#endif
9032
9033
   /* find mG and mQ */
9034
   if (err == MP_OKAY)
9035
       err = mp_copy(curve->Gx, mG->x);
9036
   if (err == MP_OKAY)
9037
       err = mp_copy(curve->Gy, mG->y);
9038
   if (err == MP_OKAY)
9039
       err = mp_set(mG->z, 1);
9040
9041
   if (err == MP_OKAY)
9042
       err = mp_copy(key->pubkey.x, mQ->x);
9043
   if (err == MP_OKAY)
9044
       err = mp_copy(key->pubkey.y, mQ->y);
9045
   if (err == MP_OKAY)
9046
       err = mp_copy(key->pubkey.z, mQ->z);
9047
9048
#if defined(FREESCALE_LTC_ECC)
9049
   /* use PKHA to compute u1*mG + u2*mQ */
9050
   if (err == MP_OKAY)
9051
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9052
   if (err == MP_OKAY)
9053
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9054
   if (err == MP_OKAY)
9055
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9056
#else
9057
#ifndef ECC_SHAMIR
9058
    if (err == MP_OKAY)
9059
    {
9060
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9061
        ecc_point mG1, mQ1;
9062
        wc_ecc_copy_point(mQ, &mQ1);
9063
        wc_ecc_copy_point(mG, &mG1);
9064
     #endif
9065
9066
        mp_digit mp = 0;
9067
9068
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9069
            /* compute u1*mG + u2*mQ = mG */
9070
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9071
                                                                     key->heap);
9072
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9073
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9074
                err = BAD_STATE_E;
9075
            }
9076
9077
            /* store new value for comparing with after add operation */
9078
           wc_ecc_copy_point(mG, &mG1);
9079
        #endif
9080
            if (err == MP_OKAY) {
9081
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9082
                                                                     key->heap);
9083
            }
9084
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9085
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9086
                err = BAD_STATE_E;
9087
            }
9088
        #endif
9089
9090
            /* find the montgomery mp */
9091
            if (err == MP_OKAY)
9092
                err = mp_montgomery_setup(curve->prime, &mp);
9093
9094
            /* add them */
9095
            if (err == MP_OKAY)
9096
                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
9097
                                                        curve->prime, mp, NULL);
9098
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9099
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9100
                err = BAD_STATE_E;
9101
            }
9102
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9103
                err = BAD_STATE_E;
9104
            }
9105
        #endif
9106
        }
9107
        else {
9108
            /* compute 0*mG + u2*mQ = mG */
9109
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9110
                                                                     key->heap);
9111
            /* find the montgomery mp */
9112
            if (err == MP_OKAY)
9113
                err = mp_montgomery_setup(curve->prime, &mp);
9114
        }
9115
9116
        /* reduce */
9117
        if (err == MP_OKAY)
9118
            err = ecc_map(mG, curve->prime, mp);
9119
    }
9120
#else
9121
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9122
    if (err == MP_OKAY) {
9123
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9124
                                                                     key->heap);
9125
    }
9126
#endif /* ECC_SHAMIR */
9127
#endif /* FREESCALE_LTC_ECC */
9128
9129
   /* v = X_x1 mod n */
9130
   if (err == MP_OKAY)
9131
       err = mp_mod(mG->x, curve->order, v);
9132
9133
   /* does v == r */
9134
   if (err == MP_OKAY) {
9135
       if (mp_cmp(v, r) == MP_EQ)
9136
           *res = 1;
9137
#ifdef WOLFSSL_CHECK_VER_FAULTS
9138
       /* redundant comparison as sanity check that first one happened */
9139
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9140
           *res = 0;
9141
#endif
9142
   }
9143
9144
   /* cleanup */
9145
   wc_ecc_del_point_ex(mG, key->heap);
9146
   wc_ecc_del_point_ex(mQ, key->heap);
9147
9148
   mp_clear(e);
9149
   mp_clear(w);
9150
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9151
#ifdef WOLFSSL_CHECK_VER_FAULTS
9152
   mp_clear(u1);
9153
   mp_clear(u2);
9154
#ifndef WOLFSSL_NO_MALLOC
9155
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9156
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9157
#endif
9158
#endif
9159
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9160
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9161
#endif
9162
9163
   return err;
9164
}
9165
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9166
#endif /* HAVE_ECC_VERIFY_HELPER */
9167
9168
/**
9169
   Verify an ECC signature
9170
   r           The signature R component to verify
9171
   s           The signature S component to verify
9172
   hash        The hash (message digest) that was signed
9173
   hashlen     The length of the hash (octets)
9174
   res         Result of signature, 1==valid, 0==invalid
9175
   key         The corresponding public ECC key
9176
   return      MP_OKAY if successful (even if the signature is not valid)
9177
               Caller should check the *res value to determine if the signature
9178
               is valid or invalid. Other negative values are returned on error.
9179
*/
9180
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9181
                    word32 hashlen, int* res, ecc_key* key)
9182
3.29k
{
9183
#if defined(WOLFSSL_STM32_PKA)
9184
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9185
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9186
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9187
#else
9188
3.29k
   int           err;
9189
3.29k
   word32        keySz = 0;
9190
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9191
   byte sigRS[ATECC_KEY_SIZE*2];
9192
#elif defined(WOLFSSL_CRYPTOCELL)
9193
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9194
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9195
   word32 msgLenInBytes = hashlen;
9196
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9197
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9198
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9199
#elif defined(WOLFSSL_KCAPI_ECC)
9200
   byte sigRS[MAX_ECC_BYTES*2];
9201
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9202
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9203
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9204
#elif defined(WOLFSSL_SE050)
9205
#else
9206
3.29k
   int curveLoaded = 0;
9207
3.29k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9208
3.29k
#endif
9209
9210
3.29k
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9211
0
       return ECC_BAD_ARG_E;
9212
9213
   /* default to invalid signature */
9214
3.29k
   *res = 0;
9215
9216
   /* is the IDX valid ?  */
9217
3.29k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9218
0
      return ECC_BAD_ARG_E;
9219
0
   }
9220
9221
3.29k
   err = wc_ecc_check_r_s_range(key, r, s);
9222
3.29k
   if (err != MP_OKAY) {
9223
23
      return err;
9224
23
   }
9225
9226
3.27k
   keySz = (word32)key->dp->size;
9227
9228
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9229
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9230
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9231
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9232
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9233
            sw->eccVerify.r = r;
9234
            sw->eccVerify.s = s;
9235
            sw->eccVerify.hash = hash;
9236
            sw->eccVerify.hashlen = hashlen;
9237
            sw->eccVerify.stat = res;
9238
            sw->eccVerify.key = key;
9239
            return WC_PENDING_E;
9240
        }
9241
    }
9242
#endif
9243
9244
#ifndef HAVE_ECC_VERIFY_HELPER
9245
9246
#ifndef WOLFSSL_SE050
9247
    /* Extract R and S with front zero padding (if required),
9248
     * SE050 does this in port layer  */
9249
    XMEMSET(sigRS, 0, sizeof(sigRS));
9250
    err = mp_to_unsigned_bin(r, sigRS +
9251
                                (keySz - mp_unsigned_bin_size(r)));
9252
    if (err != MP_OKAY) {
9253
        return err;
9254
    }
9255
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9256
                                (keySz - mp_unsigned_bin_size(s)));
9257
    if (err != MP_OKAY) {
9258
        return err;
9259
    }
9260
#endif /* WOLFSSL_SE050 */
9261
9262
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9263
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9264
    if (err != 0) {
9265
       return err;
9266
    }
9267
    (void)hashlen;
9268
#elif defined(WOLFSSL_CRYPTOCELL)
9269
9270
   /* truncate if hash is longer than key size */
9271
   if (msgLenInBytes > keySz) {
9272
       msgLenInBytes = keySz;
9273
   }
9274
   hash_mode = cc310_hashModeECC(msgLenInBytes);
9275
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
9276
       /* hash_mode = */ cc310_hashModeECC(keySz);
9277
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
9278
   }
9279
9280
   /* verify the signature using the public key */
9281
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
9282
                           &key->ctx.pubKey,
9283
                           hash_mode,
9284
                           &sigRS[0],
9285
                           keySz*2,
9286
                           (byte*)hash,
9287
                           msgLenInBytes);
9288
9289
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
9290
       /* signature verification reported invalid signature. */
9291
       *res = 0; /* Redundant, added for code clarity */
9292
       err = MP_OKAY;
9293
   }
9294
   else if (err != SA_SILIB_RET_OK) {
9295
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
9296
       return err;
9297
   }
9298
   else {
9299
       /* valid signature. */
9300
       *res = 1;
9301
       err = MP_OKAY;
9302
   }
9303
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9304
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
9305
                                hash, hashlen,
9306
                                res, key);
9307
#elif defined(WOLFSSL_KCAPI_ECC)
9308
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
9309
    if (err == 0) {
9310
        *res = 1;
9311
    }
9312
#elif defined(WOLFSSL_SE050)
9313
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9314
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9315
    if (hashlen > sizeof(hashcopy))
9316
        return ECC_BAD_ARG_E;
9317
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
9318
    mp_reverse(sigRS, keySz);
9319
    mp_reverse(sigRS + keySz, keySz);
9320
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
9321
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
9322
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
9323
9324
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
9325
                                     xil_curve_type[key->dp->id],
9326
                                     XIL_CAST_U64(hashcopy), keySz,
9327
                                     XIL_CAST_U64(key->keyRaw),
9328
                                     XIL_CAST_U64(sigRS));
9329
9330
    if (err != XST_SUCCESS) {
9331
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
9332
        err = WC_HW_E;
9333
    } else {
9334
        *res = 1;
9335
    }
9336
#endif
9337
9338
#else
9339
  /* checking if private key with no public part */
9340
3.27k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9341
1.55k
      WOLFSSL_MSG("Verify called with private key, generating public part");
9342
1.55k
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9343
1.55k
      if (err != MP_OKAY) {
9344
1
          return err;
9345
1
      }
9346
1.55k
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9347
1.55k
      if (err != MP_OKAY) {
9348
0
          FREE_CURVE_SPECS();
9349
0
          return err;
9350
0
      }
9351
1.55k
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9352
1.55k
      if (err != MP_OKAY) {
9353
6
           WOLFSSL_MSG("Unable to extract public key");
9354
6
           wc_ecc_curve_free(curve);
9355
6
           FREE_CURVE_SPECS();
9356
6
           return err;
9357
6
      }
9358
1.54k
      curveLoaded = 1;
9359
1.54k
  }
9360
9361
3.26k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9362
3.26k
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
9363
3.26k
      if (curveLoaded) {
9364
1.54k
           wc_ecc_curve_free(curve);
9365
1.54k
           FREE_CURVE_SPECS();
9366
1.54k
      }
9367
3.26k
      return err;
9368
3.26k
  }
9369
9370
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9371
   if (!curveLoaded) {
9372
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9373
       if (err != 0) {
9374
          return err;
9375
       }
9376
       /* read in the specs for this curve */
9377
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9378
       if (err != 0) {
9379
          FREE_CURVE_SPECS();
9380
          return err;
9381
       }
9382
   }
9383
9384
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9385
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9386
9387
0
   (void)curveLoaded;
9388
0
   wc_ecc_curve_free(curve);
9389
0
   FREE_CURVE_SPECS();
9390
0
#endif /* HAVE_ECC_VERIFY_HELPER */
9391
9392
0
   (void)keySz;
9393
0
   (void)hashlen;
9394
9395
0
   return err;
9396
3.26k
#endif /* WOLFSSL_STM32_PKA */
9397
3.26k
}
9398
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
9399
#endif /* HAVE_ECC_VERIFY */
9400
9401
#ifdef HAVE_ECC_KEY_IMPORT
9402
/* import point from der
9403
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
9404
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
9405
                               const int curve_idx, ecc_point* point,
9406
                               int shortKeySize)
9407
20
{
9408
20
    int err = 0;
9409
20
#ifdef HAVE_COMP_KEY
9410
20
    int compressed = 0;
9411
20
#endif
9412
20
    int keysize;
9413
20
    byte pointType;
9414
9415
#ifndef HAVE_COMP_KEY
9416
    (void)shortKeySize;
9417
#endif
9418
9419
20
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9420
20
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9421
0
        return ECC_BAD_ARG_E;
9422
9423
    /* must be odd */
9424
20
    if ((inLen & 1) == 0) {
9425
0
        return ECC_BAD_ARG_E;
9426
0
    }
9427
9428
    /* clear if previously allocated */
9429
20
    mp_clear(point->x);
9430
20
    mp_clear(point->y);
9431
20
    mp_clear(point->z);
9432
9433
    /* init point */
9434
#ifdef ALT_ECC_SIZE
9435
    point->x = (mp_int*)&point->xyz[0];
9436
    point->y = (mp_int*)&point->xyz[1];
9437
    point->z = (mp_int*)&point->xyz[2];
9438
    alt_fp_init(point->x);
9439
    alt_fp_init(point->y);
9440
    alt_fp_init(point->z);
9441
#else
9442
20
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9443
20
#endif
9444
20
    if (err != MP_OKAY)
9445
0
        return MEMORY_E;
9446
9447
20
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9448
9449
    /* check for point type (4, 2, or 3) */
9450
20
    pointType = in[0];
9451
20
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9452
0
                                         pointType != ECC_POINT_COMP_ODD) {
9453
0
        err = ASN_PARSE_E;
9454
0
    }
9455
9456
20
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9457
0
#ifdef HAVE_COMP_KEY
9458
0
        compressed = 1;
9459
#else
9460
        err = NOT_COMPILED_IN;
9461
#endif
9462
0
    }
9463
9464
    /* adjust to skip first byte */
9465
20
    inLen -= 1;
9466
20
    in += 1;
9467
9468
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9469
     * is true */
9470
20
#ifdef HAVE_COMP_KEY
9471
20
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9472
#else
9473
    keysize = (int)(inLen>>1);
9474
#endif
9475
9476
    /* read data */
9477
20
    if (err == MP_OKAY)
9478
20
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9479
9480
20
#ifdef HAVE_COMP_KEY
9481
20
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9482
0
    #if defined(WOLFSSL_HAVE_SP_ECC)
9483
0
        #ifndef WOLFSSL_SP_NO_256
9484
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9485
0
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
9486
0
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
9487
0
        }
9488
0
        else
9489
0
        #endif
9490
0
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9491
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9492
0
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
9493
0
            sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
9494
0
        }
9495
0
        else
9496
0
        #endif
9497
0
        #ifdef WOLFSSL_SP_384
9498
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9499
0
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
9500
0
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
9501
0
        }
9502
0
        else
9503
0
        #endif
9504
0
        #ifdef WOLFSSL_SP_521
9505
0
        if (curve_idx != ECC_CUSTOM_IDX &&
9506
0
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
9507
0
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
9508
0
        }
9509
0
        else
9510
0
        #endif
9511
0
    #endif
9512
    #if !defined(WOLFSSL_SP_MATH)
9513
        {
9514
            int did_init = 0;
9515
        #ifdef WOLFSSL_SMALL_STACK
9516
            mp_int* t1 = NULL;
9517
            mp_int* t2 = NULL;
9518
        #else
9519
            mp_int t1[1], t2[1];
9520
        #endif
9521
            DECLARE_CURVE_SPECS(3);
9522
9523
            ALLOC_CURVE_SPECS(3, err);
9524
9525
        #ifdef WOLFSSL_SMALL_STACK
9526
            if (err == MP_OKAY) {
9527
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9528
                                      DYNAMIC_TYPE_BIGINT);
9529
                if (t1 == NULL) {
9530
                    err = MEMORY_E;
9531
                }
9532
            }
9533
            if (err == MP_OKAY) {
9534
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9535
                                      DYNAMIC_TYPE_BIGINT);
9536
                if (t2 == NULL) {
9537
                    err = MEMORY_E;
9538
                }
9539
            }
9540
        #endif
9541
9542
            if (err == MP_OKAY) {
9543
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9544
                    err = MEMORY_E;
9545
                else
9546
                    did_init = 1;
9547
            }
9548
9549
            /* load curve info */
9550
            if (err == MP_OKAY)
9551
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9552
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9553
                        ECC_CURVE_FIELD_BF));
9554
9555
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
9556
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
9557
            /* validate prime is prime for custom curves */
9558
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
9559
                int isPrime = MP_NO;
9560
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
9561
                if (err == MP_OKAY && isPrime == MP_NO)
9562
                    err = MP_VAL;
9563
            }
9564
        #endif
9565
9566
            /* compute x^3 */
9567
            if (err == MP_OKAY)
9568
                err = mp_sqr(point->x, t1);
9569
            if (err == MP_OKAY)
9570
                err = mp_mulmod(t1, point->x, curve->prime, t1);
9571
9572
            /* compute x^3 + a*x */
9573
            if (err == MP_OKAY)
9574
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
9575
            if (err == MP_OKAY)
9576
                err = mp_add(t1, t2, t1);
9577
9578
            /* compute x^3 + a*x + b */
9579
            if (err == MP_OKAY)
9580
                err = mp_add(t1, curve->Bf, t1);
9581
9582
            /* compute sqrt(x^3 + a*x + b) */
9583
            if (err == MP_OKAY)
9584
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
9585
9586
            /* adjust y */
9587
            if (err == MP_OKAY) {
9588
                if ((mp_isodd(t2) == MP_YES &&
9589
                                            pointType == ECC_POINT_COMP_ODD) ||
9590
                    (mp_isodd(t2) == MP_NO &&
9591
                                            pointType == ECC_POINT_COMP_EVEN)) {
9592
                    err = mp_mod(t2, curve->prime, point->y);
9593
                }
9594
                else {
9595
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
9596
                }
9597
            }
9598
9599
            if (did_init) {
9600
                mp_clear(t2);
9601
                mp_clear(t1);
9602
            }
9603
9604
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
9605
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
9606
9607
            wc_ecc_curve_free(curve);
9608
            FREE_CURVE_SPECS();
9609
        }
9610
    #else
9611
0
        {
9612
0
            err = WC_KEY_SIZE_E;
9613
0
        }
9614
0
    #endif
9615
0
    }
9616
20
#endif
9617
9618
20
    if (err == MP_OKAY) {
9619
20
#ifdef HAVE_COMP_KEY
9620
20
        if (compressed == 0)
9621
20
#endif
9622
20
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9623
20
    }
9624
20
    if (err == MP_OKAY)
9625
20
        err = mp_set(point->z, 1);
9626
9627
20
    if (err != MP_OKAY) {
9628
0
        mp_clear(point->x);
9629
0
        mp_clear(point->y);
9630
0
        mp_clear(point->z);
9631
0
    }
9632
9633
20
    RESTORE_VECTOR_REGISTERS();
9634
9635
20
    return err;
9636
20
}
9637
9638
/* function for backwards compatibility with previous implementations */
9639
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
9640
                            ecc_point* point)
9641
132
{
9642
132
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9643
132
}
9644
#endif /* HAVE_ECC_KEY_IMPORT */
9645
9646
#ifdef HAVE_ECC_KEY_EXPORT
9647
/* export point to der */
9648
9649
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
9650
                               word32* outLen, int compressed)
9651
0
{
9652
0
    if (compressed == 0)
9653
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
9654
0
#ifdef HAVE_COMP_KEY
9655
0
    else
9656
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
9657
#else
9658
    return NOT_COMPILED_IN;
9659
#endif
9660
0
}
9661
9662
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
9663
                            word32* outLen)
9664
352
{
9665
352
    int    ret = MP_OKAY;
9666
352
    word32 numlen;
9667
352
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9668
9669
352
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9670
0
        return ECC_BAD_ARG_E;
9671
9672
352
    numlen = (word32)ecc_sets[curve_idx].size;
9673
9674
    /* return length needed only */
9675
352
    if (point != NULL && out == NULL && outLen != NULL) {
9676
29
        *outLen = 1 + 2*numlen;
9677
29
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9678
29
    }
9679
9680
323
    if (point == NULL || out == NULL || outLen == NULL)
9681
0
        return ECC_BAD_ARG_E;
9682
9683
323
    if (*outLen < (1 + 2*numlen)) {
9684
17
        *outLen = 1 + 2*numlen;
9685
17
        return BUFFER_E;
9686
17
    }
9687
9688
    /* Sanity check the ordinates' sizes. */
9689
306
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9690
276
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9691
77
        return ECC_BAD_ARG_E;
9692
77
    }
9693
9694
    /* store byte point type */
9695
229
    out[0] = ECC_POINT_UNCOMP;
9696
9697
229
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9698
229
        return MEMORY_E);
9699
9700
    /* pad and store x */
9701
148
    XMEMSET(buf, 0, ECC_BUFSIZE);
9702
148
    ret = mp_to_unsigned_bin(point->x, buf +
9703
148
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9704
148
    if (ret != MP_OKAY)
9705
8
        goto done;
9706
140
    XMEMCPY(out+1, buf, numlen);
9707
9708
    /* pad and store y */
9709
140
    XMEMSET(buf, 0, ECC_BUFSIZE);
9710
140
    ret = mp_to_unsigned_bin(point->y, buf +
9711
140
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9712
140
    if (ret != MP_OKAY)
9713
8
        goto done;
9714
132
    XMEMCPY(out+1+numlen, buf, numlen);
9715
9716
132
    *outLen = 1 + 2*numlen;
9717
9718
148
done:
9719
148
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9720
9721
148
    return ret;
9722
132
}
9723
9724
9725
/* export point to der */
9726
#ifdef HAVE_COMP_KEY
9727
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
9728
                                       byte* out, word32* outLen)
9729
0
{
9730
0
    int    ret = MP_OKAY;
9731
0
    word32 numlen;
9732
0
    word32 output_len;
9733
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9734
9735
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9736
0
        return ECC_BAD_ARG_E;
9737
9738
0
    numlen = (word32)ecc_sets[curve_idx].size;
9739
0
    output_len = 1 + numlen; /* y point type + x */
9740
9741
    /* return length needed only */
9742
0
    if (point != NULL && out == NULL && outLen != NULL) {
9743
0
        *outLen = output_len;
9744
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9745
0
    }
9746
9747
0
    if (point == NULL || out == NULL || outLen == NULL)
9748
0
        return ECC_BAD_ARG_E;
9749
9750
9751
0
    if (*outLen < output_len) {
9752
0
        *outLen = output_len;
9753
0
        return BUFFER_E;
9754
0
    }
9755
9756
    /* Sanity check the ordinate's size. */
9757
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
9758
0
        return ECC_BAD_ARG_E;
9759
0
    }
9760
9761
    /* store byte point type */
9762
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
9763
0
                                            ECC_POINT_COMP_EVEN;
9764
9765
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9766
0
        return MEMORY_E);
9767
9768
    /* pad and store x */
9769
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9770
0
    ret = mp_to_unsigned_bin(point->x, buf +
9771
0
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
9772
0
    if (ret != MP_OKAY)
9773
0
        goto done;
9774
0
    XMEMCPY(out+1, buf, numlen);
9775
9776
0
    *outLen = output_len;
9777
9778
0
done:
9779
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9780
9781
0
    return ret;
9782
0
}
9783
#endif /* HAVE_COMP_KEY */
9784
9785
/* export public ECC key in ANSI X9.63 format */
9786
WOLFSSL_ABI
9787
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
9788
12.2k
{
9789
12.2k
   int    ret = MP_OKAY;
9790
12.2k
   word32 numlen;
9791
12.2k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9792
12.2k
   word32 pubxlen, pubylen;
9793
9794
   /* return length needed only */
9795
12.2k
   if (key != NULL && out == NULL && outLen != NULL) {
9796
      /* if key hasn't been setup assume max bytes for size estimation */
9797
1.97k
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9798
1.97k
      *outLen = 1 + 2 * numlen;
9799
1.97k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9800
1.97k
   }
9801
9802
10.2k
   if (key == NULL || out == NULL || outLen == NULL)
9803
0
      return ECC_BAD_ARG_E;
9804
9805
10.2k
   if (key->type == ECC_PRIVATEKEY_ONLY)
9806
168
       return ECC_PRIVATEONLY_E;
9807
9808
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
9809
    /* check if public key in secure memory */
9810
    if (key->securePubKey > 0) {
9811
        int keySz = wc_ecc_size(key);
9812
9813
        /* store byte point type */
9814
        out[0] = ECC_POINT_UNCOMP;
9815
9816
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
9817
            return WC_HW_E;
9818
9819
        *outLen = 1 + 2*keySz;
9820
        return MP_OKAY;
9821
    }
9822
#endif
9823
9824
10.0k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9825
1.32k
       return ECC_BAD_ARG_E;
9826
1.32k
   }
9827
9828
8.75k
   numlen = (word32)key->dp->size;
9829
9830
    /* verify room in out buffer */
9831
8.75k
   if (*outLen < (1 + 2*numlen)) {
9832
0
      *outLen = 1 + 2*numlen;
9833
0
      return BUFFER_E;
9834
0
   }
9835
9836
   /* verify public key length is less than key size */
9837
8.75k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9838
8.75k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9839
8.75k
   if ((pubxlen > numlen) || (pubylen > numlen)) {
9840
0
      WOLFSSL_MSG("Public key x/y invalid!");
9841
0
      return BUFFER_E;
9842
0
   }
9843
9844
   /* store byte point type */
9845
8.75k
   out[0] = ECC_POINT_UNCOMP;
9846
9847
8.75k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9848
8.75k
       return MEMORY_E);
9849
9850
   /* pad and store x */
9851
8.69k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9852
8.69k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9853
8.69k
   if (ret != MP_OKAY)
9854
7
      goto done;
9855
8.68k
   XMEMCPY(out+1, buf, numlen);
9856
9857
   /* pad and store y */
9858
8.68k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9859
8.68k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9860
8.68k
   if (ret != MP_OKAY)
9861
10
      goto done;
9862
8.67k
   XMEMCPY(out+1+numlen, buf, numlen);
9863
9864
8.67k
   *outLen = 1 + 2*numlen;
9865
9866
8.69k
done:
9867
8.69k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9868
9869
8.69k
   return ret;
9870
8.67k
}
9871
9872
9873
/* export public ECC key in ANSI X9.63 format, extended with
9874
 * compression option */
9875
WOLFSSL_ABI
9876
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
9877
                          int compressed)
9878
7.78k
{
9879
7.78k
    if (compressed == 0)
9880
4.16k
        return wc_ecc_export_x963(key, out, outLen);
9881
3.61k
#ifdef HAVE_COMP_KEY
9882
3.61k
    else
9883
3.61k
        return wc_ecc_export_x963_compressed(key, out, outLen);
9884
#else
9885
    return NOT_COMPILED_IN;
9886
#endif
9887
7.78k
}
9888
#endif /* HAVE_ECC_KEY_EXPORT */
9889
9890
9891
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
9892
9893
/* is ecc point on curve described by dp ? */
9894
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
9895
2.78k
{
9896
#if !defined(WOLFSSL_SP_MATH)
9897
   int err;
9898
#ifdef WOLFSSL_SMALL_STACK
9899
   mp_int* t1;
9900
   mp_int* t2;
9901
#else
9902
   mp_int  t1[1], t2[1];
9903
#endif
9904
9905
#ifdef WOLFSSL_SMALL_STACK
9906
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9907
   if (t1 == NULL)
9908
       return MEMORY_E;
9909
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9910
   if (t2 == NULL) {
9911
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9912
       return MEMORY_E;
9913
   }
9914
#endif
9915
9916
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
9917
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9918
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9919
      return err;
9920
   }
9921
9922
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9923
9924
   /* compute y^2 */
9925
   if (err == MP_OKAY)
9926
       err = mp_sqr(ecp->y, t1);
9927
9928
   /* compute x^3 */
9929
   if (err == MP_OKAY)
9930
       err = mp_sqr(ecp->x, t2);
9931
   if (err == MP_OKAY)
9932
       err = mp_mod(t2, prime, t2);
9933
   if (err == MP_OKAY)
9934
       err = mp_mul(ecp->x, t2, t2);
9935
9936
   /* compute y^2 - x^3 */
9937
   if (err == MP_OKAY)
9938
       err = mp_submod(t1, t2, prime, t1);
9939
9940
   /* Determine if curve "a" should be used in calc */
9941
#ifdef WOLFSSL_CUSTOM_CURVES
9942
   if (err == MP_OKAY) {
9943
      /* Use a and prime to determine if a == 3 */
9944
      err = mp_set(t2, 0);
9945
      if (err == MP_OKAY)
9946
          err = mp_submod(prime, a, prime, t2);
9947
   }
9948
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
9949
      /* compute y^2 - x^3 + a*x */
9950
      if (err == MP_OKAY)
9951
          err = mp_mulmod(t2, ecp->x, prime, t2);
9952
      if (err == MP_OKAY)
9953
          err = mp_addmod(t1, t2, prime, t1);
9954
   }
9955
   else
9956
#endif /* WOLFSSL_CUSTOM_CURVES */
9957
   {
9958
      /* assumes "a" == 3 */
9959
      (void)a;
9960
9961
      /* compute y^2 - x^3 + 3x */
9962
      if (err == MP_OKAY)
9963
          err = mp_add(t1, ecp->x, t1);
9964
      if (err == MP_OKAY)
9965
          err = mp_add(t1, ecp->x, t1);
9966
      if (err == MP_OKAY)
9967
          err = mp_add(t1, ecp->x, t1);
9968
      if (err == MP_OKAY)
9969
          err = mp_mod(t1, prime, t1);
9970
  }
9971
9972
   /* adjust range (0, prime) */
9973
   while (err == MP_OKAY && mp_isneg(t1)) {
9974
      err = mp_add(t1, prime, t1);
9975
   }
9976
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
9977
      err = mp_sub(t1, prime, t1);
9978
   }
9979
9980
   /* compare to b */
9981
   if (err == MP_OKAY) {
9982
       if (mp_cmp(t1, b) != MP_EQ) {
9983
          err = IS_POINT_E;
9984
       } else {
9985
          err = MP_OKAY;
9986
       }
9987
   }
9988
9989
   mp_clear(t1);
9990
   mp_clear(t2);
9991
9992
   RESTORE_VECTOR_REGISTERS();
9993
9994
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9995
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9996
9997
   return err;
9998
#else
9999
2.78k
   (void)a;
10000
2.78k
   (void)b;
10001
10002
2.78k
#ifdef WOLFSSL_HAVE_SP_ECC
10003
2.78k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10004
2.78k
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10005
581
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10006
581
   }
10007
2.20k
#endif
10008
2.20k
#ifndef WOLFSSL_SP_NO_256
10009
2.20k
   if (mp_count_bits(prime) == 256) {
10010
712
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10011
712
   }
10012
1.49k
#endif
10013
1.49k
#ifdef WOLFSSL_SP_384
10014
1.49k
   if (mp_count_bits(prime) == 384) {
10015
712
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10016
712
   }
10017
778
#endif
10018
778
#ifdef WOLFSSL_SP_521
10019
778
   if (mp_count_bits(prime) == 521) {
10020
778
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10021
778
   }
10022
0
#endif
10023
#else
10024
   (void)ecp;
10025
   (void)prime;
10026
#endif
10027
0
   return WC_KEY_SIZE_E;
10028
778
#endif
10029
778
}
10030
10031
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10032
5.33k
{
10033
5.33k
    int err = MP_OKAY;
10034
10035
    /* Validate parameters. */
10036
5.33k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10037
0
        err = BAD_FUNC_ARG;
10038
0
    }
10039
10040
5.33k
    if (err == MP_OKAY) {
10041
        /* x must be in the range [0, p-1] */
10042
5.33k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10043
165
            err = ECC_OUT_OF_RANGE_E;
10044
165
        }
10045
5.33k
    }
10046
10047
5.33k
    if (err == MP_OKAY) {
10048
        /* y must be in the range [0, p-1] */
10049
5.16k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10050
158
            err = ECC_OUT_OF_RANGE_E;
10051
158
        }
10052
5.16k
    }
10053
10054
5.33k
    if (err == MP_OKAY) {
10055
        /* z must be one, that is point must be in affine form. */
10056
5.01k
        if (!mp_isone(ecp->z)) {
10057
1.04k
            err = ECC_BAD_ARG_E;
10058
1.04k
        }
10059
5.01k
    }
10060
10061
5.33k
    if (err == MP_OKAY) {
10062
        /* Check x and y are valid for curve equation. */
10063
3.96k
        err = _ecc_is_point(ecp, a, b, prime);
10064
3.96k
    }
10065
10066
5.33k
    return err;
10067
5.33k
}
10068
10069
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10070
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10071
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10072
/* validate privkey * generator == pubkey, 0 on success */
10073
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10074
{
10075
    int        err;
10076
    ecc_point* base = NULL;
10077
    ecc_point* res  = NULL;
10078
#ifdef WOLFSSL_NO_MALLOC
10079
    ecc_point lcl_base;
10080
    ecc_point lcl_res;
10081
#endif
10082
    DECLARE_CURVE_SPECS(3);
10083
10084
    if (key == NULL)
10085
        return BAD_FUNC_ARG;
10086
10087
    ALLOC_CURVE_SPECS(3, err);
10088
    if (err != MP_OKAY) {
10089
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10090
        return err;
10091
    }
10092
10093
#ifdef WOLFSSL_NO_MALLOC
10094
    res = &lcl_res;
10095
#endif
10096
    err = wc_ecc_new_point_ex(&res, key->heap);
10097
10098
#ifdef WOLFSSL_HAVE_SP_ECC
10099
#ifndef WOLFSSL_SP_NO_256
10100
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10101
        if (err == MP_OKAY) {
10102
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10103
        }
10104
    }
10105
    else
10106
#endif
10107
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10108
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10109
        if (err == MP_OKAY) {
10110
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10111
        }
10112
    }
10113
    else
10114
#endif
10115
#ifdef WOLFSSL_SP_384
10116
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10117
        if (err == MP_OKAY) {
10118
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10119
        }
10120
    }
10121
    else
10122
#endif
10123
#ifdef WOLFSSL_SP_521
10124
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10125
        if (err == MP_OKAY) {
10126
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10127
        }
10128
    }
10129
    else
10130
#endif
10131
#endif
10132
    {
10133
        if (err == MP_OKAY) {
10134
        #ifdef WOLFSSL_NO_MALLOC
10135
            base = &lcl_base;
10136
        #endif
10137
            err = wc_ecc_new_point_ex(&base, key->heap);
10138
        }
10139
10140
        if (err == MP_OKAY) {
10141
            /* load curve info */
10142
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10143
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10144
        }
10145
10146
        /* set up base generator */
10147
        if (err == MP_OKAY)
10148
            err = mp_copy(curve->Gx, base->x);
10149
        if (err == MP_OKAY)
10150
            err = mp_copy(curve->Gy, base->y);
10151
        if (err == MP_OKAY)
10152
            err = mp_set(base->z, 1);
10153
10154
#ifdef WOLFSSL_KCAPI_ECC
10155
        if (err == MP_OKAY) {
10156
            word32 pubkey_sz = (word32)key->dp->size*2;
10157
            if (key->handle == NULL) {
10158
                /* if handle loaded, then pubkey_raw already populated */
10159
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10160
            }
10161
            if (err == 0) {
10162
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10163
                                           pubkey_sz/2);
10164
            }
10165
            if (err == MP_OKAY) {
10166
                err = mp_read_unsigned_bin(res->y,
10167
                                           key->pubkey_raw + pubkey_sz/2,
10168
                                           pubkey_sz/2);
10169
            }
10170
            if (err == MP_OKAY) {
10171
                err = mp_set(res->z, 1);
10172
            }
10173
        }
10174
        (void)a;
10175
        (void)prime;
10176
#else
10177
#ifdef ECC_TIMING_RESISTANT
10178
        if (err == MP_OKAY)
10179
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10180
                                          curve->order, key->rng, 1, key->heap);
10181
#else
10182
        if (err == MP_OKAY)
10183
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10184
                                              curve->order, NULL, 1, key->heap);
10185
#endif
10186
#endif /* WOLFSSL_KCAPI_ECC */
10187
    }
10188
10189
    if (err == MP_OKAY) {
10190
        /* compare result to public key */
10191
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10192
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10193
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10194
            /* didn't match */
10195
            err = ECC_PRIV_KEY_E;
10196
        }
10197
    }
10198
10199
    wc_ecc_curve_free(curve);
10200
    wc_ecc_del_point_ex(res, key->heap);
10201
    wc_ecc_del_point_ex(base, key->heap);
10202
    FREE_CURVE_SPECS();
10203
10204
    return err;
10205
}
10206
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10207
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10208
10209
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10210
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10211
10212
/* check privkey generator helper, creates prime needed */
10213
static int ecc_check_privkey_gen_helper(ecc_key* key)
10214
{
10215
    int    err;
10216
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
10217
    DECLARE_CURVE_SPECS(2);
10218
#endif
10219
10220
    if (key == NULL)
10221
        return BAD_FUNC_ARG;
10222
10223
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10224
    /* Hardware based private key, so this operation is not supported */
10225
    err = MP_OKAY; /* just report success */
10226
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10227
    /* Hardware based private key, so this operation is not supported */
10228
    err = MP_OKAY; /* just report success */
10229
#elif defined(WOLFSSL_KCAPI_ECC)
10230
    /* Hardware based private key, so this operation is not supported */
10231
    err = MP_OKAY; /* just report success */
10232
#else
10233
    ALLOC_CURVE_SPECS(2, err);
10234
10235
    /* load curve info */
10236
    if (err == MP_OKAY)
10237
        err = wc_ecc_curve_load(key->dp, &curve,
10238
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10239
10240
    if (err == MP_OKAY)
10241
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10242
10243
    wc_ecc_curve_free(curve);
10244
    FREE_CURVE_SPECS();
10245
10246
#endif /* WOLFSSL_ATECC508A */
10247
10248
    return err;
10249
}
10250
10251
/* Performs a Pairwise Consistency Test on an ECC key pair. */
10252
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10253
{
10254
    int err = 0;
10255
    word32 flags = key->flags;
10256
10257
    /* If flags not set default to cofactor and dec/sign */
10258
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10259
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10260
    }
10261
10262
    if (flags & WC_ECC_FLAG_COFACTOR) {
10263
        err = ecc_check_privkey_gen_helper(key);
10264
    }
10265
10266
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10267
#ifndef WOLFSSL_SMALL_STACK
10268
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10269
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10270
#else
10271
        byte* sig;
10272
#endif
10273
        byte* digest;
10274
        word32 sigLen, digestLen;
10275
        int dynRng = 0, res = 0;
10276
10277
        sigLen = (word32)wc_ecc_sig_size(key);
10278
        digestLen = WC_SHA256_DIGEST_SIZE;
10279
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
10280
            DYNAMIC_TYPE_ECC, return MEMORY_E);
10281
        digest = sig + sigLen;
10282
10283
        if (rng == NULL) {
10284
            dynRng = 1;
10285
            rng = wc_rng_new(NULL, 0, key->heap);
10286
            if (rng == NULL) {
10287
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10288
                return MEMORY_E;
10289
            }
10290
        }
10291
10292
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10293
10294
        if (!err)
10295
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10296
                    rng, key);
10297
        if (!err)
10298
            err = wc_ecc_verify_hash(sig, sigLen,
10299
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10300
10301
        if (res == 0)
10302
            err = ECC_PCT_E;
10303
10304
        if (dynRng) {
10305
            wc_rng_free(rng);
10306
        }
10307
        ForceZero(sig, sigLen + digestLen);
10308
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10309
    }
10310
    (void)rng;
10311
10312
    if (err != 0)
10313
        err = ECC_PCT_E;
10314
10315
    return err;
10316
}
10317
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10318
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10319
10320
#ifndef WOLFSSL_SP_MATH
10321
/* validate order * pubkey = point at infinity, 0 on success */
10322
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10323
        mp_int* prime, mp_int* order)
10324
{
10325
    ecc_point* inf = NULL;
10326
#ifdef WOLFSSL_NO_MALLOC
10327
    ecc_point  lcl_inf;
10328
#endif
10329
    int err;
10330
10331
    if (key == NULL)
10332
        return BAD_FUNC_ARG;
10333
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10334
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10335
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10336
       return IS_POINT_E;
10337
   }
10338
10339
#ifdef WOLFSSL_NO_MALLOC
10340
    inf = &lcl_inf;
10341
#endif
10342
    err = wc_ecc_new_point_ex(&inf, key->heap);
10343
    if (err == MP_OKAY) {
10344
#ifdef WOLFSSL_HAVE_SP_ECC
10345
#ifndef WOLFSSL_SP_NO_256
10346
        if (key->idx != ECC_CUSTOM_IDX &&
10347
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
10348
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
10349
        }
10350
        else
10351
#endif
10352
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10353
        if (key->idx != ECC_CUSTOM_IDX &&
10354
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
10355
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
10356
        }
10357
        else
10358
#endif
10359
#ifdef WOLFSSL_SP_384
10360
        if (key->idx != ECC_CUSTOM_IDX &&
10361
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
10362
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
10363
        }
10364
        else
10365
#endif
10366
#ifdef WOLFSSL_SP_521
10367
        if (key->idx != ECC_CUSTOM_IDX &&
10368
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
10369
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
10370
        }
10371
        else
10372
#endif
10373
#endif
10374
#if !defined(WOLFSSL_SP_MATH)
10375
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10376
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10377
            err = ECC_INF_E;
10378
#else
10379
        {
10380
            (void)a;
10381
            (void)prime;
10382
10383
            err = WC_KEY_SIZE_E;
10384
        }
10385
#endif
10386
    }
10387
10388
    wc_ecc_del_point_ex(inf, key->heap);
10389
10390
    return err;
10391
}
10392
#endif /* !WOLFSSL_SP_MATH */
10393
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10394
10395
10396
#ifdef OPENSSL_EXTRA
10397
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
10398
{
10399
    int err = MP_OKAY;
10400
    DECLARE_CURVE_SPECS(2);
10401
10402
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
10403
        return BAD_FUNC_ARG;
10404
10405
    ALLOC_CURVE_SPECS(2, err);
10406
10407
    if (err == MP_OKAY)
10408
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10409
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
10410
    if (err == MP_OKAY)
10411
        err = mp_copy(curve->Gx, ecp->x);
10412
    if (err == MP_OKAY)
10413
        err = mp_copy(curve->Gy, ecp->y);
10414
    if (err == MP_OKAY)
10415
        err = mp_set(ecp->z, 1);
10416
10417
    wc_ecc_curve_free(curve);
10418
    FREE_CURVE_SPECS();
10419
10420
    return err;
10421
}
10422
#endif /* OPENSSL_EXTRA */
10423
10424
10425
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
10426
 * ECC Full Public Key Validation Routine. If the parameter
10427
 * partial is set, then it follows section 5.6.2.3.4, the ECC
10428
 * Partial Public Key Validation Routine.
10429
 * If the parameter priv is set, add in a few extra
10430
 * checks on the bounds of the private key. */
10431
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
10432
4.54k
{
10433
4.54k
    int err = MP_OKAY;
10434
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10435
    mp_int* b = NULL;
10436
    #ifdef USE_ECC_B_PARAM
10437
        DECLARE_CURVE_SPECS(4);
10438
    #else
10439
        #ifndef WOLFSSL_SMALL_STACK
10440
            mp_int b_lcl;
10441
        #endif
10442
        DECLARE_CURVE_SPECS(3);
10443
    #endif /* USE_ECC_B_PARAM */
10444
#endif
10445
10446
4.54k
    ASSERT_SAVED_VECTOR_REGISTERS();
10447
10448
4.54k
    if (key == NULL)
10449
0
        return BAD_FUNC_ARG;
10450
10451
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
10452
    /* consider key check success on HW crypto
10453
     * ex: ATECC508/608A, CryptoCell and Silabs
10454
     *
10455
     * consider key check success on most Crypt Cb only builds
10456
     */
10457
    err = MP_OKAY;
10458
10459
#else
10460
10461
4.54k
#ifdef WOLFSSL_HAVE_SP_ECC
10462
4.54k
#ifndef WOLFSSL_SP_NO_256
10463
4.54k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10464
1.24k
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10465
1.24k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10466
1.24k
    }
10467
3.30k
#endif
10468
3.30k
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10469
3.30k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10470
802
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10471
802
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10472
802
    }
10473
2.50k
#endif
10474
2.50k
#ifdef WOLFSSL_SP_384
10475
2.50k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10476
1.13k
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10477
1.13k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10478
1.13k
    }
10479
1.36k
#endif
10480
1.36k
#ifdef WOLFSSL_SP_521
10481
1.36k
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10482
1.36k
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10483
1.36k
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10484
1.36k
    }
10485
0
#endif
10486
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
10487
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
10488
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
10489
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10490
    }
10491
#endif
10492
0
#endif
10493
10494
#ifndef WOLFSSL_SP_MATH
10495
    #ifdef USE_ECC_B_PARAM
10496
        ALLOC_CURVE_SPECS(4, err);
10497
    #else
10498
        ALLOC_CURVE_SPECS(3, err);
10499
        #ifndef WOLFSSL_SMALL_STACK
10500
            b = &b_lcl;
10501
        #else
10502
            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10503
            if (b == NULL) {
10504
                FREE_CURVE_SPECS();
10505
                return MEMORY_E;
10506
            }
10507
        #endif
10508
        XMEMSET(b, 0, sizeof(mp_int));
10509
    #endif
10510
10511
    #ifdef WOLFSSL_CAAM
10512
    /* keys can be black encrypted ones which can not be checked like plain text
10513
     * keys */
10514
    if (key->blackKey > 0) {
10515
        /* encrypted key was used */
10516
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10517
        FREE_CURVE_SPECS();
10518
        return 0;
10519
    }
10520
    #endif
10521
10522
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
10523
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
10524
    /* pubkey point cannot be at infinity */
10525
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10526
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10527
        FREE_CURVE_SPECS();
10528
        return ECC_INF_E;
10529
    }
10530
10531
    /* load curve info */
10532
    if (err == MP_OKAY)
10533
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10534
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10535
#ifdef USE_ECC_B_PARAM
10536
            | ECC_CURVE_FIELD_BF
10537
#endif
10538
    ));
10539
10540
#ifndef USE_ECC_B_PARAM
10541
    /* load curve b parameter */
10542
    if (err == MP_OKAY)
10543
        err = mp_init(b);
10544
    if (err == MP_OKAY)
10545
        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
10546
#else
10547
    if (err == MP_OKAY)
10548
        b = curve->Bf;
10549
#endif
10550
10551
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
10552
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
10553
    /* Qx must be in the range [0, p-1] */
10554
    if (err == MP_OKAY) {
10555
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10556
                mp_isneg(key->pubkey.x)) {
10557
            err = ECC_OUT_OF_RANGE_E;
10558
        }
10559
    }
10560
10561
    /* Qy must be in the range [0, p-1] */
10562
    if (err == MP_OKAY) {
10563
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10564
                mp_isneg(key->pubkey.y)) {
10565
            err = ECC_OUT_OF_RANGE_E;
10566
        }
10567
    }
10568
10569
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
10570
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
10571
    /* make sure point is actually on curve */
10572
    if (err == MP_OKAY)
10573
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10574
10575
    if (!partial) {
10576
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10577
        /* pubkey * order must be at infinity */
10578
        if (err == MP_OKAY)
10579
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10580
                    curve->prime, curve->order);
10581
    }
10582
10583
    if (priv) {
10584
        /* SP 800-56Ar3, section 5.6.2.1.2 */
10585
        /* private keys must be in the range [1, n-1] */
10586
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10587
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10588
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10589
        #ifdef WOLFSSL_KCAPI_ECC
10590
            && key->handle == NULL
10591
        #endif
10592
        ) {
10593
            err = ECC_PRIV_KEY_E;
10594
        }
10595
10596
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
10597
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
10598
        /* private * base generator must equal pubkey */
10599
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
10600
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10601
    #endif
10602
    }
10603
10604
    wc_ecc_curve_free(curve);
10605
10606
#ifndef USE_ECC_B_PARAM
10607
    mp_clear(b);
10608
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10609
#endif
10610
10611
    FREE_CURVE_SPECS();
10612
10613
#else
10614
    /* The single precision math curve is not available */
10615
0
    err = WC_KEY_SIZE_E;
10616
0
#endif /* !WOLFSSL_SP_MATH */
10617
0
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10618
10619
0
    (void)partial;
10620
0
    (void)priv;
10621
0
    return err;
10622
1.36k
}
10623
10624
10625
/* perform sanity checks on ecc key validity, 0 on success */
10626
WOLFSSL_ABI
10627
int wc_ecc_check_key(ecc_key* key)
10628
14.2k
{
10629
14.2k
    int ret;
10630
14.2k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10631
14.2k
    ret = _ecc_validate_public_key(key, 0, 1);
10632
14.2k
    RESTORE_VECTOR_REGISTERS();
10633
14.2k
    return ret;
10634
14.2k
}
10635
10636
10637
#ifdef HAVE_ECC_KEY_IMPORT
10638
/* import public ECC key in ANSI X9.63 format */
10639
int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
10640
                           int curve_id, int untrusted)
10641
380
{
10642
380
    int err = MP_OKAY;
10643
380
#ifdef HAVE_COMP_KEY
10644
380
    int compressed = 0;
10645
380
#endif
10646
380
    int keysize = 0;
10647
380
    byte pointType;
10648
#ifdef WOLFSSL_CRYPTOCELL
10649
    const CRYS_ECPKI_Domain_t* pDomain;
10650
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10651
#endif
10652
380
    if (in == NULL || key == NULL)
10653
0
        return BAD_FUNC_ARG;
10654
10655
    /* must be odd */
10656
380
    if ((inLen & 1) == 0) {
10657
0
        return ECC_BAD_ARG_E;
10658
0
    }
10659
10660
    /* make sure required variables are reset */
10661
380
    wc_ecc_reset(key);
10662
10663
    /* init key */
10664
    #ifdef ALT_ECC_SIZE
10665
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10666
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10667
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10668
        alt_fp_init(key->pubkey.x);
10669
        alt_fp_init(key->pubkey.y);
10670
        alt_fp_init(key->pubkey.z);
10671
        key->k = (mp_int*)key->ka;
10672
        alt_fp_init(key->k);
10673
    #ifdef WOLFSSL_ECC_BLIND_K
10674
        key->kb = (mp_int*)key->kba;
10675
        key->ku = (mp_int*)key->kua;
10676
        alt_fp_init(key->kb);
10677
        alt_fp_init(key->ku);
10678
    #endif
10679
    #else
10680
380
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10681
380
    #ifndef WOLFSSL_ECC_BLIND_K
10682
380
                                                                      NULL, NULL
10683
    #else
10684
                                                                key->kb, key->ku
10685
    #endif
10686
380
                            );
10687
380
    #endif
10688
380
    if (err != MP_OKAY)
10689
0
        return MEMORY_E;
10690
#ifdef WOLFSSL_ECC_BLIND_K
10691
    mp_forcezero(key->kb);
10692
#endif
10693
10694
380
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10695
10696
    /* check for point type (4, 2, or 3) */
10697
380
    pointType = in[0];
10698
380
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10699
93
                                         pointType != ECC_POINT_COMP_ODD) {
10700
8
        err = ASN_PARSE_E;
10701
8
    }
10702
10703
380
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10704
214
    #ifdef HAVE_COMP_KEY
10705
214
        compressed = 1;
10706
    #else
10707
        err = NOT_COMPILED_IN;
10708
    #endif
10709
214
    }
10710
10711
    /* adjust to skip first byte */
10712
380
    inLen -= 1;
10713
380
    in += 1;
10714
10715
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10716
    /* For SECP256R1 only save raw public key for hardware */
10717
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
10718
    #ifdef HAVE_COMP_KEY
10719
        if (!compressed)
10720
    #endif
10721
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10722
    }
10723
#elif defined(WOLFSSL_KCAPI_ECC)
10724
    XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10725
#endif
10726
10727
380
    if (err == MP_OKAY) {
10728
372
    #ifdef HAVE_COMP_KEY
10729
        /* adjust inLen if compressed */
10730
372
        if (compressed)
10731
214
            inLen = inLen*2 + 1;  /* used uncompressed len */
10732
372
    #endif
10733
10734
        /* determine key size */
10735
372
        keysize = (int)(inLen>>1);
10736
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
10737
         *       on created keys or signatures */
10738
372
        err = wc_ecc_set_curve(key, keysize, curve_id);
10739
372
        key->type = ECC_PUBLICKEY;
10740
372
    }
10741
10742
    /* read data */
10743
380
    if (err == MP_OKAY)
10744
372
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10745
10746
380
#ifdef HAVE_COMP_KEY
10747
380
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10748
#if !defined(WOLFSSL_SP_MATH)
10749
    #ifdef WOLFSSL_SMALL_STACK
10750
        mp_int* t1 = NULL;
10751
        mp_int* t2 = NULL;
10752
    #else
10753
        mp_int t1[1], t2[1];
10754
    #endif
10755
        int did_init = 0;
10756
10757
        DECLARE_CURVE_SPECS(3);
10758
        ALLOC_CURVE_SPECS(3, err);
10759
10760
        #ifdef WOLFSSL_SMALL_STACK
10761
        if (err == MP_OKAY) {
10762
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10763
            if (t1 == NULL) {
10764
                err = MEMORY_E;
10765
            }
10766
        }
10767
        if (err == MP_OKAY) {
10768
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10769
            if (t2 == NULL) {
10770
                err = MEMORY_E;
10771
            }
10772
        }
10773
        #endif
10774
        if (err == MP_OKAY) {
10775
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10776
                err = MEMORY_E;
10777
            else
10778
                did_init = 1;
10779
        }
10780
10781
        /* load curve info */
10782
        if (err == MP_OKAY)
10783
            err = wc_ecc_curve_load(key->dp, &curve,
10784
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10785
                 ECC_CURVE_FIELD_BF));
10786
10787
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
10788
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10789
        /* validate prime is prime for custom curves */
10790
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
10791
            int isPrime = MP_NO;
10792
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10793
            if (err == MP_OKAY && isPrime == MP_NO)
10794
                err = MP_VAL;
10795
        }
10796
    #endif
10797
10798
        /* compute x^3 */
10799
        if (err == MP_OKAY)
10800
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10801
        if (err == MP_OKAY)
10802
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10803
10804
        /* compute x^3 + a*x */
10805
        if (err == MP_OKAY)
10806
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10807
        if (err == MP_OKAY)
10808
            err = mp_add(t1, t2, t1);
10809
10810
        /* compute x^3 + a*x + b */
10811
        if (err == MP_OKAY)
10812
            err = mp_add(t1, curve->Bf, t1);
10813
10814
        /* compute sqrt(x^3 + a*x + b) */
10815
        if (err == MP_OKAY)
10816
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10817
10818
        /* adjust y */
10819
        if (err == MP_OKAY) {
10820
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10821
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10822
                err = mp_mod(t2, curve->prime, t2);
10823
            }
10824
            else {
10825
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10826
            }
10827
            if (err == MP_OKAY)
10828
                err = mp_copy(t2, key->pubkey.y);
10829
        }
10830
10831
        if (did_init) {
10832
            mp_clear(t2);
10833
            mp_clear(t1);
10834
        }
10835
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10836
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10837
10838
        wc_ecc_curve_free(curve);
10839
        FREE_CURVE_SPECS();
10840
#else
10841
214
    #ifndef WOLFSSL_SP_NO_256
10842
214
        if (key->dp->id == ECC_SECP256R1) {
10843
57
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
10844
57
                key->pubkey.y);
10845
57
        }
10846
157
        else
10847
157
    #endif
10848
157
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10849
157
        if (key->dp->id == ECC_SM2P256V1) {
10850
47
            sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
10851
47
        }
10852
110
        else
10853
110
    #endif
10854
110
    #ifdef WOLFSSL_SP_384
10855
110
        if (key->dp->id == ECC_SECP384R1) {
10856
69
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
10857
69
                key->pubkey.y);
10858
69
        }
10859
41
        else
10860
41
    #endif
10861
41
    #ifdef WOLFSSL_SP_521
10862
41
        if (key->dp->id == ECC_SECP521R1) {
10863
41
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
10864
41
                key->pubkey.y);
10865
41
        }
10866
0
        else
10867
0
    #endif
10868
0
        {
10869
0
            err = WC_KEY_SIZE_E;
10870
0
        }
10871
214
#endif
10872
214
    }
10873
380
#endif /* HAVE_COMP_KEY */
10874
10875
380
    if (err == MP_OKAY) {
10876
288
    #ifdef HAVE_COMP_KEY
10877
288
        if (compressed == 0)
10878
158
    #endif
10879
158
        {
10880
158
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10881
158
                (word32)keysize);
10882
158
        }
10883
288
    }
10884
380
    if (err == MP_OKAY)
10885
288
        err = mp_set(key->pubkey.z, 1);
10886
10887
#ifdef WOLFSSL_CRYPTOCELL
10888
    if (err == MP_OKAY) {
10889
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
10890
10891
        /* create public key from external key buffer */
10892
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
10893
                                               (byte*)in-1, /* re-adjust */
10894
                                               inLen+1,     /* original input */
10895
                                               &key->ctx.pubKey,
10896
                                               &tempBuff);
10897
10898
        if (err != SA_SILIB_RET_OK){
10899
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
10900
        }
10901
    }
10902
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10903
    if (err == MP_OKAY)
10904
        err = silabs_ecc_import(key, keysize, 1, 0);
10905
#elif defined(WOLFSSL_SE050)
10906
    if (err == MP_OKAY) {
10907
        /* reset key ID, in case used before */
10908
        key->keyId = 0;
10909
        key->keyIdSet = 0;
10910
    }
10911
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10912
    #ifndef HAVE_COMP_KEY
10913
    if (err == MP_OKAY) {
10914
    #else
10915
    if (err == MP_OKAY && !compressed) {
10916
    #endif
10917
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
10918
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
10919
    }
10920
#endif
10921
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10922
    if (err == MP_OKAY)
10923
        err = wc_ecc_check_key(key);
10924
#endif
10925
380
#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
10926
380
     !defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
10927
380
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
10928
380
     !defined(WOLFSSL_CRYPTOCELL) && \
10929
380
     (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
10930
380
       defined(WOLFSSL_IMXRT1170_CAAM))
10931
380
    if (untrusted) {
10932
        /* Only do quick checks. */
10933
0
        if ((err == MP_OKAY) && wc_ecc_point_is_at_infinity(&key->pubkey)) {
10934
0
            err = ECC_INF_E;
10935
0
        }
10936
0
    #ifdef USE_ECC_B_PARAM
10937
0
        if ((err == MP_OKAY) && (key->idx != ECC_CUSTOM_IDX))  {
10938
0
            err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
10939
0
        }
10940
0
    #endif /* USE_ECC_B_PARAM */
10941
0
    }
10942
380
#endif
10943
380
    (void)untrusted;
10944
10945
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
10946
    if (err == MP_OKAY) {
10947
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
10948
    }
10949
#endif
10950
10951
380
    if (err != MP_OKAY) {
10952
92
        mp_clear(key->pubkey.x);
10953
92
        mp_clear(key->pubkey.y);
10954
92
        mp_clear(key->pubkey.z);
10955
92
        mp_clear(key->k);
10956
92
    }
10957
10958
380
    RESTORE_VECTOR_REGISTERS();
10959
10960
380
    return err;
10961
380
}
10962
10963
/* import public ECC key in ANSI X9.63 format */
10964
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
10965
                          int curve_id)
10966
6.31k
{
10967
6.31k
    return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 0);
10968
6.31k
}
10969
10970
WOLFSSL_ABI
10971
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
10972
831
{
10973
831
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
10974
831
}
10975
#endif /* HAVE_ECC_KEY_IMPORT */
10976
10977
#ifdef HAVE_ECC_KEY_EXPORT
10978
10979
/* export ecc key to component form, d is optional if only exporting public
10980
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
10981
 * return MP_OKAY on success */
10982
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
10983
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
10984
0
{
10985
0
    int err = 0;
10986
0
    word32 keySz;
10987
10988
0
    if (key == NULL) {
10989
0
        return BAD_FUNC_ARG;
10990
0
    }
10991
10992
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
10993
0
        return ECC_BAD_ARG_E;
10994
0
    }
10995
0
    keySz = (word32)key->dp->size;
10996
10997
    /* private key, d */
10998
0
    if (d != NULL) {
10999
0
        if (dLen == NULL ||
11000
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
11001
0
            return BAD_FUNC_ARG;
11002
11003
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11004
        /* Hardware cannot export private portion */
11005
        return NOT_COMPILED_IN;
11006
    #else
11007
    #if defined(WOLFSSL_SECO_CAAM)
11008
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
11009
            /* Hardware cannot export private portion */
11010
            WOLFSSL_MSG("Can not export private key from HSM");
11011
            return NOT_COMPILED_IN;
11012
        }
11013
    #endif
11014
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11015
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11016
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11017
                *dLen = keySz + WC_CAAM_MAC_SZ;
11018
                return BUFFER_E;
11019
            }
11020
11021
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
11022
                encType);
11023
            *dLen = keySz + WC_CAAM_MAC_SZ;
11024
        }
11025
        else if (encType == WC_TYPE_BLACK_KEY &&
11026
                key->blackKey != CAAM_BLACK_KEY_ECB &&
11027
                key->blackKey > 0) {
11028
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11029
                *dLen = keySz + WC_CAAM_MAC_SZ;
11030
                return BUFFER_E;
11031
            }
11032
11033
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11034
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11035
                    return WC_HW_E;
11036
            }
11037
11038
            *dLen = keySz + WC_CAAM_MAC_SZ;
11039
        }
11040
        else
11041
    #endif
11042
0
        {
11043
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11044
0
            if (err != MP_OKAY)
11045
0
                return err;
11046
0
        }
11047
0
    #endif
11048
0
    }
11049
11050
    /* public x component */
11051
0
    if (qx != NULL) {
11052
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11053
0
            return BAD_FUNC_ARG;
11054
11055
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11056
0
        if (err != MP_OKAY)
11057
0
            return err;
11058
0
    }
11059
11060
    /* public y component */
11061
0
    if (qy != NULL) {
11062
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11063
0
            return BAD_FUNC_ARG;
11064
11065
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11066
0
        if (err != MP_OKAY)
11067
0
            return err;
11068
0
    }
11069
11070
0
    return err;
11071
0
}
11072
11073
11074
/* export ecc private key only raw, outLen is in/out size as unsigned bin
11075
   return MP_OKAY on success */
11076
WOLFSSL_ABI
11077
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11078
0
{
11079
0
    if (out == NULL || outLen == NULL) {
11080
0
        return BAD_FUNC_ARG;
11081
0
    }
11082
11083
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11084
    /* check if black key in secure memory */
11085
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11086
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11087
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11088
            WC_TYPE_BLACK_KEY);
11089
    }
11090
#endif
11091
11092
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11093
0
        WC_TYPE_UNSIGNED_BIN);
11094
0
}
11095
11096
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11097
 * return MP_OKAY on success, negative on error */
11098
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11099
                             byte* qy, word32* qyLen)
11100
0
{
11101
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11102
0
        return BAD_FUNC_ARG;
11103
0
    }
11104
11105
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11106
0
        WC_TYPE_UNSIGNED_BIN);
11107
0
}
11108
11109
/* export ecc key to raw elements including public (Qx,Qy) and
11110
 *   private (d) as unsigned bin
11111
 * return MP_OKAY on success, negative on error */
11112
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11113
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11114
0
{
11115
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11116
0
        WC_TYPE_UNSIGNED_BIN);
11117
0
}
11118
11119
#endif /* HAVE_ECC_KEY_EXPORT */
11120
11121
#ifdef HAVE_ECC_KEY_IMPORT
11122
/* import private key, public part optional if (pub) passed as NULL */
11123
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11124
                                 const byte* pub, word32 pubSz, ecc_key* key,
11125
                                 int curve_id)
11126
8.55k
{
11127
8.55k
    int ret;
11128
#ifdef WOLFSSL_CRYPTOCELL
11129
    const CRYS_ECPKI_Domain_t* pDomain;
11130
#endif
11131
8.55k
    if (key == NULL || priv == NULL)
11132
107
        return BAD_FUNC_ARG;
11133
11134
    /* public optional, NULL if only importing private */
11135
8.44k
    if (pub != NULL) {
11136
0
    #ifndef NO_ASN
11137
0
        word32 idx = 0;
11138
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
11139
0
        if (ret < 0)
11140
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11141
0
        key->type = ECC_PRIVATEKEY;
11142
    #else
11143
        (void)pubSz;
11144
        ret = NOT_COMPILED_IN;
11145
    #endif
11146
0
    }
11147
8.44k
    else {
11148
        /* make sure required variables are reset */
11149
8.44k
        wc_ecc_reset(key);
11150
11151
        /* set key size */
11152
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11153
         *       on created keys or signatures */
11154
8.44k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11155
8.44k
        key->type = ECC_PRIVATEKEY_ONLY;
11156
8.44k
    }
11157
11158
8.44k
    if (ret != 0)
11159
868
        return ret;
11160
11161
#ifdef WOLFSSL_CRYPTOCELL
11162
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11163
    /* import private key - priv checked for NULL at top */
11164
    if (priv[0] != '\0') {
11165
11166
        /* Create private key from external key buffer*/
11167
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11168
                                      priv,
11169
                                      privSz,
11170
                                      &key->ctx.privKey);
11171
11172
        if (ret != SA_SILIB_RET_OK) {
11173
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11174
            return ret;
11175
        }
11176
11177
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11178
    #ifdef WOLFSSL_ECC_BLIND_K
11179
        if (ret == MP_OKAY) {
11180
            err = ecc_blind_k_rng(key, NULL);
11181
        }
11182
    #endif
11183
    }
11184
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11185
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11186
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11187
        int part = caamFindUnusedPartition();
11188
        if (part >= 0) {
11189
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11190
            if (vaddr == 0) {
11191
                WOLFSSL_MSG("Unable to get partition");
11192
                return MEMORY_E;
11193
            }
11194
11195
            key->partNum  = part;
11196
            key->blackKey = (word32)vaddr;
11197
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11198
                return WC_HW_E;
11199
11200
            if (pub != NULL) {
11201
                /* +1 to account for x963 compressed bit */
11202
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11203
                    return WC_HW_E;
11204
                key->securePubKey = (word32)vaddr + privSz;
11205
            }
11206
        }
11207
        else {
11208
            WOLFSSL_MSG("Unable to find an unused partition");
11209
            return MEMORY_E;
11210
        }
11211
    #else
11212
        key->blackKey = CAAM_BLACK_KEY_CCM;
11213
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11214
    #ifdef WOLFSSL_ECC_BLIND_K
11215
        if (ret == MP_OKAY) {
11216
            err = ecc_blind_k_rng(key, NULL);
11217
        }
11218
    #endif
11219
    #endif
11220
    }
11221
    else {
11222
        key->blackKey = 0;
11223
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11224
    #ifdef WOLFSSL_ECC_BLIND_K
11225
        if (ret == MP_OKAY) {
11226
            err = ecc_blind_k_rng(key, NULL);
11227
        }
11228
    #endif
11229
11230
        /* If using AES-ECB encrypted black keys check here if key is valid,
11231
         * if not valid than assume is an encrypted key. A public key is needed
11232
         * for testing validity. */
11233
        if (key->devId == WOLFSSL_CAAM_DEVID && (
11234
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11235
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11236
            if ((pub != NULL) && (ret == MP_OKAY) &&
11237
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11238
                key->blackKey = CAAM_BLACK_KEY_ECB;
11239
            }
11240
            else if ((pub == NULL) && (ret == MP_OKAY)) {
11241
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11242
                key->blackKey = CAAM_BLACK_KEY_ECB;
11243
            }
11244
            else {
11245
                WOLFSSL_MSG("Importing key that is not a black key!");
11246
            }
11247
        }
11248
    }
11249
#else
11250
11251
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11252
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11253
#endif
11254
11255
7.57k
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11256
#ifdef HAVE_WOLF_BIGINT
11257
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11258
                                                                 privSz) != 0) {
11259
        mp_clear(key->k);
11260
        ret = ASN_GETINT_E;
11261
    }
11262
#endif /* HAVE_WOLF_BIGINT */
11263
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11264
    if (ret == 0) {
11265
        WC_DECLARE_VAR(order, mp_int, 1, 0);
11266
11267
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
11268
            ret=MEMORY_E);
11269
11270
        if (ret == 0) {
11271
            ret = mp_init(order);
11272
        }
11273
        if (ret == 0) {
11274
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11275
        }
11276
    #ifdef WOLFSSL_SM2
11277
        /* SM2 curve: private key must be less than order-1. */
11278
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11279
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11280
            ret = mp_sub_d(order, 1, order);
11281
        }
11282
    #endif
11283
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11284
            ret = ECC_PRIV_KEY_E;
11285
        }
11286
11287
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
11288
    }
11289
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11290
#ifdef WOLFSSL_ECC_BLIND_K
11291
    if (ret == 0) {
11292
        ret = ecc_blind_k_rng(key, NULL);
11293
    }
11294
#endif
11295
11296
7.57k
#endif /* WOLFSSL_CRYPTOCELL */
11297
11298
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11299
    if ((pub != NULL) && (ret == MP_OKAY))
11300
        /* public key needed to perform key validation */
11301
        ret = _ecc_validate_public_key(key, 1, 1);
11302
11303
#endif
11304
11305
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11306
    RESTORE_VECTOR_REGISTERS();
11307
#endif
11308
11309
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11310
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11311
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11312
    }
11313
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11314
    if (ret == 0) {
11315
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11316
    }
11317
#endif
11318
11319
7.57k
    return ret;
11320
8.44k
}
11321
11322
/* ecc private key import, public key in ANSI X9.63 format, private raw */
11323
WOLFSSL_ABI
11324
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11325
                           word32 pubSz, ecc_key* key)
11326
43
{
11327
43
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11328
43
                                                                ECC_CURVE_DEF);
11329
43
}
11330
#endif /* HAVE_ECC_KEY_IMPORT */
11331
11332
#ifndef NO_ASN
11333
/**
11334
   Convert ECC R,S to signature
11335
   r       R component of signature
11336
   s       S component of signature
11337
   out     DER-encoded ECDSA signature
11338
   outlen  [in/out] output buffer size, output signature size
11339
   return  MP_OKAY on success
11340
*/
11341
WOLFSSL_ABI
11342
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11343
2.54k
{
11344
2.54k
    int err;
11345
2.54k
#ifdef WOLFSSL_SMALL_STACK
11346
2.54k
    mp_int* rtmp = NULL;
11347
2.54k
    mp_int* stmp = NULL;
11348
#else
11349
    mp_int  rtmp[1];
11350
    mp_int  stmp[1];
11351
#endif
11352
11353
2.54k
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11354
8
        return ECC_BAD_ARG_E;
11355
11356
2.53k
#ifdef WOLFSSL_SMALL_STACK
11357
2.53k
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11358
2.53k
    if (rtmp == NULL)
11359
5
        return MEMORY_E;
11360
2.52k
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11361
2.52k
    if (stmp == NULL) {
11362
4
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11363
4
        return MEMORY_E;
11364
4
    }
11365
2.52k
#endif
11366
11367
2.52k
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11368
2.52k
    if (err != MP_OKAY) {
11369
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11370
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11371
0
        return err;
11372
0
    }
11373
11374
2.52k
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11375
2.52k
    if (err == MP_OKAY)
11376
2.49k
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11377
11378
2.52k
    if (err == MP_OKAY) {
11379
2.49k
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11380
38
            err = MP_ZERO_E;
11381
2.49k
    }
11382
2.52k
    if (err == MP_OKAY) {
11383
2.45k
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11384
0
            err = MP_READ_E;
11385
0
        }
11386
2.45k
    }
11387
11388
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11389
2.52k
    if (err == MP_OKAY)
11390
2.45k
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11391
11392
2.52k
    mp_clear(rtmp);
11393
2.52k
    mp_clear(stmp);
11394
2.52k
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11395
2.52k
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11396
11397
2.52k
    return err;
11398
2.52k
}
11399
11400
/**
11401
   Convert ECC R,S raw unsigned bin to signature
11402
   r       R component of signature
11403
   rSz     R size
11404
   s       S component of signature
11405
   sSz     S size
11406
   out     DER-encoded ECDSA signature
11407
   outlen  [in/out] output buffer size, output signature size
11408
   return  MP_OKAY on success
11409
*/
11410
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11411
    byte* out, word32* outlen)
11412
354
{
11413
354
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11414
2
        return ECC_BAD_ARG_E;
11415
11416
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11417
352
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11418
354
}
11419
11420
/**
11421
   Convert ECC signature to R,S
11422
   sig     DER-encoded ECDSA signature
11423
   sigLen  length of signature in octets
11424
   r       R component of signature
11425
   rLen    [in/out] output "r" buffer size, output "r" size
11426
   s       S component of signature
11427
   sLen    [in/out] output "s" buffer size, output "s" size
11428
   return  MP_OKAY on success, negative on error
11429
*/
11430
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11431
                     byte* s, word32* sLen)
11432
0
{
11433
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11434
0
        return ECC_BAD_ARG_E;
11435
11436
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11437
0
}
11438
#endif /* !NO_ASN */
11439
11440
#ifdef HAVE_ECC_KEY_IMPORT
11441
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
11442
          const char* qy, const char* d, int curve_id, int encType)
11443
5.62k
{
11444
5.62k
    int err = MP_OKAY;
11445
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11446
    !defined(WOLFSSL_ATECC608A)
11447
    const CRYS_ECPKI_Domain_t* pDomain;
11448
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11449
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11450
#endif
11451
11452
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11453
    defined(WOLFSSL_CRYPTOCELL)
11454
    word32 keySz = 0;
11455
#endif
11456
11457
    /* if d is NULL, only import as public key using Qx,Qy */
11458
5.62k
    if (key == NULL || qx == NULL || qy == NULL) {
11459
0
        return BAD_FUNC_ARG;
11460
0
    }
11461
11462
    /* make sure required variables are reset */
11463
5.62k
    wc_ecc_reset(key);
11464
11465
    /* set curve type and index */
11466
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11467
     *       on created keys or signatures */
11468
5.62k
    err = wc_ecc_set_curve(key, 0, curve_id);
11469
5.62k
    if (err != 0) {
11470
0
        return err;
11471
0
    }
11472
11473
    /* init key */
11474
#ifdef ALT_ECC_SIZE
11475
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11476
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11477
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11478
    alt_fp_init(key->pubkey.x);
11479
    alt_fp_init(key->pubkey.y);
11480
    alt_fp_init(key->pubkey.z);
11481
    key->k = (mp_int*)key->ka;
11482
    alt_fp_init(key->k);
11483
#ifdef WOLFSSL_ECC_BLIND_K
11484
    key->kb = (mp_int*)key->kba;
11485
    key->ku = (mp_int*)key->kua;
11486
    alt_fp_init(key->kb);
11487
    alt_fp_init(key->ku);
11488
#endif
11489
#else
11490
5.62k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11491
5.62k
#ifndef WOLFSSL_ECC_BLIND_K
11492
5.62k
                                                                      NULL, NULL
11493
#else
11494
                                                                key->kb, key->ku
11495
#endif
11496
5.62k
                        );
11497
5.62k
#endif
11498
5.62k
    if (err != MP_OKAY)
11499
0
        return MEMORY_E;
11500
#ifdef WOLFSSL_ECC_BLIND_K
11501
    mp_forcezero(key->kb);
11502
#endif
11503
11504
    /* read Qx */
11505
5.62k
    if (err == MP_OKAY) {
11506
5.62k
        if (encType == WC_TYPE_HEX_STR)
11507
5.62k
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
11508
0
        else
11509
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
11510
0
                (word32)key->dp->size);
11511
11512
5.62k
        if (mp_isneg(key->pubkey.x)) {
11513
0
            WOLFSSL_MSG("Invalid Qx");
11514
0
            err = BAD_FUNC_ARG;
11515
0
        }
11516
5.62k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11517
50
            err = BAD_FUNC_ARG;
11518
50
        }
11519
5.62k
    }
11520
11521
    /* read Qy */
11522
5.62k
    if (err == MP_OKAY) {
11523
5.52k
        if (encType == WC_TYPE_HEX_STR)
11524
5.52k
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
11525
0
        else
11526
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
11527
0
                (word32)key->dp->size);
11528
11529
5.52k
        if (mp_isneg(key->pubkey.y)) {
11530
0
            WOLFSSL_MSG("Invalid Qy");
11531
0
            err = BAD_FUNC_ARG;
11532
0
        }
11533
5.52k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11534
48
            err = BAD_FUNC_ARG;
11535
48
        }
11536
5.52k
    }
11537
11538
5.62k
    if (err == MP_OKAY) {
11539
5.44k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11540
96
            WOLFSSL_MSG("Invalid Qx and Qy");
11541
96
            err = ECC_INF_E;
11542
96
        }
11543
5.44k
    }
11544
11545
5.62k
    if (err == MP_OKAY)
11546
5.34k
        err = mp_set(key->pubkey.z, 1);
11547
11548
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11549
    /* For SECP256R1 only save raw public key for hardware */
11550
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
11551
        keySz = key->dp->size;
11552
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11553
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11554
        if (err == MP_OKAY)
11555
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
11556
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11557
    }
11558
#elif defined(WOLFSSL_CRYPTOCELL)
11559
    if (err == MP_OKAY) {
11560
        keyRaw[0] = ECC_POINT_UNCOMP;
11561
        keySz = (word32)key->dp->size;
11562
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
11563
            WC_TYPE_UNSIGNED_BIN);
11564
        if (err == MP_OKAY) {
11565
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
11566
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11567
        }
11568
11569
        if (err == MP_OKAY) {
11570
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11571
11572
            /* create public key from external key buffer */
11573
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11574
                                                   keyRaw,
11575
                                                   keySz*2 + 1,
11576
                                                   &key->ctx.pubKey,
11577
                                                   &tempBuff);
11578
        }
11579
11580
        if (err != SA_SILIB_RET_OK){
11581
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11582
            return err;
11583
        }
11584
    }
11585
#elif defined(WOLFSSL_KCAPI_ECC)
11586
    if (err == MP_OKAY) {
11587
        word32 keySz = key->dp->size;
11588
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11589
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11590
        if (err == MP_OKAY) {
11591
            err = wc_export_int(key->pubkey.y,
11592
                &key->pubkey_raw[keySz], &keySz, keySz,
11593
                WC_TYPE_UNSIGNED_BIN);
11594
        }
11595
    }
11596
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11597
    if (err == MP_OKAY) {
11598
        const word32 keySize = key->dp->size;
11599
        word32 bufSize = sizeof(key->keyRaw);
11600
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
11601
                            WC_TYPE_UNSIGNED_BIN);
11602
        if (err == MP_OKAY) {
11603
            const word32 offset = bufSize;
11604
            bufSize = sizeof(key->keyRaw) - offset;
11605
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
11606
                                keySize, WC_TYPE_UNSIGNED_BIN);
11607
        }
11608
        if (err == MP_OKAY) {
11609
            mp_reverse(key->keyRaw, keySize);
11610
            mp_reverse(&key->keyRaw[keySize], keySize);
11611
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
11612
                                           keySize * 2);
11613
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
11614
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
11615
                                              xil_curve_type[key->dp->id],
11616
                                              XIL_CAST_U64(key->keyRaw));
11617
            if (err) {
11618
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
11619
                err = WC_HW_E;
11620
            }
11621
#endif
11622
        }
11623
    }
11624
#endif
11625
11626
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11627
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11628
#endif
11629
11630
    /* import private key */
11631
5.62k
    if (err == MP_OKAY) {
11632
5.34k
        if (d != NULL) {
11633
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11634
            /* Hardware doesn't support loading private key */
11635
            err = NOT_COMPILED_IN;
11636
11637
        #elif defined(WOLFSSL_CRYPTOCELL)
11638
            key->type = ECC_PRIVATEKEY;
11639
11640
            if (encType == WC_TYPE_HEX_STR)
11641
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11642
            else
11643
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
11644
                    key->dp->size);
11645
            if (err == MP_OKAY) {
11646
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
11647
                    WC_TYPE_UNSIGNED_BIN);
11648
            }
11649
        #ifdef WOLFSSL_ECC_BLIND_K
11650
            if (err == 0) {
11651
                err = ecc_blind_k_rng(key, NULL);
11652
            }
11653
        #endif
11654
11655
            if (err == MP_OKAY) {
11656
                /* Create private key from external key buffer*/
11657
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
11658
                                              keyRaw,
11659
                                              keySz,
11660
                                              &key->ctx.privKey);
11661
11662
                if (err != SA_SILIB_RET_OK){
11663
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11664
                    return err;
11665
                }
11666
            }
11667
11668
        #else
11669
0
            key->type = ECC_PRIVATEKEY;
11670
0
            if (encType == WC_TYPE_HEX_STR)
11671
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11672
0
            else {
11673
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11674
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11675
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11676
                    key->dp->size + WC_CAAM_MAC_SZ);
11677
                }
11678
                else
11679
            #endif /* WOLFSSL_QNX_CAAM */
11680
0
                {
11681
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11682
0
                        (word32)key->dp->size);
11683
0
                }
11684
0
            }
11685
        #ifdef WOLFSSL_ECC_BLIND_K
11686
            if (err == 0) {
11687
                err = ecc_blind_k_rng(key, NULL);
11688
            }
11689
        #endif
11690
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11691
            if (err == MP_OKAY) {
11692
                const word32 key_size = key->dp->size;
11693
                word32 buf_size = key_size;
11694
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
11695
                                    WC_TYPE_UNSIGNED_BIN);
11696
                mp_reverse(key->privKey, key_size);
11697
            }
11698
#endif
11699
11700
0
        #endif /* #else-case of custom HW-specific implementations */
11701
0
            if (mp_iszero(key->k) || mp_isneg(key->k)) {
11702
0
                WOLFSSL_MSG("Invalid private key");
11703
0
                err = BAD_FUNC_ARG;
11704
0
            }
11705
5.34k
        } else {
11706
5.34k
            key->type = ECC_PUBLICKEY;
11707
5.34k
        }
11708
5.34k
    }
11709
11710
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11711
    if (err == MP_OKAY) {
11712
        err = wc_ecc_check_key(key);
11713
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
11714
                                  mp_iszero(key->pubkey.y))) {
11715
            err = BAD_FUNC_ARG;
11716
        }
11717
    }
11718
#endif
11719
11720
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11721
    RESTORE_VECTOR_REGISTERS();
11722
#endif
11723
11724
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11725
    if (err == MP_OKAY) {
11726
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11727
    }
11728
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11729
    if (err == MP_OKAY) {
11730
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
11731
    }
11732
#endif
11733
11734
5.62k
    if (err != MP_OKAY) {
11735
281
        mp_clear(key->pubkey.x);
11736
281
        mp_clear(key->pubkey.y);
11737
281
        mp_clear(key->pubkey.z);
11738
281
        mp_clear(key->k);
11739
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11740
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11741
#endif
11742
281
    }
11743
11744
5.62k
    return err;
11745
5.62k
}
11746
11747
/**
11748
   Import raw ECC key
11749
   key       The destination ecc_key structure
11750
   qx        x component of the public key, as ASCII hex string
11751
   qy        y component of the public key, as ASCII hex string
11752
   d         private key, as ASCII hex string, optional if importing public
11753
             key only
11754
   curve_id  The id of the curve.
11755
   @return    MP_OKAY on success
11756
*/
11757
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
11758
                   const char* d, int curve_id)
11759
0
{
11760
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
11761
0
        WC_TYPE_HEX_STR);
11762
0
}
11763
11764
/* Import x, y and optional private (d) as unsigned binary */
11765
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
11766
                   const byte* d, int curve_id)
11767
0
{
11768
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
11769
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
11770
0
}
11771
11772
/**
11773
   Import raw ECC key
11774
   key       The destination ecc_key structure
11775
   qx        x component of the public key, as ASCII hex string
11776
   qy        y component of the public key, as ASCII hex string
11777
   d         private key, as ASCII hex string, optional if importing public
11778
             key only
11779
   curveName ECC curve name, from ecc_sets[]
11780
   return    MP_OKAY on success
11781
*/
11782
WOLFSSL_ABI
11783
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
11784
                   const char* d, const char* curveName)
11785
12.0k
{
11786
12.0k
    int err, x;
11787
11788
    /* if d is NULL, only import as public key using Qx,Qy */
11789
12.0k
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
11790
0
        return BAD_FUNC_ARG;
11791
0
    }
11792
11793
    /* set curve type and index */
11794
142k
    for (x = 0; ecc_sets[x].size != 0; x++) {
11795
142k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11796
142k
                     XSTRLEN(curveName)) == 0) {
11797
12.0k
            break;
11798
12.0k
        }
11799
142k
    }
11800
11801
12.0k
    if (ecc_sets[x].size == 0) {
11802
0
        WOLFSSL_MSG("ecc_set curve name not found");
11803
0
        err = ASN_PARSE_E;
11804
12.0k
    } else {
11805
12.0k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
11806
12.0k
            WC_TYPE_HEX_STR);
11807
12.0k
    }
11808
11809
0
    return err;
11810
12.0k
}
11811
#endif /* HAVE_ECC_KEY_IMPORT */
11812
11813
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
11814
/* public key size in octets */
11815
static int ecc_public_key_size(ecc_key* key, word32* sz)
11816
358
{
11817
358
    if (key == NULL || key->dp == NULL)
11818
0
        return BAD_FUNC_ARG;
11819
11820
    /* 'Uncompressed' | x | y */
11821
358
    *sz = 1 + 2 * (word32)key->dp->size;
11822
11823
358
    return 0;
11824
358
}
11825
#endif
11826
11827
/* key size in octets */
11828
WOLFSSL_ABI
11829
int wc_ecc_size(ecc_key* key)
11830
337
{
11831
337
    if (key == NULL || key->dp == NULL)
11832
0
        return 0;
11833
11834
337
    return key->dp->size;
11835
337
}
11836
11837
/* maximum signature size based on key size */
11838
WOLFSSL_ABI
11839
int wc_ecc_sig_size_calc(int sz)
11840
0
{
11841
0
    int maxSigSz = 0;
11842
11843
    /* calculate based on key bits */
11844
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
11845
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
11846
11847
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11848
0
    if (maxSigSz < (128 + 2)) {
11849
0
        maxSigSz -= 1;
11850
0
    }
11851
11852
0
    return maxSigSz;
11853
0
}
11854
11855
/* maximum signature size based on actual key curve */
11856
WOLFSSL_ABI
11857
int wc_ecc_sig_size(const ecc_key* key)
11858
704
{
11859
704
    int maxSigSz;
11860
704
    int orderBits, keySz;
11861
11862
704
    if (key == NULL || key->dp == NULL)
11863
0
        return 0;
11864
11865
    /* the signature r and s will always be less than order */
11866
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
11867
        extra byte for r and s, so add 2 */
11868
704
    keySz = key->dp->size;
11869
704
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11870
704
    if (orderBits > keySz * 8) {
11871
0
        keySz = (orderBits + 7) >> 3;
11872
0
    }
11873
    /* maximum possible signature header size is 7 bytes */
11874
704
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11875
704
    if ((orderBits % 8) == 0) {
11876
        /* MSB can be set, so add 2 */
11877
388
        maxSigSz += ECC_MAX_PAD_SZ;
11878
388
    }
11879
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11880
704
    if (maxSigSz < (128 + 2)) {
11881
388
        maxSigSz -= 1;
11882
388
    }
11883
11884
704
    return maxSigSz;
11885
704
}
11886
11887
11888
#ifdef FP_ECC
11889
11890
/* fixed point ECC cache */
11891
/* number of entries in the cache */
11892
#ifndef FP_ENTRIES
11893
    #define FP_ENTRIES 15
11894
#endif
11895
11896
/* number of bits in LUT */
11897
#ifndef FP_LUT
11898
    #define FP_LUT     8U
11899
#endif
11900
11901
#ifdef ECC_SHAMIR
11902
    /* Sharmir requires a bigger LUT, TAO */
11903
    #if (FP_LUT > 12) || (FP_LUT < 4)
11904
        #error FP_LUT must be between 4 and 12 inclusively
11905
    #endif
11906
#else
11907
    #if (FP_LUT > 12) || (FP_LUT < 2)
11908
        #error FP_LUT must be between 2 and 12 inclusively
11909
    #endif
11910
#endif
11911
11912
11913
#if !defined(WOLFSSL_SP_MATH)
11914
11915
/** Our FP cache */
11916
typedef struct {
11917
   ecc_point* g;               /* cached COPY of base point */
11918
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
11919
   int        LUT_set;         /* flag to determine if the LUT has been computed */
11920
   mp_int     mu;              /* copy of the montgomery constant */
11921
   int        lru_count;       /* amount of times this entry has been used */
11922
   int        lock;            /* flag to indicate cache eviction */
11923
                               /* permitted (0) or not (1) */
11924
} fp_cache_t;
11925
11926
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
11927
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
11928
11929
#ifndef HAVE_THREAD_LS
11930
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
11931
#ifndef WOLFSSL_MUTEX_INITIALIZER
11932
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
11933
#endif
11934
#endif /* HAVE_THREAD_LS */
11935
11936
/* simple table to help direct the generation of the LUT */
11937
static const struct {
11938
   int ham, terma, termb;
11939
} lut_orders[] = {
11940
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
11941
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
11942
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
11943
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
11944
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
11945
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
11946
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
11947
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
11948
#if FP_LUT > 6
11949
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
11950
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
11951
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
11952
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
11953
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
11954
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
11955
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
11956
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
11957
#if FP_LUT > 7
11958
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
11959
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
11960
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
11961
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
11962
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
11963
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
11964
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
11965
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
11966
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
11967
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
11968
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
11969
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
11970
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
11971
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
11972
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
11973
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
11974
#if FP_LUT > 8
11975
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
11976
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
11977
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
11978
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
11979
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
11980
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
11981
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
11982
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
11983
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
11984
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
11985
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
11986
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
11987
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
11988
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
11989
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
11990
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
11991
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
11992
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
11993
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
11994
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
11995
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
11996
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
11997
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
11998
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
11999
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
12000
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
12001
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
12002
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
12003
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
12004
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
12005
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
12006
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
12007
#if FP_LUT > 9
12008
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
12009
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
12010
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
12011
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
12012
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
12013
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
12014
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
12015
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
12016
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
12017
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
12018
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
12019
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
12020
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
12021
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
12022
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
12023
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
12024
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
12025
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
12026
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
12027
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
12028
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12029
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12030
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12031
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12032
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12033
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12034
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12035
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12036
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12037
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12038
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12039
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12040
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12041
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12042
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12043
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12044
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12045
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12046
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12047
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12048
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12049
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12050
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12051
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12052
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12053
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12054
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12055
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12056
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12057
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12058
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12059
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12060
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12061
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12062
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12063
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12064
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12065
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12066
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12067
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12068
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12069
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12070
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12071
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12072
#if FP_LUT > 10
12073
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12074
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12075
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12076
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12077
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12078
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12079
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12080
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12081
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12082
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12083
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12084
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12085
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12086
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12087
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12088
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12089
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12090
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12091
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12092
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12093
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12094
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12095
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12096
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12097
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12098
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12099
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12100
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12101
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12102
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12103
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12104
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12105
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12106
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12107
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12108
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12109
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12110
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12111
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12112
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12113
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12114
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12115
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12116
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12117
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12118
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12119
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12120
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12121
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12122
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12123
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12124
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12125
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12126
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12127
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12128
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12129
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12130
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12131
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12132
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12133
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12134
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12135
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12136
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12137
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12138
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12139
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12140
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12141
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12142
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12143
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12144
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12145
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12146
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12147
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12148
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12149
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12150
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12151
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12152
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12153
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12154
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12155
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12156
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12157
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12158
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12159
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12160
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12161
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12162
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12163
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12164
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12165
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12166
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12167
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12168
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12169
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12170
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12171
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12172
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12173
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12174
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12175
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12176
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12177
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12178
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12179
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12180
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12181
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12182
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12183
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12184
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12185
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12186
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12187
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12188
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12189
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12190
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12191
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12192
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12193
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12194
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12195
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12196
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12197
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12198
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12199
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12200
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12201
#if FP_LUT > 11
12202
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12203
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12204
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12205
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12206
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12207
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12208
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12209
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12210
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12211
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12212
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12213
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12214
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12215
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12216
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12217
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12218
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12219
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12220
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12221
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12222
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12223
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12224
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12225
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12226
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12227
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12228
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12229
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12230
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12231
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12232
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12233
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12234
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12235
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12236
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12237
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12238
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12239
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12240
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12241
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12242
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12243
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12244
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12245
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12246
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12247
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12248
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12249
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12250
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12251
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12252
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12253
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12254
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12255
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12256
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12257
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12258
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12259
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12260
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12261
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12262
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12263
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12264
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12265
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12266
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12267
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12268
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12269
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12270
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12271
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12272
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12273
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12274
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12275
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12276
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12277
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12278
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12279
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12280
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12281
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12282
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12283
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12284
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12285
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12286
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12287
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12288
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12289
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12290
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12291
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12292
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12293
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12294
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12295
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12296
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12297
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12298
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12299
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12300
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12301
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12302
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12303
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12304
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12305
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12306
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12307
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12308
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12309
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12310
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12311
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12312
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12313
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12314
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12315
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12316
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12317
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12318
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12319
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12320
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12321
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12322
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12323
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12324
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12325
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12326
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12327
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12328
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12329
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12330
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12331
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12332
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12333
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12334
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12335
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12336
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12337
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12338
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12339
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12340
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12341
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12342
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12343
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12344
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12345
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12346
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12347
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12348
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12349
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12350
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12351
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12352
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12353
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12354
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12355
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12356
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12357
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12358
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12359
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12360
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12361
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12362
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12363
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12364
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12365
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12366
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12367
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12368
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12369
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
12370
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
12371
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
12372
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
12373
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
12374
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
12375
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
12376
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
12377
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
12378
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
12379
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
12380
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
12381
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
12382
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
12383
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
12384
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
12385
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
12386
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
12387
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
12388
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
12389
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
12390
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
12391
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
12392
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
12393
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
12394
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
12395
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
12396
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
12397
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
12398
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
12399
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
12400
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
12401
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
12402
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
12403
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
12404
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
12405
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
12406
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
12407
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
12408
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
12409
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
12410
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
12411
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
12412
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
12413
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
12414
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
12415
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
12416
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
12417
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
12418
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
12419
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
12420
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
12421
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
12422
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
12423
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
12424
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
12425
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
12426
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
12427
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
12428
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
12429
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
12430
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
12431
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
12432
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
12433
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
12434
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
12435
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
12436
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
12437
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
12438
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
12439
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
12440
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
12441
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
12442
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
12443
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
12444
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
12445
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
12446
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
12447
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
12448
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
12449
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
12450
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
12451
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
12452
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
12453
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
12454
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
12455
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
12456
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
12457
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
12458
#endif
12459
#endif
12460
#endif
12461
#endif
12462
#endif
12463
#endif
12464
};
12465
12466
12467
/* find a hole and free as required, return -1 if no hole found */
12468
static int find_hole(void)
12469
{
12470
#ifdef WOLFSSL_NO_MALLOC
12471
   return -1;
12472
#else
12473
   int      x, y, z;
12474
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
12475
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
12476
          z = x;
12477
          y = fp_cache[x].lru_count;
12478
       }
12479
   }
12480
12481
   /* decrease all */
12482
   for (x = 0; x < FP_ENTRIES; x++) {
12483
      if (fp_cache[x].lru_count > 3) {
12484
         --(fp_cache[x].lru_count);
12485
      }
12486
   }
12487
12488
   /* free entry z */
12489
   if (z >= 0 && fp_cache[z].g) {
12490
      mp_clear(&fp_cache[z].mu);
12491
      wc_ecc_del_point(fp_cache[z].g);
12492
      fp_cache[z].g  = NULL;
12493
      for (x = 0; x < (1<<FP_LUT); x++) {
12494
         wc_ecc_del_point(fp_cache[z].LUT[x]);
12495
         fp_cache[z].LUT[x] = NULL;
12496
      }
12497
      fp_cache[z].LUT_set = 0;
12498
      fp_cache[z].lru_count = 0;
12499
   }
12500
   return z;
12501
#endif /* !WOLFSSL_NO_MALLOC */
12502
}
12503
12504
/* determine if a base is already in the cache and if so, where */
12505
static int find_base(ecc_point* g)
12506
{
12507
   int x;
12508
   for (x = 0; x < FP_ENTRIES; x++) {
12509
      if (fp_cache[x].g != NULL &&
12510
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
12511
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
12512
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
12513
         break;
12514
      }
12515
   }
12516
   if (x == FP_ENTRIES) {
12517
      x = -1;
12518
   }
12519
   return x;
12520
}
12521
12522
/* add a new base to the cache */
12523
static int add_entry(int idx, ecc_point *g)
12524
{
12525
   unsigned x, y;
12526
12527
   /* allocate base and LUT */
12528
   fp_cache[idx].g = wc_ecc_new_point();
12529
   if (fp_cache[idx].g == NULL) {
12530
      return MP_MEM;
12531
   }
12532
12533
   /* copy x and y */
12534
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
12535
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
12536
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
12537
      wc_ecc_del_point(fp_cache[idx].g);
12538
      fp_cache[idx].g = NULL;
12539
      return MP_MEM;
12540
   }
12541
12542
   for (x = 0; x < (1U<<FP_LUT); x++) {
12543
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
12544
      if (fp_cache[idx].LUT[x] == NULL) {
12545
         for (y = 0; y < x; y++) {
12546
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
12547
            fp_cache[idx].LUT[y] = NULL;
12548
         }
12549
         wc_ecc_del_point(fp_cache[idx].g);
12550
         fp_cache[idx].g         = NULL;
12551
         fp_cache[idx].lru_count = 0;
12552
         return MP_MEM;
12553
      }
12554
   }
12555
12556
   fp_cache[idx].LUT_set   = 0;
12557
   fp_cache[idx].lru_count = 0;
12558
12559
   return MP_OKAY;
12560
}
12561
#endif
12562
12563
#if !defined(WOLFSSL_SP_MATH)
12564
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
12565
 *
12566
 * The algorithm builds patterns in increasing bit order by first making all
12567
 * single bit input patterns, then all two bit input patterns and so on
12568
 */
12569
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
12570
    mp_int* mu)
12571
{
12572
   int err;
12573
   unsigned x, y, bitlen, lut_gap;
12574
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
12575
   int infinity;
12576
12577
#ifdef WOLFSSL_SMALL_STACK
12578
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12579
       return MEMORY_E;
12580
#endif
12581
12582
   err = mp_init(tmp);
12583
   if (err != MP_OKAY) {
12584
       err = MP_MEM;
12585
       goto errout;
12586
   }
12587
12588
   /* sanity check to make sure lut_order table is of correct size,
12589
      should compile out to a NOP if true */
12590
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
12591
       err = BAD_FUNC_ARG;
12592
       goto errout;
12593
   }
12594
12595
   /* get bitlen and round up to next multiple of FP_LUT */
12596
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12597
   x       = bitlen % FP_LUT;
12598
   if (x) {
12599
       bitlen += FP_LUT - x;
12600
   }
12601
   lut_gap = bitlen / FP_LUT;
12602
12603
   /* init the mu */
12604
   err = mp_init_copy(&fp_cache[idx].mu, mu);
12605
   if (err != MP_OKAY)
12606
       goto errout;
12607
12608
   /* copy base */
12609
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
12610
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
12611
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
12612
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
12613
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
12614
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
12615
       err = MP_MULMOD_E;
12616
       goto errout;
12617
   }
12618
12619
   /* make all single bit entries */
12620
   for (x = 1; x < FP_LUT; x++) {
12621
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
12622
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
12623
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
12624
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
12625
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
12626
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
12627
          err = MP_INIT_E;
12628
          goto errout;
12629
      } else {
12630
12631
         /* now double it bitlen/FP_LUT times */
12632
         for (y = 0; y < lut_gap; y++) {
12633
             if ((err = ecc_projective_dbl_point_safe(
12634
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12635
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12636
                                      a, modulus, mp)) != MP_OKAY) {
12637
                 goto errout;
12638
             }
12639
         }
12640
     }
12641
  }
12642
12643
   /* now make all entries in increase order of hamming weight */
12644
   for (x = 2; x <= FP_LUT; x++) {
12645
       if (err != MP_OKAY)
12646
           goto errout;
12647
       for (y = 0; y < (1UL<<FP_LUT); y++) {
12648
           if (lut_orders[y].ham != (int)x) continue;
12649
12650
           /* perform the add */
12651
           if ((err = ecc_projective_add_point_safe(
12652
                           fp_cache[idx].LUT[lut_orders[y].terma],
12653
                           fp_cache[idx].LUT[lut_orders[y].termb],
12654
                           fp_cache[idx].LUT[y], a, modulus, mp,
12655
                           &infinity)) != MP_OKAY) {
12656
               goto errout;
12657
           }
12658
       }
12659
   }
12660
12661
   /* now map all entries back to affine space to make point addition faster */
12662
   for (x = 1; x < (1UL<<FP_LUT); x++) {
12663
       if (err != MP_OKAY)
12664
           break;
12665
12666
       /* convert z to normal from montgomery */
12667
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
12668
12669
       /* invert it */
12670
       if (err == MP_OKAY)
12671
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
12672
                         fp_cache[idx].LUT[x]->z);
12673
12674
       if (err == MP_OKAY)
12675
         /* now square it */
12676
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
12677
12678
       if (err == MP_OKAY)
12679
         /* fix x */
12680
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
12681
                         fp_cache[idx].LUT[x]->x);
12682
12683
       if (err == MP_OKAY)
12684
         /* get 1/z^3 */
12685
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
12686
12687
       if (err == MP_OKAY)
12688
         /* fix y */
12689
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
12690
                         fp_cache[idx].LUT[x]->y);
12691
12692
       if (err == MP_OKAY)
12693
         /* free z */
12694
         mp_clear(fp_cache[idx].LUT[x]->z);
12695
   }
12696
12697
  errout:
12698
12699
   mp_clear(tmp);
12700
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12701
12702
   if (err == MP_OKAY) {
12703
       fp_cache[idx].LUT_set = 1;
12704
       return MP_OKAY;
12705
   }
12706
12707
   /* err cleanup */
12708
   for (y = 0; y < (1U<<FP_LUT); y++) {
12709
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
12710
      fp_cache[idx].LUT[y] = NULL;
12711
   }
12712
   wc_ecc_del_point(fp_cache[idx].g);
12713
   fp_cache[idx].g         = NULL;
12714
   fp_cache[idx].LUT_set   = 0;
12715
   fp_cache[idx].lru_count = 0;
12716
   mp_clear(&fp_cache[idx].mu);
12717
12718
   return err;
12719
}
12720
12721
/* perform a fixed point ECC mulmod */
12722
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
12723
                        mp_int* modulus, mp_digit mp, int map)
12724
{
12725
#ifdef WOLFCRYPT_HAVE_SAKKE
12726
    #define KB_SIZE 256
12727
#else
12728
    #define KB_SIZE 128
12729
#endif
12730
12731
#ifdef WOLFSSL_SMALL_STACK
12732
   unsigned char* kb = NULL;
12733
   mp_int*        tk = NULL;
12734
   mp_int*        order = NULL;
12735
#else
12736
   unsigned char kb[KB_SIZE];
12737
   mp_int        tk[1];
12738
   mp_int        order[1];
12739
#endif
12740
   int      x, err;
12741
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
12742
   int first;
12743
   int tk_zeroize = 0;
12744
12745
#ifdef WOLFSSL_SMALL_STACK
12746
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12747
   if (tk == NULL) {
12748
      err = MEMORY_E; goto done;
12749
   }
12750
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12751
   if (order == NULL) {
12752
      err = MEMORY_E; goto done;
12753
   }
12754
#endif
12755
12756
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
12757
       err = MP_INIT_E; goto done;
12758
   }
12759
12760
   if ((err = mp_copy(k, tk)) != MP_OKAY)
12761
       goto done;
12762
   tk_zeroize = 1;
12763
12764
#ifdef WOLFSSL_CHECK_MEM_ZERO
12765
   mp_memzero_add("accel_fp_mul tk", tk);
12766
#endif
12767
12768
   /* if it's smaller than modulus we fine */
12769
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
12770
      /* find order */
12771
       y = (unsigned)mp_unsigned_bin_size(modulus);
12772
      for (x = 0; ecc_sets[x].size; x++) {
12773
         if (y <= (unsigned)ecc_sets[x].size) break;
12774
      }
12775
12776
      /* back off if we are on the 521 bit curve */
12777
      if (y == 66) --x;
12778
12779
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12780
                                                MP_RADIX_HEX)) != MP_OKAY) {
12781
         goto done;
12782
      }
12783
12784
      /* k must be less than modulus */
12785
      if (mp_cmp(tk, order) != MP_LT) {
12786
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
12787
            goto done;
12788
         }
12789
      }
12790
   }
12791
12792
   /* get bitlen and round up to next multiple of FP_LUT */
12793
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12794
   x       = bitlen % FP_LUT;
12795
   if (x) {
12796
      bitlen += FP_LUT - (unsigned)x;
12797
   }
12798
   lut_gap = bitlen / FP_LUT;
12799
12800
   /* get the k value */
12801
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
12802
      err = BUFFER_E; goto done;
12803
   }
12804
12805
   /* store k */
12806
#ifdef WOLFSSL_SMALL_STACK
12807
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12808
   if (kb == NULL) {
12809
      err = MEMORY_E; goto done;
12810
   }
12811
#endif
12812
12813
   XMEMSET(kb, 0, KB_SIZE);
12814
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
12815
   #ifdef WOLFSSL_CHECK_MEM_ZERO
12816
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
12817
   #endif
12818
      /* let's reverse kb so it's little endian */
12819
      x = 0;
12820
      y = (unsigned)mp_unsigned_bin_size(tk);
12821
      if (y > 0) {
12822
          y -= 1;
12823
      }
12824
12825
      while ((unsigned)x < y) {
12826
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
12827
         ++x; --y;
12828
      }
12829
12830
      /* at this point we can start, yipee */
12831
      first = 1;
12832
      for (x = (int)lut_gap-1; x >= 0; x--) {
12833
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
12834
             by x bits from the start */
12835
          bitpos = (unsigned)x;
12836
          for (y = z = 0; y < FP_LUT; y++) {
12837
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
12838
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
12839
                                    the mult in each loop */
12840
          }
12841
12842
          /* double if not first */
12843
          if (!first) {
12844
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
12845
                                                              mp)) != MP_OKAY) {
12846
                break;
12847
             }
12848
          }
12849
12850
          /* add if not first, otherwise copy */
12851
          if (!first && z) {
12852
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
12853
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
12854
                break;
12855
             }
12856
          } else if (z) {
12857
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
12858
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
12859
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
12860
                 err = MP_MEM;
12861
                 break;
12862
             }
12863
             first = 0;
12864
          }
12865
      }
12866
   }
12867
12868
   if (err == MP_OKAY) {
12869
      (void) z; /* Acknowledge the unused assignment */
12870
      ForceZero(kb, KB_SIZE);
12871
12872
      /* map R back from projective space */
12873
      if (map) {
12874
         err = ecc_map(R, modulus, mp);
12875
      } else {
12876
         err = MP_OKAY;
12877
      }
12878
   }
12879
12880
done:
12881
   /* cleanup */
12882
   mp_clear(order);
12883
   /* Ensure it was initialized. */
12884
   if (tk_zeroize) {
12885
       mp_forcezero(tk);
12886
   }
12887
12888
#ifdef WOLFSSL_SMALL_STACK
12889
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12890
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12891
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12892
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
12893
   wc_MemZero_Check(kb, KB_SIZE);
12894
   mp_memzero_check(tk);
12895
#endif
12896
12897
#undef KB_SIZE
12898
12899
   return err;
12900
}
12901
#endif
12902
12903
#ifdef ECC_SHAMIR
12904
#if !defined(WOLFSSL_SP_MATH)
12905
/* perform a fixed point ECC mulmod */
12906
static int accel_fp_mul2add(int idx1, int idx2,
12907
                            mp_int* kA, mp_int* kB,
12908
                            ecc_point *R, mp_int* a,
12909
                            mp_int* modulus, mp_digit mp)
12910
{
12911
#define KB_SIZE 128
12912
12913
#ifdef WOLFSSL_SMALL_STACK
12914
   unsigned char* kb[2] = {NULL, NULL};
12915
   mp_int*        tka = NULL;
12916
   mp_int*        tkb = NULL;
12917
   mp_int*        order = NULL;
12918
#else
12919
   unsigned char kb[2][KB_SIZE];
12920
   mp_int        tka[1];
12921
   mp_int        tkb[1];
12922
   mp_int        order[1];
12923
#endif
12924
   int      x, err;
12925
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
12926
   int first;
12927
12928
#ifdef WOLFSSL_SMALL_STACK
12929
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12930
   if (tka == NULL) {
12931
      err = MEMORY_E; goto done;
12932
   }
12933
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12934
   if (tkb == NULL) {
12935
      err = MEMORY_E; goto done;
12936
   }
12937
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12938
   if (order == NULL) {
12939
      err = MEMORY_E; goto done;
12940
   }
12941
#endif
12942
12943
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
12944
      err = MP_INIT_E; goto done;
12945
   }
12946
12947
   /* if it's smaller than modulus we fine */
12948
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
12949
      /* find order */
12950
      y = (unsigned)mp_unsigned_bin_size(modulus);
12951
      for (x = 0; ecc_sets[x].size; x++) {
12952
         if (y <= (unsigned)ecc_sets[x].size) break;
12953
      }
12954
12955
      /* back off if we are on the 521 bit curve */
12956
      if (y == 66) --x;
12957
12958
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12959
                                                MP_RADIX_HEX)) != MP_OKAY) {
12960
         goto done;
12961
      }
12962
12963
      /* kA must be less than modulus */
12964
      if (mp_cmp(kA, order) != MP_LT) {
12965
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
12966
            goto done;
12967
         }
12968
      } else {
12969
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12970
            goto done;
12971
         }
12972
      }
12973
   } else {
12974
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12975
         goto done;
12976
      }
12977
   }
12978
#ifdef WOLFSSL_CHECK_MEM_ZERO
12979
   mp_memzero_add("accel_fp_mul2add tka", tka);
12980
#endif
12981
12982
   /* if it's smaller than modulus we fine */
12983
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
12984
      /* find order */
12985
      y = (unsigned)mp_unsigned_bin_size(modulus);
12986
      for (x = 0; ecc_sets[x].size; x++) {
12987
         if (y <= (unsigned)ecc_sets[x].size) break;
12988
      }
12989
12990
      /* back off if we are on the 521 bit curve */
12991
      if (y == 66) --x;
12992
12993
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12994
                                                MP_RADIX_HEX)) != MP_OKAY) {
12995
         goto done;
12996
      }
12997
12998
      /* kB must be less than modulus */
12999
      if (mp_cmp(kB, order) != MP_LT) {
13000
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
13001
            goto done;
13002
         }
13003
      } else {
13004
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13005
            goto done;
13006
         }
13007
      }
13008
   } else {
13009
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13010
         goto done;
13011
      }
13012
   }
13013
#ifdef WOLFSSL_CHECK_MEM_ZERO
13014
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
13015
#endif
13016
13017
   /* get bitlen and round up to next multiple of FP_LUT */
13018
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13019
   x       = bitlen % FP_LUT;
13020
   if (x) {
13021
      bitlen += FP_LUT - (unsigned)x;
13022
   }
13023
   lut_gap = bitlen / FP_LUT;
13024
13025
   /* get the k value */
13026
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
13027
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
13028
      err = BUFFER_E; goto done;
13029
   }
13030
13031
   /* store k */
13032
#ifdef WOLFSSL_SMALL_STACK
13033
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13034
   if (kb[0] == NULL) {
13035
      err = MEMORY_E; goto done;
13036
   }
13037
#endif
13038
13039
   XMEMSET(kb[0], 0, KB_SIZE);
13040
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13041
      goto done;
13042
   }
13043
#ifdef WOLFSSL_CHECK_MEM_ZERO
13044
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13045
#endif
13046
13047
   /* let's reverse kb so it's little endian */
13048
   x = 0;
13049
   y = (unsigned)mp_unsigned_bin_size(tka);
13050
   if (y > 0) {
13051
       y -= 1;
13052
   }
13053
   mp_clear(tka);
13054
   while ((unsigned)x < y) {
13055
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13056
      ++x; --y;
13057
   }
13058
13059
   /* store b */
13060
#ifdef WOLFSSL_SMALL_STACK
13061
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13062
   if (kb[1] == NULL) {
13063
      err = MEMORY_E; goto done;
13064
   }
13065
#endif
13066
13067
   XMEMSET(kb[1], 0, KB_SIZE);
13068
#ifdef WOLFSSL_CHECK_MEM_ZERO
13069
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13070
#endif
13071
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13072
      x = 0;
13073
      y = (unsigned)mp_unsigned_bin_size(tkb);
13074
      if (y > 0) {
13075
          y -= 1;
13076
      }
13077
13078
      while ((unsigned)x < y) {
13079
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13080
         ++x; --y;
13081
      }
13082
13083
      /* at this point we can start, yipee */
13084
      first = 1;
13085
      for (x = (int)lut_gap-1; x >= 0; x--) {
13086
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13087
             offset by x bits from the start */
13088
          bitpos = (unsigned)x;
13089
          for (y = zA = zB = 0; y < FP_LUT; y++) {
13090
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13091
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13092
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13093
                                      the mult in each loop */
13094
          }
13095
13096
          /* double if not first */
13097
          if (!first) {
13098
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13099
                                                              mp)) != MP_OKAY) {
13100
                break;
13101
             }
13102
13103
             /* add if not first, otherwise copy */
13104
             if (zA) {
13105
                if ((err = ecc_projective_add_point_safe(R,
13106
                                             fp_cache[idx1].LUT[zA], R, a,
13107
                                             modulus, mp, &first)) != MP_OKAY) {
13108
                   break;
13109
                }
13110
             }
13111
13112
             if (zB) {
13113
                if ((err = ecc_projective_add_point_safe(R,
13114
                                             fp_cache[idx2].LUT[zB], R, a,
13115
                                             modulus, mp, &first)) != MP_OKAY) {
13116
                   break;
13117
                }
13118
             }
13119
          } else {
13120
             if (zA) {
13121
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13122
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13123
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13124
                     err = MP_MEM;
13125
                     break;
13126
                 }
13127
                    first = 0;
13128
             }
13129
             if (zB && first == 0) {
13130
                if ((err = ecc_projective_add_point_safe(R,
13131
                                        fp_cache[idx2].LUT[zB], R, a,
13132
                                        modulus, mp, &first)) != MP_OKAY){
13133
                   break;
13134
                }
13135
             } else if (zB && first == 1) {
13136
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13137
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13138
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13139
                     err = MP_MEM;
13140
                     break;
13141
                 }
13142
                    first = 0;
13143
             }
13144
          }
13145
      }
13146
   }
13147
13148
done:
13149
   /* cleanup */
13150
   mp_forcezero(tkb);
13151
   mp_forcezero(tka);
13152
   mp_clear(order);
13153
13154
#ifdef WOLFSSL_SMALL_STACK
13155
   if (kb[0])
13156
#endif
13157
      ForceZero(kb[0], KB_SIZE);
13158
#ifdef WOLFSSL_SMALL_STACK
13159
   if (kb[1])
13160
#endif
13161
      ForceZero(kb[1], KB_SIZE);
13162
13163
#ifdef WOLFSSL_SMALL_STACK
13164
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13165
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13166
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13167
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13168
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13169
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13170
   wc_MemZero_Check(kb[1], KB_SIZE);
13171
   wc_MemZero_Check(kb[0], KB_SIZE);
13172
   mp_memzero_check(tkb);
13173
   mp_memzero_check(tka);
13174
#endif
13175
13176
#undef KB_SIZE
13177
13178
    if (err != MP_OKAY)
13179
        return err;
13180
13181
   return ecc_map(R, modulus, mp);
13182
}
13183
13184
13185
/** ECC Fixed Point mulmod global with heap hint used
13186
  Computes kA*A + kB*B = C using Shamir's Trick
13187
  A        First point to multiply
13188
  kA       What to multiple A by
13189
  B        Second point to multiply
13190
  kB       What to multiple B by
13191
  C        [out] Destination point (can overlap with A or B)
13192
  a        ECC curve parameter a
13193
  modulus  Modulus for curve
13194
  return MP_OKAY on success
13195
*/
13196
int ecc_mul2add(ecc_point* A, mp_int* kA,
13197
                ecc_point* B, mp_int* kB,
13198
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13199
{
13200
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13201
   mp_digit mp = 0;
13202
#ifdef WOLFSSL_SMALL_STACK
13203
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13204
13205
   if (mu == NULL)
13206
       return MP_MEM;
13207
#else
13208
   mp_int   mu[1];
13209
#endif
13210
13211
   err = mp_init(mu);
13212
   if (err != MP_OKAY) {
13213
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13214
       return err;
13215
   }
13216
13217
#ifndef HAVE_THREAD_LS
13218
#ifndef WOLFSSL_MUTEX_INITIALIZER
13219
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13220
        wc_InitMutex(&ecc_fp_lock);
13221
        initMutex = 1;
13222
   }
13223
#endif
13224
13225
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13226
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13227
      return BAD_MUTEX_E;
13228
   }
13229
#endif /* HAVE_THREAD_LS */
13230
13231
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13232
13233
      /* find point */
13234
      idx1 = find_base(A);
13235
13236
      /* no entry? */
13237
      if (idx1 == -1) {
13238
         /* find hole and add it */
13239
         if ((idx1 = find_hole()) >= 0) {
13240
            err = add_entry(idx1, A);
13241
         }
13242
      }
13243
      if (err == MP_OKAY && idx1 != -1 && fp_cache[idx1].lru_count < (INT_MAX-1)) {
13244
         /* increment LRU */
13245
         ++(fp_cache[idx1].lru_count);
13246
      }
13247
13248
      if (err == MP_OKAY) {
13249
        /* find point */
13250
        idx2 = find_base(B);
13251
13252
        /* no entry? */
13253
        if (idx2 == -1) {
13254
           /* find hole and add it */
13255
           if ((idx2 = find_hole()) >= 0)
13256
              err = add_entry(idx2, B);
13257
         }
13258
      }
13259
13260
      if (err == MP_OKAY && idx2 != -1 && fp_cache[idx2].lru_count < (INT_MAX-1)) {
13261
         /* increment LRU */
13262
         ++(fp_cache[idx2].lru_count);
13263
      }
13264
13265
      if (err == MP_OKAY) {
13266
        /* if it's >= 2 AND the LUT is not set build the LUT */
13267
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13268
           /* compute mp */
13269
           err = mp_montgomery_setup(modulus, &mp);
13270
13271
           if (err == MP_OKAY) {
13272
             mpInit = 1;
13273
             err = mp_montgomery_calc_normalization(mu, modulus);
13274
           }
13275
13276
           if (err == MP_OKAY)
13277
             /* build the LUT */
13278
             err = build_lut(idx1, a, modulus, mp, mu);
13279
        }
13280
      }
13281
13282
      if (err == MP_OKAY) {
13283
        /* if it's >= 2 AND the LUT is not set build the LUT */
13284
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13285
           if (mpInit == 0) {
13286
                /* compute mp */
13287
                err = mp_montgomery_setup(modulus, &mp);
13288
                if (err == MP_OKAY) {
13289
                    mpInit = 1;
13290
                    err = mp_montgomery_calc_normalization(mu, modulus);
13291
                }
13292
            }
13293
13294
            if (err == MP_OKAY)
13295
              /* build the LUT */
13296
              err = build_lut(idx2, a, modulus, mp, mu);
13297
        }
13298
      }
13299
13300
13301
      if (err == MP_OKAY) {
13302
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13303
                                     fp_cache[idx2].LUT_set) {
13304
           if (mpInit == 0) {
13305
              /* compute mp */
13306
              err = mp_montgomery_setup(modulus, &mp);
13307
           }
13308
           if (err == MP_OKAY)
13309
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13310
        } else {
13311
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13312
        }
13313
      }
13314
13315
      RESTORE_VECTOR_REGISTERS();
13316
13317
#ifndef HAVE_THREAD_LS
13318
    wc_UnLockMutex(&ecc_fp_lock);
13319
#endif /* HAVE_THREAD_LS */
13320
    mp_clear(mu);
13321
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13322
13323
    return err;
13324
}
13325
#endif
13326
#endif /* ECC_SHAMIR */
13327
13328
/** ECC Fixed Point mulmod global
13329
    k        The multiplicand
13330
    G        Base point to multiply
13331
    R        [out] Destination of product
13332
    a        ECC curve parameter a
13333
    modulus  The modulus for the curve
13334
    map      [boolean] If non-zero maps the point back to affine coordinates,
13335
             otherwise it's left in jacobian-montgomery form
13336
    return MP_OKAY if successful
13337
*/
13338
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13339
    mp_int* modulus, int map, void* heap)
13340
{
13341
#if !defined(WOLFSSL_SP_MATH)
13342
   int   idx, err = MP_OKAY;
13343
   mp_digit mp = 0;
13344
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13345
   int      mpSetup = 0;
13346
#ifndef HAVE_THREAD_LS
13347
   int got_ecc_fp_lock = 0;
13348
#endif
13349
13350
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13351
       return ECC_BAD_ARG_E;
13352
   }
13353
13354
   /* k can't have more bits than modulus count plus 1 */
13355
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13356
      return ECC_OUT_OF_RANGE_E;
13357
   }
13358
13359
#ifdef WOLFSSL_SMALL_STACK
13360
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13361
       return MP_MEM;
13362
#endif
13363
13364
   if (mp_init(mu) != MP_OKAY) {
13365
       err = MP_INIT_E;
13366
       goto out;
13367
   }
13368
13369
#ifndef HAVE_THREAD_LS
13370
#ifndef WOLFSSL_MUTEX_INITIALIZER
13371
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13372
        wc_InitMutex(&ecc_fp_lock);
13373
        initMutex = 1;
13374
   }
13375
#endif
13376
13377
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13378
      err = BAD_MUTEX_E;
13379
      goto out;
13380
   }
13381
   got_ecc_fp_lock = 1;
13382
#endif /* HAVE_THREAD_LS */
13383
13384
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13385
13386
      /* find point */
13387
      idx = find_base(G);
13388
13389
      /* no entry? */
13390
      if (idx == -1) {
13391
         /* find hole and add it */
13392
         idx = find_hole();
13393
13394
         if (idx >= 0)
13395
            err = add_entry(idx, G);
13396
      }
13397
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
13398
         /* increment LRU */
13399
         ++(fp_cache[idx].lru_count);
13400
      }
13401
13402
13403
      if (err == MP_OKAY) {
13404
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13405
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13406
           /* compute mp */
13407
           err = mp_montgomery_setup(modulus, &mp);
13408
13409
           if (err == MP_OKAY) {
13410
             /* compute mu */
13411
             mpSetup = 1;
13412
             err = mp_montgomery_calc_normalization(mu, modulus);
13413
           }
13414
13415
           if (err == MP_OKAY)
13416
             /* build the LUT */
13417
             err = build_lut(idx, a, modulus, mp, mu);
13418
        }
13419
      }
13420
13421
      if (err == MP_OKAY) {
13422
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13423
           if (mpSetup == 0) {
13424
              /* compute mp */
13425
              err = mp_montgomery_setup(modulus, &mp);
13426
           }
13427
           if (err == MP_OKAY)
13428
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13429
        } else {
13430
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
13431
        }
13432
      }
13433
13434
      RESTORE_VECTOR_REGISTERS();
13435
13436
  out:
13437
13438
#ifndef HAVE_THREAD_LS
13439
    if (got_ecc_fp_lock)
13440
        wc_UnLockMutex(&ecc_fp_lock);
13441
#endif /* HAVE_THREAD_LS */
13442
    mp_clear(mu);
13443
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13444
13445
    return err;
13446
13447
#else /* WOLFSSL_SP_MATH */
13448
13449
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13450
        return ECC_BAD_ARG_E;
13451
    }
13452
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13453
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13454
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13455
        return IS_POINT_E;
13456
    }
13457
13458
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13459
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13460
        int ret;
13461
        SAVE_VECTOR_REGISTERS(return _svr_ret);
13462
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13463
        RESTORE_VECTOR_REGISTERS();
13464
        return ret;
13465
    }
13466
#endif
13467
#ifndef WOLFSSL_SP_NO_256
13468
    if (mp_count_bits(modulus) == 256) {
13469
        int ret;
13470
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13471
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13472
        RESTORE_VECTOR_REGISTERS();
13473
        return ret;
13474
    }
13475
#endif
13476
#ifdef WOLFSSL_SP_384
13477
    if (mp_count_bits(modulus) == 384) {
13478
        int ret;
13479
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13480
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13481
        RESTORE_VECTOR_REGISTERS();
13482
        return ret;
13483
    }
13484
#endif
13485
#ifdef WOLFSSL_SP_521
13486
    if (mp_count_bits(modulus) == 521) {
13487
        int ret;
13488
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13489
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13490
        RESTORE_VECTOR_REGISTERS();
13491
        return ret;
13492
    }
13493
#endif
13494
    return WC_KEY_SIZE_E;
13495
#endif /* WOLFSSL_SP_MATH */
13496
}
13497
13498
/** ECC Fixed Point mulmod global
13499
    k        The multiplicand
13500
    G        Base point to multiply
13501
    R        [out] Destination of product
13502
    a        ECC curve parameter a
13503
    modulus  The modulus for the curve
13504
    map      [boolean] If non-zero maps the point back to affine coordinates,
13505
             otherwise it's left in jacobian-montgomery form
13506
    return MP_OKAY if successful
13507
*/
13508
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13509
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
13510
{
13511
#if !defined(WOLFSSL_SP_MATH)
13512
   int   idx, err = MP_OKAY;
13513
   mp_digit mp = 0;
13514
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13515
   int      mpSetup = 0;
13516
#ifndef HAVE_THREAD_LS
13517
   int got_ecc_fp_lock = 0;
13518
#endif
13519
13520
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13521
                                                                order == NULL) {
13522
       return ECC_BAD_ARG_E;
13523
   }
13524
13525
   /* k can't have more bits than order */
13526
   if (mp_count_bits(k) > mp_count_bits(order)) {
13527
      return ECC_OUT_OF_RANGE_E;
13528
   }
13529
13530
#ifdef WOLFSSL_SMALL_STACK
13531
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13532
       return MP_MEM;
13533
#endif
13534
13535
   if (mp_init(mu) != MP_OKAY) {
13536
       err = MP_INIT_E;
13537
       goto out;
13538
   }
13539
13540
#ifndef HAVE_THREAD_LS
13541
#ifndef WOLFSSL_MUTEX_INITIALIZER
13542
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13543
        wc_InitMutex(&ecc_fp_lock);
13544
        initMutex = 1;
13545
   }
13546
#endif
13547
13548
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13549
      err = BAD_MUTEX_E;
13550
      goto out;
13551
   }
13552
   got_ecc_fp_lock = 1;
13553
#endif /* HAVE_THREAD_LS */
13554
13555
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13556
13557
      /* find point */
13558
      idx = find_base(G);
13559
13560
      /* no entry? */
13561
      if (idx == -1) {
13562
         /* find hole and add it */
13563
         idx = find_hole();
13564
13565
         if (idx >= 0)
13566
            err = add_entry(idx, G);
13567
      }
13568
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
13569
         /* increment LRU */
13570
         ++(fp_cache[idx].lru_count);
13571
      }
13572
13573
13574
      if (err == MP_OKAY) {
13575
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13576
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13577
           /* compute mp */
13578
           err = mp_montgomery_setup(modulus, &mp);
13579
13580
           if (err == MP_OKAY) {
13581
             /* compute mu */
13582
             mpSetup = 1;
13583
             err = mp_montgomery_calc_normalization(mu, modulus);
13584
           }
13585
13586
           if (err == MP_OKAY)
13587
             /* build the LUT */
13588
             err = build_lut(idx, a, modulus, mp, mu);
13589
        }
13590
      }
13591
13592
      if (err == MP_OKAY) {
13593
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13594
           if (mpSetup == 0) {
13595
              /* compute mp */
13596
              err = mp_montgomery_setup(modulus, &mp);
13597
           }
13598
           if (err == MP_OKAY)
13599
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13600
        } else {
13601
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
13602
        }
13603
      }
13604
13605
      RESTORE_VECTOR_REGISTERS();
13606
13607
  out:
13608
13609
#ifndef HAVE_THREAD_LS
13610
    if (got_ecc_fp_lock)
13611
        wc_UnLockMutex(&ecc_fp_lock);
13612
#endif /* HAVE_THREAD_LS */
13613
    mp_clear(mu);
13614
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13615
13616
    return err;
13617
13618
#else /* WOLFSSL_SP_MATH */
13619
13620
    (void)rng;
13621
13622
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13623
                                                                order == NULL) {
13624
        return ECC_BAD_ARG_E;
13625
    }
13626
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13627
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13628
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13629
        return IS_POINT_E;
13630
    }
13631
13632
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13633
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13634
        int ret;
13635
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13636
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13637
        RESTORE_VECTOR_REGISTERS();
13638
        return ret;
13639
    }
13640
#endif
13641
#ifndef WOLFSSL_SP_NO_256
13642
    if (mp_count_bits(modulus) == 256) {
13643
        int ret;
13644
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13645
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13646
        RESTORE_VECTOR_REGISTERS();
13647
        return ret;
13648
    }
13649
#endif
13650
#ifdef WOLFSSL_SP_384
13651
    if (mp_count_bits(modulus) == 384) {
13652
        int ret;
13653
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13654
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13655
        RESTORE_VECTOR_REGISTERS();
13656
        return ret;
13657
    }
13658
#endif
13659
#ifdef WOLFSSL_SP_521
13660
    if (mp_count_bits(modulus) == 521) {
13661
        int ret;
13662
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13663
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13664
        RESTORE_VECTOR_REGISTERS();
13665
        return ret;
13666
    }
13667
#endif
13668
    return WC_KEY_SIZE_E;
13669
#endif /* WOLFSSL_SP_MATH */
13670
}
13671
13672
#if !defined(WOLFSSL_SP_MATH)
13673
/* helper function for freeing the cache ...
13674
   must be called with the cache mutex locked */
13675
static void wc_ecc_fp_free_cache(void)
13676
{
13677
   unsigned x, y;
13678
   for (x = 0; x < FP_ENTRIES; x++) {
13679
      if (fp_cache[x].g != NULL) {
13680
         for (y = 0; y < (1U<<FP_LUT); y++) {
13681
            wc_ecc_del_point(fp_cache[x].LUT[y]);
13682
            fp_cache[x].LUT[y] = NULL;
13683
         }
13684
         wc_ecc_del_point(fp_cache[x].g);
13685
         fp_cache[x].g         = NULL;
13686
         mp_clear(&fp_cache[x].mu);
13687
         fp_cache[x].LUT_set   = 0;
13688
         fp_cache[x].lru_count = 0;
13689
         fp_cache[x].lock = 0;
13690
      }
13691
   }
13692
}
13693
#endif
13694
13695
13696
/** Init the Fixed Point cache */
13697
void wc_ecc_fp_init(void)
13698
{
13699
#ifndef WOLFSSL_SP_MATH
13700
#ifndef HAVE_THREAD_LS
13701
#ifndef WOLFSSL_MUTEX_INITIALIZER
13702
   if (initMutex == 0) {
13703
        wc_InitMutex(&ecc_fp_lock);
13704
        initMutex = 1;
13705
   }
13706
#endif
13707
#endif
13708
#endif
13709
}
13710
13711
13712
/** Free the Fixed Point cache */
13713
WOLFSSL_ABI
13714
void wc_ecc_fp_free(void)
13715
{
13716
#if !defined(WOLFSSL_SP_MATH)
13717
#ifndef HAVE_THREAD_LS
13718
#ifndef WOLFSSL_MUTEX_INITIALIZER
13719
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13720
        wc_InitMutex(&ecc_fp_lock);
13721
        initMutex = 1;
13722
   }
13723
#endif
13724
13725
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
13726
#endif /* HAVE_THREAD_LS */
13727
13728
       wc_ecc_fp_free_cache();
13729
13730
#ifndef HAVE_THREAD_LS
13731
       wc_UnLockMutex(&ecc_fp_lock);
13732
#ifndef WOLFSSL_MUTEX_INITIALIZER
13733
       wc_FreeMutex(&ecc_fp_lock);
13734
       initMutex = 0;
13735
#endif
13736
   }
13737
#endif /* HAVE_THREAD_LS */
13738
#endif
13739
}
13740
13741
13742
#endif /* FP_ECC */
13743
13744
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
13745
5.78k
{
13746
5.78k
    int err = 0;
13747
13748
5.78k
#ifdef ECC_TIMING_RESISTANT
13749
5.78k
    if (key == NULL) {
13750
0
        err = BAD_FUNC_ARG;
13751
0
    }
13752
5.78k
    else {
13753
5.78k
        key->rng = rng;
13754
5.78k
    }
13755
#else
13756
    (void)key;
13757
    (void)rng;
13758
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
13759
#endif
13760
13761
5.78k
    return err;
13762
5.78k
}
13763
13764
#ifdef HAVE_ECC_ENCRYPT
13765
13766
13767
enum ecCliState {
13768
    ecCLI_INIT      = 1,
13769
    ecCLI_SALT_GET  = 2,
13770
    ecCLI_SALT_SET  = 3,
13771
    ecCLI_SENT_REQ  = 4,
13772
    ecCLI_RECV_RESP = 5,
13773
    ecCLI_BAD_STATE = 99
13774
};
13775
13776
enum ecSrvState {
13777
    ecSRV_INIT      = 1,
13778
    ecSRV_SALT_GET  = 2,
13779
    ecSRV_SALT_SET  = 3,
13780
    ecSRV_RECV_REQ  = 4,
13781
    ecSRV_SENT_RESP = 5,
13782
    ecSRV_BAD_STATE = 99
13783
};
13784
13785
13786
struct ecEncCtx {
13787
    const byte* kdfSalt;   /* optional salt for kdf */
13788
    const byte* kdfInfo;   /* optional info for kdf */
13789
    const byte* macSalt;   /* optional salt for mac */
13790
    word32    kdfSaltSz;   /* size of kdfSalt */
13791
    word32    kdfInfoSz;   /* size of kdfInfo */
13792
    word32    macSaltSz;   /* size of macSalt */
13793
    void*     heap;        /* heap hint for memory used */
13794
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13795
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13796
    byte      encAlgo;     /* which encryption type */
13797
    byte      kdfAlgo;     /* which key derivation function type */
13798
    byte      macAlgo;     /* which mac function type */
13799
    byte      protocol;    /* are we REQ_RESP client or server ? */
13800
    byte      cliSt;       /* protocol state, for sanity checks */
13801
    byte      srvSt;       /* protocol state, for sanity checks */
13802
    WC_RNG*   rng;
13803
};
13804
13805
/* optional set info, can be called before or after set_peer_salt */
13806
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
13807
0
{
13808
0
    if (ctx == NULL)
13809
0
        return BAD_FUNC_ARG;
13810
13811
0
    ctx->encAlgo = encAlgo;
13812
0
    ctx->kdfAlgo = kdfAlgo;
13813
0
    ctx->macAlgo = macAlgo;
13814
13815
0
    return 0;
13816
0
}
13817
13818
13819
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
13820
0
{
13821
0
    if (ctx == NULL || ctx->protocol == 0)
13822
0
        return NULL;
13823
13824
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13825
0
        if (ctx->cliSt == ecCLI_INIT) {
13826
0
            ctx->cliSt =  ecCLI_SALT_GET;
13827
0
            return ctx->clientSalt;
13828
0
        }
13829
0
        else {
13830
0
            ctx->cliSt = ecCLI_BAD_STATE;
13831
0
            return NULL;
13832
0
        }
13833
0
    }
13834
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13835
0
        if (ctx->srvSt == ecSRV_INIT) {
13836
0
            ctx->srvSt =  ecSRV_SALT_GET;
13837
0
            return ctx->serverSalt;
13838
0
        }
13839
0
        else {
13840
0
            ctx->srvSt = ecSRV_BAD_STATE;
13841
0
            return NULL;
13842
0
        }
13843
0
    }
13844
13845
0
    return NULL;
13846
0
}
13847
13848
13849
/* optional set info, can be called before or after set_peer_salt */
13850
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
13851
0
{
13852
0
    if (ctx == NULL || info == 0 || sz < 0)
13853
0
        return BAD_FUNC_ARG;
13854
13855
0
    ctx->kdfInfo   = info;
13856
0
    ctx->kdfInfoSz = (word32)sz;
13857
13858
0
    return 0;
13859
0
}
13860
13861
13862
static const char* exchange_info = "Secure Message Exchange";
13863
13864
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
13865
0
{
13866
0
    byte tmp[EXCHANGE_SALT_SZ/2];
13867
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
13868
13869
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13870
0
        return BAD_FUNC_ARG;
13871
13872
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13873
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
13874
0
        if (ctx->cliSt == ecCLI_SALT_GET)
13875
0
            ctx->cliSt =  ecCLI_SALT_SET;
13876
0
        else {
13877
0
            ctx->cliSt =  ecCLI_BAD_STATE;
13878
0
            return BAD_STATE_E;
13879
0
        }
13880
0
    }
13881
0
    else {
13882
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
13883
0
        if (ctx->srvSt == ecSRV_SALT_GET)
13884
0
            ctx->srvSt =  ecSRV_SALT_SET;
13885
0
        else {
13886
0
            ctx->srvSt =  ecSRV_BAD_STATE;
13887
0
            return BAD_STATE_E;
13888
0
        }
13889
0
    }
13890
13891
    /* mix half and half */
13892
    /* tmp stores 2nd half of client before overwrite */
13893
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
13894
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
13895
0
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
13896
13897
0
    ctx->kdfSalt   = ctx->clientSalt;
13898
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
13899
13900
0
    ctx->macSalt   = ctx->serverSalt;
13901
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
13902
13903
0
    if (ctx->kdfInfo == NULL) {
13904
        /* default info */
13905
0
        ctx->kdfInfo   = (const byte*)exchange_info;
13906
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
13907
0
    }
13908
13909
0
    return 0;
13910
0
}
13911
13912
/* Set the salt pointer into context.
13913
 *
13914
 * @param  [in, out]  ctx   ECIES context object.
13915
 * @param  [in]       salt  Salt to use with KDF.
13916
 * @param  [in]       sz    Length of salt in bytes.
13917
 * @return  0 on success.
13918
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13919
 */
13920
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13921
0
{
13922
0
    if (ctx == NULL || (salt == NULL && sz != 0))
13923
0
        return BAD_FUNC_ARG;
13924
13925
    /* truncate salt if exceeds max */
13926
0
    if (sz > EXCHANGE_SALT_SZ)
13927
0
        sz = EXCHANGE_SALT_SZ;
13928
13929
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
13930
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
13931
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13932
0
        ctx->cliSt = ecCLI_SALT_SET;
13933
0
        ctx->kdfSalt = ctx->clientSalt;
13934
0
    }
13935
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13936
0
        ctx->srvSt = ecSRV_SALT_SET;
13937
0
        ctx->kdfSalt = ctx->serverSalt;
13938
0
    }
13939
13940
0
    if (salt != NULL) {
13941
0
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
13942
0
    }
13943
0
    ctx->kdfSaltSz = sz;
13944
13945
0
    return 0;
13946
0
}
13947
13948
/* Set your own salt. By default we generate a random salt for ourselves.
13949
 * This allows overriding that after init or reset.
13950
 *
13951
 * @param  [in, out]  ctx   ECIES context object.
13952
 * @param  [in]       salt  Salt to use for ourselves
13953
 * @param  [in]       sz    Length of salt in bytes.
13954
 * @return  0 on success.
13955
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13956
 */
13957
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13958
0
{
13959
0
    byte* saltBuffer;
13960
13961
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13962
0
        return BAD_FUNC_ARG;
13963
13964
0
    if (sz > EXCHANGE_SALT_SZ)
13965
0
        sz = EXCHANGE_SALT_SZ;
13966
0
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
13967
0
        ctx->clientSalt :
13968
0
        ctx->serverSalt;
13969
0
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
13970
0
    XMEMCPY(saltBuffer, salt, sz);
13971
13972
0
    return 0;
13973
0
}
13974
13975
13976
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
13977
0
{
13978
0
    byte* saltBuffer;
13979
13980
0
    if (ctx == NULL || flags == 0)
13981
0
        return BAD_FUNC_ARG;
13982
13983
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
13984
13985
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
13986
0
}
13987
13988
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
13989
695
{
13990
695
    if (ctx) {
13991
695
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
13992
13993
695
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13994
695
        #ifdef WOLFSSL_AES_128
13995
695
            ctx->encAlgo  = ecAES_128_CBC;
13996
        #else
13997
            ctx->encAlgo  = ecAES_256_CBC;
13998
        #endif
13999
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14000
        #ifdef WOLFSSL_AES_256
14001
            ctx->encAlgo  = ecAES_256_CTR;
14002
        #else
14003
            ctx->encAlgo  = ecAES_128_CTR;
14004
        #endif
14005
    #else
14006
        #error "No valid encryption algorithm for ECIES configured."
14007
    #endif
14008
695
        ctx->kdfAlgo  = ecHKDF_SHA256;
14009
695
        ctx->macAlgo  = ecHMAC_SHA256;
14010
695
        ctx->protocol = (byte)flags;
14011
695
        ctx->rng      = rng;
14012
14013
695
        if (flags == REQ_RESP_CLIENT)
14014
0
            ctx->cliSt = ecCLI_INIT;
14015
695
        if (flags == REQ_RESP_SERVER)
14016
0
            ctx->srvSt = ecSRV_INIT;
14017
695
    }
14018
695
}
14019
14020
14021
/* allow ecc context reset so user doesn't have to init/free for reuse */
14022
WOLFSSL_ABI
14023
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
14024
0
{
14025
0
    if (ctx == NULL || rng == NULL)
14026
0
        return BAD_FUNC_ARG;
14027
14028
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
14029
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
14030
0
}
14031
14032
14033
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14034
0
{
14035
0
    int       ret = 0;
14036
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14037
0
                                                              DYNAMIC_TYPE_ECC);
14038
14039
0
    if (ctx) {
14040
0
        ctx->protocol = (byte)flags;
14041
0
        ctx->heap     = heap;
14042
0
    }
14043
14044
0
    ret = wc_ecc_ctx_reset(ctx, rng);
14045
0
    if (ret != 0) {
14046
0
        wc_ecc_ctx_free(ctx);
14047
0
        ctx = NULL;
14048
0
    }
14049
14050
0
    return ctx;
14051
0
}
14052
14053
14054
/* alloc/init and set defaults, return new Context  */
14055
WOLFSSL_ABI
14056
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14057
0
{
14058
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14059
0
}
14060
14061
14062
/* free any resources, clear any keys */
14063
WOLFSSL_ABI
14064
void wc_ecc_ctx_free(ecEncCtx* ctx)
14065
0
{
14066
0
    if (ctx) {
14067
0
        void* heap = ctx->heap;
14068
0
        ForceZero(ctx, sizeof(ecEncCtx));
14069
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14070
0
        (void)heap;
14071
0
    }
14072
0
}
14073
14074
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14075
                             int* keysLen, word32* digestSz, word32* blockSz)
14076
695
{
14077
695
    if (ctx) {
14078
695
        switch (ctx->encAlgo) {
14079
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14080
695
            case ecAES_128_CBC:
14081
695
                *encKeySz = KEY_SIZE_128;
14082
695
                *ivSz     = IV_SIZE_128;
14083
695
                *blockSz  = WC_AES_BLOCK_SIZE;
14084
695
                break;
14085
0
            case ecAES_256_CBC:
14086
0
                *encKeySz = KEY_SIZE_256;
14087
0
                *ivSz     = IV_SIZE_128;
14088
0
                *blockSz  = WC_AES_BLOCK_SIZE;
14089
0
                break;
14090
0
        #endif
14091
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14092
0
            case ecAES_128_CTR:
14093
0
                *encKeySz = KEY_SIZE_128;
14094
0
                *ivSz     = 12;
14095
0
                *blockSz  = 1;
14096
0
                break;
14097
0
            case ecAES_256_CTR:
14098
0
                *encKeySz = KEY_SIZE_256;
14099
0
                *ivSz     = 12;
14100
0
                *blockSz  = 1;
14101
0
                break;
14102
0
        #endif
14103
0
            default:
14104
0
                return BAD_FUNC_ARG;
14105
695
        }
14106
14107
695
        switch (ctx->macAlgo) {
14108
695
            case ecHMAC_SHA256:
14109
695
                *digestSz = WC_SHA256_DIGEST_SIZE;
14110
695
                break;
14111
0
            default:
14112
0
                return BAD_FUNC_ARG;
14113
695
        }
14114
695
    } else
14115
0
        return BAD_FUNC_ARG;
14116
14117
#ifdef WOLFSSL_ECIES_OLD
14118
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14119
#else
14120
695
    *keysLen  = *encKeySz + (int)*digestSz;
14121
695
#endif
14122
14123
695
    return 0;
14124
695
}
14125
14126
14127
/* ecc encrypt with shared secret run through kdf
14128
   ctx holds non default algos and inputs
14129
   msgSz should be the right size for encAlgo, i.e., already padded
14130
   return 0 on success */
14131
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14132
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14133
367
{
14134
367
    int          ret = 0;
14135
367
    word32       blockSz = 0;
14136
367
#ifndef WOLFSSL_ECIES_OLD
14137
367
#ifndef WOLFSSL_ECIES_GEN_IV
14138
367
    byte         iv[ECC_MAX_IV_SIZE];
14139
367
#endif
14140
367
    word32       pubKeySz = 0;
14141
367
#endif
14142
367
    word32       digestSz = 0;
14143
367
    ecEncCtx     localCtx;
14144
367
#ifdef WOLFSSL_SMALL_STACK
14145
367
    byte*        sharedSecret;
14146
367
    byte*        keys;
14147
#else
14148
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14149
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14150
#else
14151
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14152
#endif
14153
    byte         keys[ECC_BUFSIZE];         /* max size */
14154
#endif
14155
367
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14156
367
    word32       sharedSz = ECC_MAXSIZE;
14157
#else
14158
    /* 'Uncompressed' byte | public key x | public key y | secret */
14159
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14160
#endif
14161
367
    int          keysLen = 0;
14162
367
    int          encKeySz = 0;
14163
367
    int          ivSz = 0;
14164
367
    int          offset = 0;         /* keys offset if doing msg exchange */
14165
367
    byte*        encKey = NULL;
14166
367
    byte*        encIv = NULL;
14167
367
    byte*        macKey = NULL;
14168
14169
367
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14170
337
                           outSz  == NULL)
14171
30
        return BAD_FUNC_ARG;
14172
14173
337
    if (ctx == NULL) {  /* use defaults */
14174
337
        ecc_ctx_init(&localCtx, 0, NULL);
14175
337
        ctx = &localCtx;
14176
337
    }
14177
14178
337
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14179
337
                            &blockSz);
14180
337
    if (ret != 0)
14181
0
        return ret;
14182
14183
337
#ifndef WOLFSSL_ECIES_OLD
14184
337
    if (!compressed) {
14185
337
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14186
337
    }
14187
0
    else {
14188
0
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14189
0
    }
14190
#else
14191
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14192
#endif
14193
14194
337
    if (ctx->protocol == REQ_RESP_SERVER) {
14195
0
        offset = keysLen;
14196
0
        keysLen *= 2;
14197
14198
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
14199
0
            return BAD_STATE_E;
14200
14201
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14202
0
    }
14203
337
    else if (ctx->protocol == REQ_RESP_CLIENT) {
14204
0
        if (ctx->cliSt != ecCLI_SALT_SET)
14205
0
            return BAD_STATE_E;
14206
14207
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14208
0
    }
14209
14210
337
    if (keysLen > ECC_BUFSIZE) /* keys size */
14211
0
        return BUFFER_E;
14212
14213
337
    if ((msgSz % blockSz) != 0)
14214
57
        return BAD_PADDING_E;
14215
14216
#ifdef WOLFSSL_ECIES_OLD
14217
    if (*outSz < (msgSz + digestSz))
14218
        return BUFFER_E;
14219
#elif defined(WOLFSSL_ECIES_GEN_IV)
14220
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14221
        return BUFFER_E;
14222
#else
14223
280
    if (*outSz < (pubKeySz + msgSz + digestSz))
14224
16
        return BUFFER_E;
14225
264
#endif
14226
14227
264
#ifdef ECC_TIMING_RESISTANT
14228
264
    if (ctx->rng != NULL && privKey->rng == NULL)
14229
0
        privKey->rng = ctx->rng;
14230
264
#endif
14231
14232
264
#ifndef WOLFSSL_ECIES_OLD
14233
264
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14234
264
#ifdef ECC_TIMING_RESISTANT
14235
264
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14236
#else
14237
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14238
#endif
14239
264
        if (ret != 0)
14240
43
            return ret;
14241
264
    }
14242
221
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14243
221
    if (ret != 0)
14244
1
        return ret;
14245
220
    out += pubKeySz;
14246
220
#endif
14247
14248
220
#ifdef WOLFSSL_SMALL_STACK
14249
220
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14250
220
    if (sharedSecret == NULL)
14251
1
        return MEMORY_E;
14252
14253
219
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14254
219
    if (keys == NULL) {
14255
1
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14256
1
        return MEMORY_E;
14257
1
    }
14258
218
#endif
14259
14260
218
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14261
14262
#ifdef WOLFSSL_ECIES_ISO18033
14263
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14264
    sharedSz -= pubKeySz;
14265
#endif
14266
14267
218
    do {
14268
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14269
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14270
        if (ret != 0)
14271
            break;
14272
    #endif
14273
218
    #ifndef WOLFSSL_ECIES_ISO18033
14274
218
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14275
    #else
14276
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14277
                                                                     &sharedSz);
14278
    #endif
14279
218
    }
14280
218
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14281
14282
218
    if (ret == 0) {
14283
    #ifdef WOLFSSL_ECIES_ISO18033
14284
        /* KDF data is encoded public key and secret. */
14285
        sharedSz += pubKeySz;
14286
    #endif
14287
213
        switch (ctx->kdfAlgo) {
14288
213
            case ecHKDF_SHA256 :
14289
213
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14290
213
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14291
213
                           keys, (word32)keysLen);
14292
213
                break;
14293
0
            case ecHKDF_SHA1 :
14294
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14295
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14296
0
                           keys, (word32)keysLen);
14297
0
                break;
14298
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14299
0
            case ecKDF_X963_SHA1 :
14300
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14301
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14302
0
                break;
14303
0
            case ecKDF_X963_SHA256 :
14304
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14305
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14306
0
                break;
14307
0
            case ecKDF_SHA1 :
14308
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14309
0
                           NULL, 0, keys, (word32)keysLen);
14310
0
                break;
14311
0
            case ecKDF_SHA256 :
14312
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14313
0
                           NULL, 0, keys, (word32)keysLen);
14314
0
                break;
14315
0
#endif
14316
14317
14318
0
            default:
14319
0
                ret = BAD_FUNC_ARG;
14320
0
                break;
14321
213
        }
14322
213
    }
14323
14324
218
    if (ret == 0) {
14325
    #ifdef WOLFSSL_ECIES_OLD
14326
        encKey = keys + offset;
14327
        encIv  = encKey + encKeySz;
14328
        macKey = encKey + encKeySz + ivSz;
14329
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14330
        encKey = keys + offset;
14331
        encIv  = out;
14332
        out += ivSz;
14333
        macKey = encKey + encKeySz;
14334
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14335
    #else
14336
200
        XMEMSET(iv, 0, (size_t)ivSz);
14337
200
        encKey = keys + offset;
14338
200
        encIv  = iv;
14339
200
        macKey = encKey + encKeySz;
14340
200
    #endif
14341
200
    }
14342
14343
218
    if (ret == 0) {
14344
200
       switch (ctx->encAlgo) {
14345
200
            case ecAES_128_CBC:
14346
200
            case ecAES_256_CBC:
14347
200
            {
14348
200
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14349
200
            #ifdef WOLFSSL_SMALL_STACK
14350
200
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14351
200
                                          DYNAMIC_TYPE_AES);
14352
200
                if (aes == NULL) {
14353
1
                    ret = MEMORY_E;
14354
1
                    break;
14355
1
                }
14356
            #else
14357
                Aes aes[1];
14358
            #endif
14359
199
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14360
199
                if (ret == 0) {
14361
199
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14362
199
                                                                AES_ENCRYPTION);
14363
199
                    if (ret == 0) {
14364
199
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14365
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14366
                                                    defined(WC_ASYNC_ENABLE_AES)
14367
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14368
                                            WC_ASYNC_FLAG_NONE);
14369
                    #endif
14370
199
                    }
14371
199
                    wc_AesFree(aes);
14372
199
                }
14373
199
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14374
        #else
14375
                ret = NOT_COMPILED_IN;
14376
        #endif
14377
199
                break;
14378
200
            }
14379
0
            case ecAES_128_CTR:
14380
0
            case ecAES_256_CTR:
14381
0
            {
14382
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14383
0
                byte ctr_iv[WC_AES_BLOCK_SIZE];
14384
            #ifndef WOLFSSL_SMALL_STACK
14385
                Aes aes[1];
14386
            #else
14387
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14388
0
                                            DYNAMIC_TYPE_AES);
14389
0
                if (aes == NULL) {
14390
0
                    ret = MEMORY_E;
14391
0
                    break;
14392
0
                }
14393
0
            #endif
14394
14395
                /* Include 4 byte counter starting at all zeros. */
14396
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14397
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14398
0
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14399
14400
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14401
0
                if (ret == 0) {
14402
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14403
0
                                                                AES_ENCRYPTION);
14404
0
                    if (ret == 0) {
14405
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
14406
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14407
                                                    defined(WC_ASYNC_ENABLE_AES)
14408
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14409
                                            WC_ASYNC_FLAG_NONE);
14410
                    #endif
14411
0
                    }
14412
0
                    wc_AesFree(aes);
14413
0
                }
14414
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14415
        #else
14416
                ret = NOT_COMPILED_IN;
14417
        #endif
14418
0
                break;
14419
0
            }
14420
0
            default:
14421
0
                ret = BAD_FUNC_ARG;
14422
0
                break;
14423
200
        }
14424
200
    }
14425
14426
218
    if (ret == 0) {
14427
199
        switch (ctx->macAlgo) {
14428
199
            case ecHMAC_SHA256:
14429
199
            {
14430
199
            #ifdef WOLFSSL_SMALL_STACK
14431
199
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14432
199
                                             DYNAMIC_TYPE_HMAC);
14433
199
                if (hmac == NULL) {
14434
1
                    ret = MEMORY_E;
14435
1
                    break;
14436
1
                }
14437
            #else
14438
                Hmac hmac[1];
14439
            #endif
14440
198
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14441
198
                if (ret == 0) {
14442
198
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14443
198
                                                         WC_SHA256_DIGEST_SIZE);
14444
198
                    if (ret == 0) {
14445
198
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14446
198
                        ret = wc_HmacUpdate(hmac, out, msgSz);
14447
                    #else
14448
                        /* IV is before encrypted message. */
14449
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
14450
                    #endif
14451
198
                    }
14452
198
                    if (ret == 0)
14453
197
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14454
198
                    if (ret == 0)
14455
197
                        ret = wc_HmacFinal(hmac, out+msgSz);
14456
198
                    wc_HmacFree(hmac);
14457
198
                }
14458
198
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14459
198
                break;
14460
199
            }
14461
14462
0
            default:
14463
0
                ret = BAD_FUNC_ARG;
14464
0
                break;
14465
199
        }
14466
199
    }
14467
14468
218
    if (ret == 0) {
14469
#ifdef WOLFSSL_ECIES_OLD
14470
        *outSz = msgSz + digestSz;
14471
#elif defined(WOLFSSL_ECIES_GEN_IV)
14472
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
14473
#else
14474
197
        *outSz = pubKeySz + msgSz + digestSz;
14475
197
#endif
14476
197
    }
14477
14478
218
    RESTORE_VECTOR_REGISTERS();
14479
14480
218
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14481
218
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14482
14483
218
    return ret;
14484
218
}
14485
14486
/* ecc encrypt with shared secret run through kdf
14487
   ctx holds non default algos and inputs
14488
   msgSz should be the right size for encAlgo, i.e., already padded
14489
   return 0 on success */
14490
WOLFSSL_ABI
14491
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14492
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14493
367
{
14494
367
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14495
367
}
14496
14497
/* ecc decrypt with shared secret run through kdf
14498
   ctx holds non default algos and inputs
14499
   return 0 on success */
14500
WOLFSSL_ABI
14501
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14502
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14503
386
{
14504
386
    int          ret = 0;
14505
386
    word32       blockSz = 0;
14506
386
#ifndef WOLFSSL_ECIES_OLD
14507
386
#ifndef WOLFSSL_ECIES_GEN_IV
14508
386
    byte         iv[ECC_MAX_IV_SIZE];
14509
386
#endif
14510
386
    word32       pubKeySz = 0;
14511
386
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
14512
386
#endif
14513
386
    word32       digestSz = 0;
14514
386
    ecEncCtx     localCtx;
14515
386
#ifdef WOLFSSL_SMALL_STACK
14516
386
    byte*        sharedSecret;
14517
386
    byte*        keys;
14518
#else
14519
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14520
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14521
#else
14522
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14523
#endif
14524
    byte         keys[ECC_BUFSIZE];         /* max size */
14525
#endif
14526
386
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14527
386
    word32       sharedSz = ECC_MAXSIZE;
14528
#else
14529
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14530
#endif
14531
386
    int          keysLen = 0;
14532
386
    int          encKeySz = 0;
14533
386
    int          ivSz = 0;
14534
386
    int          offset = 0;       /* in case using msg exchange */
14535
386
    byte*        encKey = NULL;
14536
386
    const byte*  encIv = NULL;
14537
386
    byte*        macKey = NULL;
14538
14539
14540
386
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14541
28
        return BAD_FUNC_ARG;
14542
#ifdef WOLFSSL_ECIES_OLD
14543
    if (pubKey == NULL)
14544
        return BAD_FUNC_ARG;
14545
#endif
14546
14547
358
    if (ctx == NULL) {  /* use defaults */
14548
358
        ecc_ctx_init(&localCtx, 0, NULL);
14549
358
        ctx = &localCtx;
14550
358
    }
14551
14552
358
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14553
358
                            &blockSz);
14554
358
    if (ret != 0)
14555
0
        return ret;
14556
14557
358
#ifndef WOLFSSL_ECIES_OLD
14558
358
    ret = ecc_public_key_size(privKey, &pubKeySz);
14559
358
    if (ret != 0)
14560
0
        return ret;
14561
358
#ifdef HAVE_COMP_KEY
14562
358
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14563
142
        pubKeySz = (pubKeySz / 2) + 1;
14564
142
    }
14565
358
#endif /* HAVE_COMP_KEY */
14566
358
#endif /* WOLFSSL_ECIES_OLD */
14567
14568
358
    if (ctx->protocol == REQ_RESP_CLIENT) {
14569
0
        offset = keysLen;
14570
0
        keysLen *= 2;
14571
14572
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
14573
0
            return BAD_STATE_E;
14574
14575
0
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14576
0
    }
14577
358
    else if (ctx->protocol == REQ_RESP_SERVER) {
14578
0
        if (ctx->srvSt != ecSRV_SALT_SET)
14579
0
            return BAD_STATE_E;
14580
14581
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
14582
0
    }
14583
14584
358
    if (keysLen > ECC_BUFSIZE) /* keys size */
14585
0
        return BUFFER_E;
14586
14587
#ifdef WOLFSSL_ECIES_OLD
14588
    if (((msgSz - digestSz) % blockSz) != 0)
14589
        return BAD_PADDING_E;
14590
14591
    if (*outSz < (msgSz - digestSz))
14592
        return BUFFER_E;
14593
#elif defined(WOLFSSL_ECIES_GEN_IV)
14594
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
14595
        return BAD_PADDING_E;
14596
14597
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
14598
        return BAD_FUNC_ARG;
14599
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
14600
        return BUFFER_E;
14601
#else
14602
358
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14603
123
        return BAD_PADDING_E;
14604
14605
235
    if (msgSz < pubKeySz + blockSz + digestSz)
14606
18
        return BAD_FUNC_ARG;
14607
217
    if (*outSz < (msgSz - digestSz - pubKeySz))
14608
16
        return BUFFER_E;
14609
201
#endif
14610
14611
201
#ifdef ECC_TIMING_RESISTANT
14612
201
    if (ctx->rng != NULL && privKey->rng == NULL)
14613
0
        privKey->rng = ctx->rng;
14614
201
#endif
14615
14616
201
#ifdef WOLFSSL_SMALL_STACK
14617
201
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14618
201
    if (sharedSecret == NULL) {
14619
14
    #ifndef WOLFSSL_ECIES_OLD
14620
14
        if (pubKey == peerKey)
14621
0
            wc_ecc_free(peerKey);
14622
14
    #endif
14623
14
        return MEMORY_E;
14624
14
    }
14625
14626
187
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14627
187
    if (keys == NULL) {
14628
10
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14629
10
    #ifndef WOLFSSL_ECIES_OLD
14630
10
        if (pubKey == peerKey)
14631
0
            wc_ecc_free(peerKey);
14632
10
    #endif
14633
10
        return MEMORY_E;
14634
10
    }
14635
177
#endif
14636
14637
177
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14638
14639
177
#ifndef WOLFSSL_ECIES_OLD
14640
177
    if (pubKey == NULL) {
14641
0
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
14642
0
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
14643
0
        pubKey = peerKey;
14644
0
    }
14645
177
    else {
14646
        /* if a public key was passed in we should free it here before init
14647
         * and import */
14648
177
        wc_ecc_free(pubKey);
14649
177
    }
14650
177
    if (ret == 0) {
14651
177
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14652
177
    }
14653
177
    if (ret == 0) {
14654
177
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14655
177
    }
14656
177
    if (ret == 0) {
14657
        /* Point is not MACed. */
14658
90
        msg += pubKeySz;
14659
90
        msgSz -= pubKeySz;
14660
90
    }
14661
177
#endif
14662
14663
177
    if (ret == 0) {
14664
    #ifdef WOLFSSL_ECIES_ISO18033
14665
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14666
        sharedSz -= pubKeySz;
14667
    #endif
14668
14669
90
        do {
14670
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14671
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
14672
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
14673
            if (ret != 0)
14674
                break;
14675
        #endif
14676
90
        #ifndef WOLFSSL_ECIES_ISO18033
14677
90
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14678
90
                                                                    &sharedSz);
14679
        #else
14680
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14681
                                                          pubKeySz, &sharedSz);
14682
        #endif
14683
90
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14684
90
    }
14685
177
    if (ret == 0) {
14686
    #ifdef WOLFSSL_ECIES_ISO18033
14687
        /* KDF data is encoded public key and secret. */
14688
        sharedSz += pubKeySz;
14689
    #endif
14690
81
        switch (ctx->kdfAlgo) {
14691
81
            case ecHKDF_SHA256 :
14692
81
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14693
81
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14694
81
                           keys, (word32)keysLen);
14695
81
                break;
14696
0
            case ecHKDF_SHA1 :
14697
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14698
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14699
0
                           keys, (word32)keysLen);
14700
0
                break;
14701
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14702
0
            case ecKDF_X963_SHA1 :
14703
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14704
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14705
0
                break;
14706
0
            case ecKDF_X963_SHA256 :
14707
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14708
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14709
0
                break;
14710
0
            case ecKDF_SHA1 :
14711
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14712
0
                           NULL, 0, keys, (word32)keysLen);
14713
0
                break;
14714
0
            case ecKDF_SHA256 :
14715
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14716
0
                           NULL, 0, keys, (word32)keysLen);
14717
0
                break;
14718
0
#endif
14719
14720
0
            default:
14721
0
                ret = BAD_FUNC_ARG;
14722
0
                break;
14723
81
         }
14724
81
    }
14725
14726
177
    if (ret == 0) {
14727
    #ifdef WOLFSSL_ECIES_OLD
14728
        encKey = keys + offset;
14729
        encIv  = encKey + encKeySz;
14730
        macKey = encKey + encKeySz + ivSz;
14731
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14732
        encKey = keys + offset;
14733
        encIv  = msg;
14734
        msg   += ivSz;
14735
        msgSz -= ivSz;
14736
        macKey = encKey + encKeySz;
14737
    #else
14738
81
        XMEMSET(iv, 0, (size_t)ivSz);
14739
81
        encKey = keys + offset;
14740
81
        encIv  = iv;
14741
81
        macKey = encKey + encKeySz;
14742
81
    #endif
14743
14744
81
        switch (ctx->macAlgo) {
14745
81
            case ecHMAC_SHA256:
14746
81
            {
14747
81
                byte verify[WC_SHA256_DIGEST_SIZE];
14748
81
            #ifdef WOLFSSL_SMALL_STACK
14749
81
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14750
81
                                             DYNAMIC_TYPE_HMAC);
14751
81
                if (hmac == NULL) {
14752
0
                    ret = MEMORY_E;
14753
0
                    break;
14754
0
                }
14755
            #else
14756
                Hmac hmac[1];
14757
            #endif
14758
81
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14759
81
                if (ret == 0) {
14760
81
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14761
81
                                                         WC_SHA256_DIGEST_SIZE);
14762
81
                    if (ret == 0)
14763
81
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14764
81
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
14765
                    #else
14766
                        /* IV is before encrypted message. */
14767
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
14768
                    #endif
14769
81
                    if (ret == 0)
14770
81
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14771
14772
81
                    if (ret == 0)
14773
81
                        ret = wc_HmacFinal(hmac, verify);
14774
81
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14775
81
                                                             digestSz) != 0)) {
14776
60
                        ret = HASH_TYPE_E;
14777
60
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14778
60
                    }
14779
14780
81
                    wc_HmacFree(hmac);
14781
81
                }
14782
81
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14783
81
                break;
14784
81
            }
14785
14786
0
            default:
14787
0
                ret = BAD_FUNC_ARG;
14788
0
                break;
14789
81
        }
14790
81
    }
14791
14792
177
    if (ret == 0) {
14793
21
        switch (ctx->encAlgo) {
14794
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14795
21
            case ecAES_128_CBC:
14796
21
            case ecAES_256_CBC:
14797
21
            {
14798
21
            #ifdef WOLFSSL_SMALL_STACK
14799
21
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14800
21
                                          DYNAMIC_TYPE_AES);
14801
21
                if (aes == NULL) {
14802
0
                    ret = MEMORY_E;
14803
0
                    break;
14804
0
                }
14805
            #else
14806
                Aes aes[1];
14807
            #endif
14808
21
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14809
21
                if (ret == 0) {
14810
21
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14811
21
                                                                AES_DECRYPTION);
14812
21
                    if (ret == 0) {
14813
21
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
14814
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14815
                                                    defined(WC_ASYNC_ENABLE_AES)
14816
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14817
                                                            WC_ASYNC_FLAG_NONE);
14818
                    #endif
14819
21
                    }
14820
21
                    wc_AesFree(aes);
14821
21
                }
14822
21
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14823
21
                break;
14824
21
            }
14825
0
        #endif
14826
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14827
0
            case ecAES_128_CTR:
14828
0
            case ecAES_256_CTR:
14829
0
            {
14830
0
            #ifdef WOLFSSL_SMALL_STACK
14831
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14832
0
                                          DYNAMIC_TYPE_AES);
14833
0
                if (aes == NULL) {
14834
0
                    ret = MEMORY_E;
14835
0
                    break;
14836
0
                }
14837
             #else
14838
                Aes aes[1];
14839
             #endif
14840
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14841
0
                if (ret == 0) {
14842
0
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
14843
                    /* Make a 16 byte IV from the bytes passed in. */
14844
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14845
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14846
0
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14847
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14848
0
                                                                AES_ENCRYPTION);
14849
0
                    if (ret == 0) {
14850
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
14851
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14852
                                                    defined(WC_ASYNC_ENABLE_AES)
14853
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14854
                                                            WC_ASYNC_FLAG_NONE);
14855
                    #endif
14856
0
                    }
14857
0
                    wc_AesFree(aes);
14858
0
                }
14859
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14860
0
                break;
14861
0
            }
14862
0
        #endif
14863
0
            default:
14864
0
                ret = BAD_FUNC_ARG;
14865
0
                break;
14866
21
        }
14867
21
    }
14868
14869
177
    if (ret == 0)
14870
21
       *outSz = msgSz - digestSz;
14871
14872
177
    RESTORE_VECTOR_REGISTERS();
14873
14874
177
#ifndef WOLFSSL_ECIES_OLD
14875
177
    if (pubKey == peerKey)
14876
0
        wc_ecc_free(peerKey);
14877
177
#endif
14878
177
#ifdef WOLFSSL_SMALL_STACK
14879
177
#ifndef WOLFSSL_ECIES_OLD
14880
177
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14881
177
#endif
14882
177
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14883
177
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14884
177
#endif
14885
14886
177
    return ret;
14887
177
}
14888
14889
14890
#endif /* HAVE_ECC_ENCRYPT */
14891
14892
14893
#ifdef HAVE_COMP_KEY
14894
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
14895
    !defined(WOLFSSL_CRYPTOCELL)
14896
14897
#ifndef WOLFSSL_SP_MATH
14898
#if !defined(SQRTMOD_USE_MOD_EXP)
14899
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
14900
 */
14901
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
14902
{
14903
#ifdef WOLFSSL_SMALL_STACK
14904
    mp_int*  a1 = NULL;
14905
    mp_int*  n1 = NULL;
14906
#else
14907
    mp_int   a1[1], n1[1];
14908
#endif
14909
    int      res;
14910
    int      s = 1;
14911
    int      k;
14912
    mp_int*  t[2];
14913
    mp_int*  ts;
14914
    mp_digit residue;
14915
14916
    if (mp_isneg(a) == MP_YES) {
14917
        return MP_VAL;
14918
    }
14919
    if (mp_isneg(n) == MP_YES) {
14920
        return MP_VAL;
14921
    }
14922
    if (mp_iseven(n) == MP_YES) {
14923
        return MP_VAL;
14924
    }
14925
14926
#ifdef WOLFSSL_SMALL_STACK
14927
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14928
    if (a1 == NULL) {
14929
        return MP_MEM;
14930
    }
14931
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14932
    if (n1 == NULL) {
14933
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
14934
        return MP_MEM;
14935
    }
14936
#endif
14937
14938
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
14939
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14940
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14941
        return res;
14942
    }
14943
14944
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
14945
14946
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
14947
        goto done;
14948
    }
14949
14950
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
14951
        goto done;
14952
    }
14953
14954
    t[0] = a1;
14955
    t[1] = n1;
14956
14957
    /* Keep reducing until first number is 0. */
14958
    while (!mp_iszero(t[0])) {
14959
        /* Divide by 2 until odd. */
14960
        k = mp_cnt_lsb(t[0]);
14961
        if (k > 0) {
14962
            mp_rshb(t[0], k);
14963
14964
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
14965
             * Odd number of divides results in a negate.
14966
             */
14967
            residue = t[1]->dp[0] & 7;
14968
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
14969
                s = -s;
14970
            }
14971
        }
14972
14973
        /* Swap t[0] and t[1]. */
14974
        ts   = t[0];
14975
        t[0] = t[1];
14976
        t[1] = ts;
14977
14978
        /* Negate s if both numbers == 3 mod 4. */
14979
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
14980
             s = -s;
14981
        }
14982
14983
        /* Reduce first number modulo second. */
14984
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
14985
            res = mp_sub(t[0], t[1], t[0]);
14986
        }
14987
        else {
14988
            res = mp_mod(t[0], t[1], t[0]);
14989
        }
14990
        if (res != MP_OKAY) {
14991
            goto done;
14992
        }
14993
    }
14994
14995
    /* When the two numbers have divisors in common. */
14996
    if (!mp_isone(t[1])) {
14997
        s = 0;
14998
    }
14999
    *c = s;
15000
15001
done:
15002
15003
    RESTORE_VECTOR_REGISTERS();
15004
15005
    /* cleanup */
15006
    mp_clear(n1);
15007
    mp_clear(a1);
15008
15009
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
15010
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
15011
15012
  return res;
15013
}
15014
#endif /* !SQRTMOD_USE_MOD_EXP */
15015
15016
15017
/* Solves the modular equation x^2 = n (mod p)
15018
 * where prime number is greater than 2 (odd prime).
15019
 * The result is returned in the third argument x
15020
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
15021
 */
15022
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
15023
{
15024
#if defined(SQRTMOD_USE_MOD_EXP)
15025
  int res;
15026
  mp_digit i;
15027
  mp_int e;
15028
15029
  /* first handle the simple cases n = 0 or n = 1 */
15030
  if (mp_cmp_d(n, 0) == MP_EQ) {
15031
      mp_zero(ret);
15032
      return MP_OKAY;
15033
  }
15034
  if (mp_cmp_d(n, 1) == MP_EQ) {
15035
      return mp_set(ret, 1);
15036
  }
15037
15038
  if (mp_iseven(prime)) {
15039
      return MP_VAL;
15040
  }
15041
15042
  SAVE_VECTOR_REGISTERS(return _svr_ret;);
15043
15044
  res = mp_init(&e);
15045
  if (res == MP_OKAY)
15046
      res = mp_mod_d(prime, 8, &i);
15047
  if (res == MP_OKAY && i == 1) {
15048
      return MP_VAL;
15049
  }
15050
  /* prime mod 8 = 5 */
15051
  else if (res == MP_OKAY && i == 5) {
15052
      res = mp_sub_d(prime, 1, &e);
15053
      if (res == MP_OKAY)
15054
          res = mp_div_2d(&e, 2, &e, NULL);
15055
  }
15056
  /* prime mod 4 = 3 */
15057
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
15058
      res = mp_add_d(prime, 1, &e);
15059
      if (res == MP_OKAY)
15060
          res = mp_div_2d(&e, 2, &e, NULL);
15061
  }
15062
  if (res == MP_OKAY)
15063
      res = mp_exptmod(n, &e, prime, ret);
15064
15065
  mp_clear(&e);
15066
15067
  RESTORE_VECTOR_REGISTERS();
15068
15069
  return res;
15070
#else
15071
  int res, legendre, done = 0;
15072
  mp_digit i;
15073
#ifdef WOLFSSL_SMALL_STACK
15074
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15075
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15076
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15077
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15078
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15079
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15080
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15081
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15082
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15083
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15084
#else
15085
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
15086
#endif
15087
15088
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15089
15090
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15091
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15092
    res = MP_INIT_E;
15093
    goto out;
15094
  }
15095
15096
#ifdef WOLFSSL_SMALL_STACK
15097
  if ((t1 == NULL) ||
15098
      (C == NULL) ||
15099
      (Q == NULL) ||
15100
      (S == NULL) ||
15101
      (Z == NULL) ||
15102
      (M == NULL) ||
15103
      (T == NULL) ||
15104
      (R == NULL) ||
15105
      (N == NULL) ||
15106
      (two == NULL)) {
15107
    res = MP_MEM;
15108
    goto out;
15109
  }
15110
#endif
15111
15112
  /* first handle the simple cases n = 0 or n = 1 */
15113
  if (mp_cmp_d(n, 0) == MP_EQ) {
15114
    mp_zero(ret);
15115
    res = MP_OKAY;
15116
    goto out;
15117
  }
15118
  if (mp_cmp_d(n, 1) == MP_EQ) {
15119
    res = mp_set(ret, 1);
15120
    goto out;
15121
  }
15122
15123
  /* prime must be odd */
15124
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15125
    res = MP_VAL;
15126
    goto out;
15127
  }
15128
15129
  /* reduce n to less than prime */
15130
  res = mp_mod(n, prime, N);
15131
  if (res != MP_OKAY) {
15132
    goto out;
15133
  }
15134
  /* when N is zero, sqrt is zero */
15135
  if (mp_iszero(N)) {
15136
    mp_set(ret, 0);
15137
    goto out;
15138
  }
15139
15140
  /* is quadratic non-residue mod prime */
15141
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15142
    goto out;
15143
  }
15144
  if (legendre == -1) {
15145
    res = MP_VAL;
15146
    goto out;
15147
  }
15148
15149
  /* SPECIAL CASE: if prime mod 4 == 3
15150
   * compute directly: res = n^(prime+1)/4 mod prime
15151
   * Handbook of Applied Cryptography algorithm 3.36
15152
   */
15153
  res = mp_mod_d(prime, 4, &i);
15154
  if (res == MP_OKAY && i == 3) {
15155
    res = mp_add_d(prime, 1, t1);
15156
15157
    if (res == MP_OKAY)
15158
      res = mp_div_2(t1, t1);
15159
    if (res == MP_OKAY)
15160
      res = mp_div_2(t1, t1);
15161
    if (res == MP_OKAY)
15162
      res = mp_exptmod(N, t1, prime, ret);
15163
15164
    done = 1;
15165
  }
15166
15167
  /* NOW: TonelliShanks algorithm */
15168
  if (res == MP_OKAY && done == 0) {
15169
15170
    /* factor out powers of 2 from prime-1, defining Q and S
15171
    *                                      as: prime-1 = Q*2^S */
15172
    /* Q = prime - 1 */
15173
    res = mp_copy(prime, Q);
15174
    if (res == MP_OKAY)
15175
      res = mp_sub_d(Q, 1, Q);
15176
15177
    /* S = 0 */
15178
    if (res == MP_OKAY)
15179
      mp_zero(S);
15180
15181
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15182
      /* Q = Q / 2 */
15183
      res = mp_div_2(Q, Q);
15184
15185
      /* S = S + 1 */
15186
      if (res == MP_OKAY)
15187
        res = mp_add_d(S, 1, S);
15188
    }
15189
15190
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15191
    /* Z = 2 */
15192
    if (res == MP_OKAY)
15193
      res = mp_set_int(Z, 2);
15194
15195
    while (res == MP_OKAY) {
15196
      res = mp_jacobi(Z, prime, &legendre);
15197
      if (res == MP_OKAY && legendre == -1)
15198
        break;
15199
15200
#if defined(WOLFSSL_CUSTOM_CURVES)
15201
      /* P224R1 succeeds with a value of 11. */
15202
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15203
        /* This is to clamp the loop in case 'prime' is not really prime */
15204
        res = MP_VAL;
15205
        break;
15206
      }
15207
#endif
15208
15209
      /* Z = Z + 1 */
15210
      if (res == MP_OKAY)
15211
        res = mp_add_d(Z, 1, Z);
15212
15213
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
15214
        /* This is to clamp the loop in case 'prime' is not really prime */
15215
        res = MP_VAL;
15216
        break;
15217
      }
15218
    }
15219
15220
    /* C = Z ^ Q mod prime */
15221
    if (res == MP_OKAY)
15222
      res = mp_exptmod(Z, Q, prime, C);
15223
15224
    /* t1 = (Q + 1) / 2 */
15225
    if (res == MP_OKAY)
15226
      res = mp_add_d(Q, 1, t1);
15227
    if (res == MP_OKAY)
15228
      res = mp_div_2(t1, t1);
15229
15230
    /* R = n ^ ((Q + 1) / 2) mod prime */
15231
    if (res == MP_OKAY)
15232
      res = mp_exptmod(N, t1, prime, R);
15233
15234
    /* T = n ^ Q mod prime */
15235
    if (res == MP_OKAY)
15236
      res = mp_exptmod(N, Q, prime, T);
15237
15238
    /* M = S */
15239
    if (res == MP_OKAY)
15240
      res = mp_copy(S, M);
15241
15242
    if (res == MP_OKAY)
15243
      res = mp_set_int(two, 2);
15244
15245
    while (res == MP_OKAY && done == 0) {
15246
      res = mp_copy(T, t1);
15247
15248
      /* reduce to 1 and count */
15249
      i = 0;
15250
      while (res == MP_OKAY) {
15251
        if (mp_cmp_d(t1, 1) == MP_EQ)
15252
            break;
15253
        res = mp_exptmod(t1, two, prime, t1);
15254
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
15255
          /* This is to clamp the loop in case 'prime' is not really prime */
15256
          res = MP_VAL;
15257
          break;
15258
        }
15259
        if (res == MP_OKAY)
15260
          i++;
15261
      }
15262
      if (res == MP_OKAY && i == 0) {
15263
        res = mp_copy(R, ret);
15264
        done = 1;
15265
      }
15266
15267
      if (done == 0) {
15268
        /* t1 = 2 ^ (M - i - 1) */
15269
        if (res == MP_OKAY)
15270
          res = mp_sub_d(M, i, t1);
15271
        if (res == MP_OKAY)
15272
          res = mp_sub_d(t1, 1, t1);
15273
        if (res == MP_OKAY)
15274
          res = mp_exptmod(two, t1, prime, t1);
15275
15276
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15277
        if (res == MP_OKAY)
15278
          res = mp_exptmod(C, t1, prime, t1);
15279
15280
        /* C = (t1 * t1) mod prime */
15281
        if (res == MP_OKAY)
15282
          res = mp_sqrmod(t1, prime, C);
15283
15284
        /* R = (R * t1) mod prime */
15285
        if (res == MP_OKAY)
15286
          res = mp_mulmod(R, t1, prime, R);
15287
15288
        /* T = (T * C) mod prime */
15289
        if (res == MP_OKAY)
15290
          res = mp_mulmod(T, C, prime, T);
15291
15292
        /* M = i */
15293
        if (res == MP_OKAY)
15294
          res = mp_set(M, i);
15295
      }
15296
    }
15297
  }
15298
15299
  out:
15300
15301
  RESTORE_VECTOR_REGISTERS();
15302
15303
#ifdef WOLFSSL_SMALL_STACK
15304
  if (t1) {
15305
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15306
      mp_clear(t1);
15307
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15308
  }
15309
  if (C) {
15310
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15311
      mp_clear(C);
15312
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15313
  }
15314
  if (Q) {
15315
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15316
      mp_clear(Q);
15317
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15318
  }
15319
  if (S) {
15320
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15321
      mp_clear(S);
15322
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15323
  }
15324
  if (Z) {
15325
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15326
      mp_clear(Z);
15327
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15328
  }
15329
  if (M) {
15330
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15331
      mp_clear(M);
15332
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15333
  }
15334
  if (T) {
15335
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15336
      mp_clear(T);
15337
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15338
  }
15339
  if (R) {
15340
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15341
      mp_clear(R);
15342
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15343
  }
15344
  if (N) {
15345
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15346
      mp_clear(N);
15347
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15348
  }
15349
  if (two) {
15350
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15351
      mp_clear(two);
15352
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15353
  }
15354
#else
15355
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
15356
    mp_clear(t1);
15357
    mp_clear(C);
15358
    mp_clear(Q);
15359
    mp_clear(S);
15360
    mp_clear(Z);
15361
    mp_clear(M);
15362
    mp_clear(T);
15363
    mp_clear(R);
15364
    mp_clear(N);
15365
    mp_clear(two);
15366
  }
15367
#endif
15368
15369
  return res;
15370
#endif
15371
}
15372
#endif /* !WOLFSSL_SP_MATH */
15373
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
15374
15375
#ifdef HAVE_ECC_KEY_EXPORT
15376
/* export public ECC key in ANSI X9.63 format compressed */
15377
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
15378
2.56k
{
15379
2.56k
   word32 numlen;
15380
2.56k
   int    ret = MP_OKAY;
15381
15382
2.56k
   if (key == NULL || outLen == NULL)
15383
0
       return BAD_FUNC_ARG;
15384
15385
2.56k
   if (key->type == ECC_PRIVATEKEY_ONLY)
15386
73
       return ECC_PRIVATEONLY_E;
15387
15388
2.49k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15389
394
       return ECC_BAD_ARG_E;
15390
394
   }
15391
15392
2.10k
   numlen = (word32)key->dp->size;
15393
15394
2.10k
   if (*outLen < (1 + numlen)) {
15395
1.05k
      *outLen = 1 + numlen;
15396
1.05k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15397
1.05k
   }
15398
15399
1.05k
   if (out == NULL)
15400
0
       return BAD_FUNC_ARG;
15401
15402
1.05k
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15403
0
       return ECC_BAD_ARG_E;
15404
15405
   /* store first byte */
15406
1.05k
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15407
15408
   /* pad and store x */
15409
1.05k
   XMEMSET(out+1, 0, numlen);
15410
1.05k
   ret = mp_to_unsigned_bin(
15411
1.05k
       key->pubkey.x,
15412
1.05k
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15413
1.05k
   *outLen = 1 + numlen;
15414
15415
1.05k
   return ret;
15416
1.05k
}
15417
#endif /* HAVE_ECC_KEY_EXPORT */
15418
#endif /* HAVE_COMP_KEY */
15419
15420
#ifdef HAVE_OID_ENCODING
15421
int wc_ecc_oid_cache_init(void)
15422
{
15423
    int ret = 0;
15424
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15425
    ret = wc_InitMutex(&ecc_oid_cache_lock);
15426
#endif
15427
    return ret;
15428
}
15429
15430
void wc_ecc_oid_cache_free(void)
15431
{
15432
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15433
    wc_FreeMutex(&ecc_oid_cache_lock);
15434
#endif
15435
}
15436
#endif /* HAVE_OID_ENCODING */
15437
15438
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
15439
7.11k
{
15440
7.11k
    int x;
15441
7.11k
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
15442
#ifdef HAVE_OID_ENCODING
15443
    oid_cache_t* o = NULL;
15444
#endif
15445
15446
7.11k
    if (oidSum == 0) {
15447
34
        return BAD_FUNC_ARG;
15448
34
    }
15449
15450
#ifdef HAVE_OID_ENCODING
15451
    #ifndef WOLFSSL_MUTEX_INITIALIZER
15452
        /* extra sanity check if wolfCrypt_Init not called */
15453
        if (eccOidLockInit == 0) {
15454
            wc_InitMutex(&ecc_oid_cache_lock);
15455
            eccOidLockInit = 1;
15456
        }
15457
    #endif
15458
15459
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
15460
        return BAD_MUTEX_E;
15461
    }
15462
#endif
15463
15464
    /* find matching OID sum (based on encoded value) */
15465
32.5k
    for (x = 0; ecc_sets[x].size != 0; x++) {
15466
29.4k
        if (ecc_sets[x].oidSum == oidSum) {
15467
        #ifdef HAVE_OID_ENCODING
15468
            /* check cache */
15469
            ret = 0;
15470
            o = &ecc_oid_cache[x];
15471
            if (o->oidSz == 0) {
15472
                o->oidSz = sizeof(o->oid);
15473
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
15474
                                                            o->oid, &o->oidSz);
15475
            }
15476
            if (oidSz) {
15477
                *oidSz = o->oidSz;
15478
            }
15479
            if (oid) {
15480
                *oid = o->oid;
15481
            }
15482
15483
            /* on success return curve id */
15484
            if (ret == 0) {
15485
                ret = ecc_sets[x].id;
15486
            }
15487
            break;
15488
        #else
15489
3.96k
            if (oidSz) {
15490
3.96k
                *oidSz = ecc_sets[x].oidSz;
15491
3.96k
            }
15492
3.96k
            if (oid) {
15493
3.96k
                *oid = ecc_sets[x].oid;
15494
3.96k
            }
15495
3.96k
            ret = ecc_sets[x].id;
15496
3.96k
            break;
15497
3.96k
        #endif
15498
3.96k
        }
15499
29.4k
    }
15500
15501
#ifdef HAVE_OID_ENCODING
15502
    wc_UnLockMutex(&ecc_oid_cache_lock);
15503
#endif
15504
15505
7.07k
    return ret;
15506
7.11k
}
15507
15508
#ifdef WOLFSSL_CUSTOM_CURVES
15509
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15510
{
15511
    if (key == NULL || dp == NULL) {
15512
        return BAD_FUNC_ARG;
15513
    }
15514
15515
    key->idx = ECC_CUSTOM_IDX;
15516
    key->dp = dp;
15517
15518
    return 0;
15519
}
15520
#endif /* WOLFSSL_CUSTOM_CURVES */
15521
15522
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15523
15524
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
15525
0
{
15526
0
    int i;
15527
15528
    /* in network byte order so start at end and work back */
15529
0
    for (i = 3; i >= 0; i--) {
15530
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
15531
0
            return;
15532
0
    }
15533
0
}
15534
15535
/* ASN X9.63 Key Derivation Function (SEC1) */
15536
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
15537
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
15538
0
{
15539
0
    int ret;
15540
0
    word32 digestSz, copySz, remaining = outSz;
15541
0
    byte* outIdx;
15542
0
    byte  counter[4];
15543
0
    byte  tmp[WC_MAX_DIGEST_SIZE];
15544
15545
0
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
15546
15547
0
    if (secret == NULL || secretSz == 0 || out == NULL)
15548
0
        return BAD_FUNC_ARG;
15549
15550
    /* X9.63 allowed algos only */
15551
0
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
15552
0
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
15553
0
        type != WC_HASH_TYPE_SHA512)
15554
0
        return BAD_FUNC_ARG;
15555
15556
0
    ret = wc_HashGetDigestSize(type);
15557
0
    if (ret < 0)
15558
0
        return ret;
15559
0
    digestSz = (word32)ret;
15560
15561
0
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
15562
0
        return MEMORY_E);
15563
15564
0
    ret = wc_HashInit(hash, type);
15565
0
    if (ret != 0) {
15566
0
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15567
0
        return ret;
15568
0
    }
15569
15570
0
    outIdx = out;
15571
0
    XMEMSET(counter, 0, sizeof(counter));
15572
15573
0
    while (remaining > 0) {
15574
15575
0
        IncrementX963KdfCounter(counter);
15576
15577
0
        ret = wc_HashUpdate(hash, type, secret, secretSz);
15578
0
        if (ret != 0) {
15579
0
            break;
15580
0
        }
15581
15582
0
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
15583
0
        if (ret != 0) {
15584
0
            break;
15585
0
        }
15586
15587
0
        if (sinfo) {
15588
0
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
15589
0
            if (ret != 0) {
15590
0
                break;
15591
0
            }
15592
0
        }
15593
15594
0
        ret = wc_HashFinal(hash, type, tmp);
15595
0
        if (ret != 0) {
15596
0
            break;
15597
0
        }
15598
15599
0
        copySz = min(remaining, digestSz);
15600
0
        XMEMCPY(outIdx, tmp, copySz);
15601
15602
0
        remaining -= copySz;
15603
0
        outIdx += copySz;
15604
0
    }
15605
15606
0
    wc_HashFree(hash, type);
15607
15608
0
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15609
15610
0
    return ret;
15611
0
}
15612
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
15613
15614
#ifdef WOLFSSL_SE050
15615
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
15616
 * keyId is a word32, can be used for key IDs larger than an int.
15617
 *
15618
 * key    initialized ecc_key struct
15619
 * keyId  hardware key ID which stores ECC key
15620
 * flags  optional flags, currently unused
15621
 *
15622
 * Return 0 on success, negative on error */
15623
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
15624
{
15625
    (void)flags;
15626
15627
    if (key == NULL) {
15628
        return BAD_FUNC_ARG;
15629
    }
15630
15631
    return se050_ecc_use_key_id(key, keyId);
15632
}
15633
15634
/* Get hardware key ID associated with this ecc_key structure.
15635
 *
15636
 * key    initialized ecc_key struct
15637
 * keyId  [OUT] output for key ID associated with this structure
15638
 *
15639
 * Returns 0 on success, negative on error.
15640
 */
15641
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
15642
{
15643
    if (key == NULL || keyId == NULL) {
15644
        return BAD_FUNC_ARG;
15645
    }
15646
15647
    return se050_ecc_get_key_id(key, keyId);
15648
}
15649
#endif /* WOLFSSL_SE050 */
15650
15651
15652
#ifdef WC_ECC_NONBLOCK
15653
/* Enable ECC support for non-blocking operations */
15654
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
15655
{
15656
    if (key == NULL) {
15657
        return BAD_FUNC_ARG;
15658
    }
15659
    /* If a different context is already set, clear it before replacing.
15660
     * The caller is responsible for freeing any heap-allocated context. */
15661
    if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
15662
        XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
15663
    }
15664
    if (ctx != NULL) {
15665
        XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
15666
    }
15667
    key->nb_ctx = ctx;
15668
    return 0;
15669
}
15670
#endif /* WC_ECC_NONBLOCK */
15671
15672
#endif /* HAVE_ECC */