Coverage Report

Created: 2025-09-01 06:47

/src/wolfssl/wolfcrypt/src/ecc.c
Line
Count
Source (jump to first uncovered line)
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
25
#undef WOLFSSL_SMALL_STACK
26
#undef WOLFSSL_SMALL_STACK_CACHE
27
#endif
28
29
/*
30
Possible ECC enable options:
31
 * HAVE_ECC:            Overall control of ECC                  default: on
32
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
33
 * HAVE_ECC_SIGN:       ECC sign                                default: on
34
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
35
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
36
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
37
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
38
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
39
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
40
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
41
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
42
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
43
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
44
 *                        Includes the curve "a" variable in calculation
45
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
46
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
47
 *                                                              default: off
48
 * FP_ECC:              ECC Fixed Point Cache                   default: off
49
 *                      FP cache is not supported for SECP160R1, SECP160R2,
50
 *                      SECP160K1 and SECP224K1. These do not work with scalars
51
 *                      that are the length of the order when the order is
52
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
53
 * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
54
 *                      (on for HAVE_COMP_KEY)
55
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
56
 *                      For the ECC curve parameters `ecc_set_type` use fixed
57
 *                      array for hex string
58
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
59
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
60
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
61
 *                      normal blocking API's
62
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
63
 *                      signing. If the value is invalid, a new random 'k' is
64
 *                      generated in the loop. (For testing)
65
 *                                                              default: off
66
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
67
 *                      Enables the setting of the 'k' value to use during ECDSA
68
 *                      signing. If the value is invalid then an error is
69
 *                      returned rather than generating a new 'k'. (For testing)
70
 *                                                              default: off
71
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
72
 *                      deterministic ECC signatures. The following function
73
 *                      can be used to set the deterministic signing flag in the
74
 *                      ecc key structure.
75
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
76
 *                                                              default: off
77
 *
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
79
 *                      hash directly instead of doing bits2octets(H(m)), when
80
 *                      the variant macro is used the bits2octets operation on
81
 *                      the hash is removed.
82
 *                                                              default: off
83
 *
84
 * WC_PROTECT_ENCRYPTED_MEM:
85
 *                      Enables implementations that protect data that is in
86
 *                      encrypted memory.
87
 *                                                              default: off
88
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
89
 *                      Enables generation of scalar (private key and ECDSA
90
 *                      nonce) to be performed using reject sampling algorithm.
91
 *                      Use this when CPU state can be closely observed by
92
 *                      attacker.
93
 *                                                              default: off
94
 * WOLFSSL_ECC_BLIND_K
95
 *                      Blind the private key k by using a random mask.
96
 *                      The private key is never stored unprotected but an
97
 *                      unmasked copy is computed and stored each time it is
98
 *                      needed.
99
 *                                                              default: off
100
 * WOLFSSL_CHECK_VER_FAULTS
101
 *                      Sanity check on verification steps in case of faults.
102
 *                                                              default: off
103
 */
104
105
/*
106
ECC Curve Types:
107
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
108
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
109
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
110
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
111
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
112
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
113
 */
114
115
/*
116
ECC Curve Sizes:
117
 * ECC_USER_CURVES: Allows custom combination of key sizes below
118
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
119
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
120
 * HAVE_ECC112: 112 bit key
121
 * HAVE_ECC128: 128 bit key
122
 * HAVE_ECC160: 160 bit key
123
 * HAVE_ECC192: 192 bit key
124
 * HAVE_ECC224: 224 bit key
125
 * HAVE_ECC239: 239 bit key
126
 * NO_ECC256: Disables 256 bit key (on by default)
127
 * HAVE_ECC320: 320 bit key
128
 * HAVE_ECC384: 384 bit key
129
 * HAVE_ECC512: 512 bit key
130
 * HAVE_ECC521: 521 bit key
131
 */
132
133
134
#ifdef HAVE_ECC
135
136
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
137
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
138
    !defined(WOLFSSL_CUSTOM_CURVES)
139
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
140
#endif
141
142
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
143
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
144
    #define FIPS_NO_WRAPPERS
145
146
    #ifdef USE_WINDOWS_API
147
        #pragma code_seg(".fipsA$f")
148
        #pragma const_seg(".fipsB$f")
149
    #endif
150
#endif
151
152
/* public ASN interface */
153
#include <wolfssl/wolfcrypt/asn_public.h>
154
155
#include <wolfssl/wolfcrypt/ecc.h>
156
#include <wolfssl/wolfcrypt/asn.h>
157
158
#ifdef WOLFSSL_HAVE_SP_ECC
159
#include <wolfssl/wolfcrypt/sp.h>
160
#endif
161
162
#ifdef HAVE_ECC_ENCRYPT
163
    #include <wolfssl/wolfcrypt/kdf.h>
164
    #include <wolfssl/wolfcrypt/aes.h>
165
#endif
166
167
#ifdef HAVE_X963_KDF
168
    #include <wolfssl/wolfcrypt/hash.h>
169
#endif
170
171
#ifdef WOLF_CRYPTO_CB
172
    #include <wolfssl/wolfcrypt/cryptocb.h>
173
#endif
174
175
#ifdef NO_INLINE
176
    #include <wolfssl/wolfcrypt/misc.h>
177
#else
178
    #define WOLFSSL_MISC_INCLUDED
179
    #include <wolfcrypt/src/misc.c>
180
#endif
181
182
#if FIPS_VERSION3_GE(6,0,0)
183
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
184
                                                     { 0x1a2b3c4d, 0x00000005 };
185
    int wolfCrypt_FIPS_ECC_sanity(void)
186
    {
187
        return 0;
188
    }
189
#endif
190
191
#if defined(FREESCALE_LTC_ECC)
192
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
193
#endif
194
195
#if defined(WOLFSSL_STM32_PKA)
196
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
197
#endif
198
199
#if defined(WOLFSSL_PSOC6_CRYPTO)
200
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
201
#endif
202
203
#if defined(WOLFSSL_CAAM)
204
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
205
#endif
206
207
#if defined(WOLFSSL_KCAPI_ECC)
208
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
209
#endif
210
211
#ifdef WOLFSSL_SE050
212
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
213
#endif
214
215
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
216
    #include <xsecure_ellipticclient.h>
217
#endif
218
219
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
220
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
221
    #include <wolfssl/wolfcrypt/hmac.h>
222
#endif
223
224
#if defined(WOLFSSL_LINUXKM) && !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
    #undef  HAVE_ECC_VERIFY_HELPER
237
    #define HAVE_ECC_VERIFY_HELPER
238
#endif
239
240
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
241
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
242
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
243
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
244
    #undef  HAVE_ECC_MAKE_PUB
245
    #define HAVE_ECC_MAKE_PUB
246
#endif
247
248
249
/* macro guard for ecc_check_pubkey_order functionality */
250
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
251
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
252
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
253
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
254
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
255
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
256
257
    /* CAAM builds use public key validation as a means to check if an
258
     * imported private key is an encrypted black key or not */
259
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
260
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
261
#endif
262
263
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
264
#define MAX_ECC_BITS_USE    SP_INT_BITS
265
#else
266
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
267
#endif
268
269
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
270
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
271
272
#define ECC_KEY_MAX_BITS(key)                                       \
273
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
274
        ((unsigned)((key)->dp->size * 8)))
275
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
276
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
277
        ((unsigned)((key)->dp->size * 8)))
278
279
#else
280
281
/* Add one bit for cases when order is a bit greater than prime. */
282
#define ECC_KEY_MAX_BITS(key)                                       \
283
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
284
        ((unsigned)((key)->dp->size * 8 + 1)))
285
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
286
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
287
        ((unsigned)((key)->dp->size * 8 + 1)))
288
289
#endif
290
291
#ifdef WOLFSSL_ECC_BLIND_K
292
mp_int* ecc_get_k(ecc_key* key)
293
{
294
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
295
    return key->ku;
296
}
297
void ecc_blind_k(ecc_key* key, mp_int* b)
298
{
299
    mp_xor_ct(key->k, b, key->dp->size, key->k);
300
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
301
}
302
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
303
{
304
    int ret = 0;
305
    WC_RNG local_rng;
306
307
#ifdef ECC_TIMING_RESISTANT
308
    if (rng == NULL) {
309
        rng = key->rng;
310
    }
311
#endif
312
    if (rng == NULL) {
313
        ret = wc_InitRng(&local_rng);
314
        if (ret == 0) {
315
            rng = &local_rng;
316
        }
317
    }
318
    if (ret == 0) {
319
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
320
            sizeof(mp_digit), rng);
321
        if (ret == 0) {
322
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
323
        }
324
    }
325
326
    if (rng == &local_rng) {
327
        wc_FreeRng(&local_rng);
328
    }
329
    return ret;
330
}
331
332
mp_int* wc_ecc_key_get_priv(ecc_key* key)
333
{
334
    return ecc_get_k(key);
335
}
336
#endif
337
338
/* forward declarations */
339
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
340
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
341
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
342
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
343
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
344
#endif
345
346
/* internal ECC states */
347
enum {
348
    ECC_STATE_NONE = 0,
349
350
    ECC_STATE_SHARED_SEC_GEN,
351
    ECC_STATE_SHARED_SEC_RES,
352
353
    ECC_STATE_SIGN_DO,
354
    ECC_STATE_SIGN_ENCODE,
355
356
    ECC_STATE_VERIFY_DECODE,
357
    ECC_STATE_VERIFY_DO,
358
    ECC_STATE_VERIFY_RES
359
};
360
361
362
/* map
363
   ptmul -> mulmod
364
*/
365
366
/* 256-bit curve on by default whether user curves or not */
367
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
368
    #define ECC112
369
#endif
370
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
371
    #define ECC128
372
#endif
373
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
374
    #define ECC160
375
#endif
376
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
377
    #define ECC192
378
#endif
379
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
380
    #define ECC224
381
#endif
382
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
383
    #define ECC239
384
#endif
385
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
386
    #define ECC256
387
#endif
388
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
389
    #define ECC320
390
#endif
391
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
392
    #define ECC384
393
#endif
394
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
395
    #define ECC512
396
#endif
397
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
398
    #define ECC521
399
#endif
400
401
/* The encoded OID's for ECC curves */
402
#ifdef ECC112
403
    #ifndef NO_ECC_SECP
404
        #ifdef HAVE_OID_ENCODING
405
            #define CODED_SECP112R1    {1,3,132,0,6}
406
            #define CODED_SECP112R1_SZ 5
407
        #else
408
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
409
            #define CODED_SECP112R1_SZ 5
410
        #endif
411
        #ifndef WOLFSSL_ECC_CURVE_STATIC
412
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
413
        #else
414
            #define ecc_oid_secp112r1 CODED_SECP112R1
415
        #endif
416
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
417
    #endif /* !NO_ECC_SECP */
418
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
419
        #ifdef HAVE_OID_ENCODING
420
            #define CODED_SECP112R2    {1,3,132,0,7}
421
            #define CODED_SECP112R2_SZ 5
422
        #else
423
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
424
            #define CODED_SECP112R2_SZ 5
425
        #endif
426
        #ifndef WOLFSSL_ECC_CURVE_STATIC
427
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
428
        #else
429
            #define ecc_oid_secp112r2 CODED_SECP112R2
430
        #endif
431
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
432
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
433
#endif /* ECC112 */
434
#ifdef ECC128
435
    #ifndef NO_ECC_SECP
436
        #ifdef HAVE_OID_ENCODING
437
            #define CODED_SECP128R1    {1,3,132,0,28}
438
            #define CODED_SECP128R1_SZ 5
439
        #else
440
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
441
            #define CODED_SECP128R1_SZ 5
442
        #endif
443
        #ifndef WOLFSSL_ECC_CURVE_STATIC
444
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
445
        #else
446
            #define ecc_oid_secp128r1 CODED_SECP128R1
447
        #endif
448
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
449
    #endif /* !NO_ECC_SECP */
450
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
451
        #ifdef HAVE_OID_ENCODING
452
            #define CODED_SECP128R2    {1,3,132,0,29}
453
            #define CODED_SECP128R2_SZ 5
454
        #else
455
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
456
            #define CODED_SECP128R2_SZ 5
457
        #endif
458
        #ifndef WOLFSSL_ECC_CURVE_STATIC
459
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
460
        #else
461
            #define ecc_oid_secp128r2 CODED_SECP128R2
462
        #endif
463
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
464
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
465
#endif /* ECC128 */
466
#ifdef ECC160
467
#ifndef FP_ECC
468
    #ifndef NO_ECC_SECP
469
        #ifdef HAVE_OID_ENCODING
470
            #define CODED_SECP160R1    {1,3,132,0,8}
471
            #define CODED_SECP160R1_SZ 5
472
        #else
473
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
474
            #define CODED_SECP160R1_SZ 5
475
        #endif
476
        #ifndef WOLFSSL_ECC_CURVE_STATIC
477
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
478
        #else
479
            #define ecc_oid_secp160r1 CODED_SECP160R1
480
        #endif
481
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
482
    #endif /* !NO_ECC_SECP */
483
    #ifdef HAVE_ECC_SECPR2
484
        #ifdef HAVE_OID_ENCODING
485
            #define CODED_SECP160R2    {1,3,132,0,30}
486
            #define CODED_SECP160R2_SZ 5
487
        #else
488
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
489
            #define CODED_SECP160R2_SZ 5
490
        #endif
491
        #ifndef WOLFSSL_ECC_CURVE_STATIC
492
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
493
        #else
494
            #define ecc_oid_secp160r2 CODED_SECP160R2
495
        #endif
496
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
497
    #endif /* HAVE_ECC_SECPR2 */
498
    #ifdef HAVE_ECC_KOBLITZ
499
        #ifdef HAVE_OID_ENCODING
500
            #define CODED_SECP160K1    {1,3,132,0,9}
501
            #define CODED_SECP160K1_SZ 5
502
        #else
503
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
504
            #define CODED_SECP160K1_SZ 5
505
        #endif
506
        #ifndef WOLFSSL_ECC_CURVE_STATIC
507
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
508
        #else
509
            #define ecc_oid_secp160k1 CODED_SECP160K1
510
        #endif
511
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
512
    #endif /* HAVE_ECC_KOBLITZ */
513
#endif /* !FP_ECC */
514
    #ifdef HAVE_ECC_BRAINPOOL
515
        #ifdef HAVE_OID_ENCODING
516
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
517
            #define CODED_BRAINPOOLP160R1_SZ 10
518
        #else
519
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
520
            #define CODED_BRAINPOOLP160R1_SZ 9
521
        #endif
522
        #ifndef WOLFSSL_ECC_CURVE_STATIC
523
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
524
        #else
525
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
526
        #endif
527
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
528
    #endif /* HAVE_ECC_BRAINPOOL */
529
#endif /* ECC160 */
530
#ifdef ECC192
531
    #ifndef NO_ECC_SECP
532
        #ifdef HAVE_OID_ENCODING
533
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
534
            #define CODED_SECP192R1_SZ 7
535
        #else
536
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
537
            #define CODED_SECP192R1_SZ 8
538
        #endif
539
        #ifndef WOLFSSL_ECC_CURVE_STATIC
540
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
541
        #else
542
            #define ecc_oid_secp192r1 CODED_SECP192R1
543
        #endif
544
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
545
    #endif /* !NO_ECC_SECP */
546
    #ifdef HAVE_ECC_SECPR2
547
        #ifdef HAVE_OID_ENCODING
548
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
549
            #define CODED_PRIME192V2_SZ 7
550
        #else
551
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
552
            #define CODED_PRIME192V2_SZ 8
553
        #endif
554
        #ifndef WOLFSSL_ECC_CURVE_STATIC
555
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
556
        #else
557
            #define ecc_oid_prime192v2 CODED_PRIME192V2
558
        #endif
559
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
560
    #endif /* HAVE_ECC_SECPR2 */
561
    #ifdef HAVE_ECC_SECPR3
562
        #ifdef HAVE_OID_ENCODING
563
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
564
            #define CODED_PRIME192V3_SZ 7
565
        #else
566
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
567
            #define CODED_PRIME192V3_SZ 8
568
        #endif
569
        #ifndef WOLFSSL_ECC_CURVE_STATIC
570
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
571
        #else
572
            #define ecc_oid_prime192v3 CODED_PRIME192V3
573
        #endif
574
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
575
    #endif /* HAVE_ECC_SECPR3 */
576
    #ifdef HAVE_ECC_KOBLITZ
577
        #ifdef HAVE_OID_ENCODING
578
            #define CODED_SECP192K1    {1,3,132,0,31}
579
            #define CODED_SECP192K1_SZ 5
580
        #else
581
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
582
            #define CODED_SECP192K1_SZ 5
583
        #endif
584
        #ifndef WOLFSSL_ECC_CURVE_STATIC
585
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
586
        #else
587
            #define ecc_oid_secp192k1 CODED_SECP192K1
588
        #endif
589
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
590
    #endif /* HAVE_ECC_KOBLITZ */
591
    #ifdef HAVE_ECC_BRAINPOOL
592
        #ifdef HAVE_OID_ENCODING
593
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
594
            #define CODED_BRAINPOOLP192R1_SZ 10
595
        #else
596
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
597
            #define CODED_BRAINPOOLP192R1_SZ 9
598
        #endif
599
        #ifndef WOLFSSL_ECC_CURVE_STATIC
600
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
601
        #else
602
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
603
        #endif
604
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
605
    #endif /* HAVE_ECC_BRAINPOOL */
606
#endif /* ECC192 */
607
#ifdef ECC224
608
    #ifndef NO_ECC_SECP
609
        #ifdef HAVE_OID_ENCODING
610
            #define CODED_SECP224R1    {1,3,132,0,33}
611
            #define CODED_SECP224R1_SZ 5
612
        #else
613
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
614
            #define CODED_SECP224R1_SZ 5
615
        #endif
616
        #ifndef WOLFSSL_ECC_CURVE_STATIC
617
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
618
        #else
619
            #define ecc_oid_secp224r1 CODED_SECP224R1
620
        #endif
621
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
622
    #endif /* !NO_ECC_SECP */
623
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
624
        #ifdef HAVE_OID_ENCODING
625
            #define CODED_SECP224K1    {1,3,132,0,32}
626
            #define CODED_SECP224K1_SZ 5
627
        #else
628
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
629
            #define CODED_SECP224K1_SZ 5
630
        #endif
631
        #ifndef WOLFSSL_ECC_CURVE_STATIC
632
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
633
        #else
634
            #define ecc_oid_secp224k1 CODED_SECP224K1
635
        #endif
636
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
637
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
638
    #ifdef HAVE_ECC_BRAINPOOL
639
        #ifdef HAVE_OID_ENCODING
640
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
641
            #define CODED_BRAINPOOLP224R1_SZ 10
642
        #else
643
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
644
            #define CODED_BRAINPOOLP224R1_SZ 9
645
        #endif
646
        #ifndef WOLFSSL_ECC_CURVE_STATIC
647
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
648
        #else
649
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
650
        #endif
651
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
652
    #endif /* HAVE_ECC_BRAINPOOL */
653
#endif /* ECC224 */
654
#ifdef ECC239
655
    #ifndef NO_ECC_SECP
656
        #ifdef HAVE_OID_ENCODING
657
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
658
            #define CODED_PRIME239V1_SZ 7
659
        #else
660
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
661
            #define CODED_PRIME239V1_SZ 8
662
        #endif
663
        #ifndef WOLFSSL_ECC_CURVE_STATIC
664
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
665
        #else
666
            #define ecc_oid_prime239v1 CODED_PRIME239V1
667
        #endif
668
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
669
    #endif /* !NO_ECC_SECP */
670
    #ifdef HAVE_ECC_SECPR2
671
        #ifdef HAVE_OID_ENCODING
672
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
673
            #define CODED_PRIME239V2_SZ 7
674
        #else
675
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
676
            #define CODED_PRIME239V2_SZ 8
677
        #endif
678
        #ifndef WOLFSSL_ECC_CURVE_STATIC
679
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
680
        #else
681
            #define ecc_oid_prime239v2 CODED_PRIME239V2
682
        #endif
683
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
684
    #endif /* HAVE_ECC_SECPR2 */
685
    #ifdef HAVE_ECC_SECPR3
686
        #ifdef HAVE_OID_ENCODING
687
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
688
            #define CODED_PRIME239V3_SZ 7
689
        #else
690
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
691
            #define CODED_PRIME239V3_SZ 8
692
        #endif
693
        #ifndef WOLFSSL_ECC_CURVE_STATIC
694
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
695
        #else
696
            #define ecc_oid_prime239v3 CODED_PRIME239V3
697
        #endif
698
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
699
    #endif /* HAVE_ECC_SECPR3 */
700
#endif /* ECC239 */
701
#ifdef ECC256
702
    #ifndef NO_ECC_SECP
703
        #ifdef HAVE_OID_ENCODING
704
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
705
            #define CODED_SECP256R1_SZ 7
706
        #else
707
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
708
            #define CODED_SECP256R1_SZ 8
709
        #endif
710
        #ifndef WOLFSSL_ECC_CURVE_STATIC
711
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
712
        #else
713
            #define ecc_oid_secp256r1 CODED_SECP256R1
714
        #endif
715
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
716
    #endif /* !NO_ECC_SECP */
717
    #ifdef HAVE_ECC_KOBLITZ
718
        #ifdef HAVE_OID_ENCODING
719
            #define CODED_SECP256K1    {1,3,132,0,10}
720
            #define CODED_SECP256K1_SZ 5
721
        #else
722
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
723
            #define CODED_SECP256K1_SZ 5
724
        #endif
725
        #ifndef WOLFSSL_ECC_CURVE_STATIC
726
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
727
        #else
728
            #define ecc_oid_secp256k1 CODED_SECP256K1
729
        #endif
730
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
731
    #endif /* HAVE_ECC_KOBLITZ */
732
    #ifdef HAVE_ECC_BRAINPOOL
733
        #ifdef HAVE_OID_ENCODING
734
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
735
            #define CODED_BRAINPOOLP256R1_SZ 10
736
        #else
737
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
738
            #define CODED_BRAINPOOLP256R1_SZ 9
739
        #endif
740
        #ifndef WOLFSSL_ECC_CURVE_STATIC
741
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
742
        #else
743
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
744
        #endif
745
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
746
    #endif /* HAVE_ECC_BRAINPOOL */
747
#endif /* ECC256 */
748
    #if defined(WOLFSSL_SM2)
749
        #ifdef HAVE_OID_ENCODING
750
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
751
            #define CODED_SM2P256V1_SZ 6
752
        #else
753
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
754
            #define CODED_SM2P256V1_SZ 8
755
        #endif
756
        #ifndef WOLFSSL_ECC_CURVE_STATIC
757
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
758
        #else
759
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
760
        #endif
761
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
762
    #endif /* WOLFSSL_SM2 */
763
#ifdef ECC320
764
    #ifdef HAVE_ECC_BRAINPOOL
765
        #ifdef HAVE_OID_ENCODING
766
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
767
            #define CODED_BRAINPOOLP320R1_SZ 10
768
        #else
769
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
770
            #define CODED_BRAINPOOLP320R1_SZ 9
771
        #endif
772
        #ifndef WOLFSSL_ECC_CURVE_STATIC
773
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
774
        #else
775
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
776
        #endif
777
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
778
    #endif /* HAVE_ECC_BRAINPOOL */
779
#endif /* ECC320 */
780
#ifdef ECC384
781
    #ifndef NO_ECC_SECP
782
        #ifdef HAVE_OID_ENCODING
783
            #define CODED_SECP384R1    {1,3,132,0,34}
784
            #define CODED_SECP384R1_SZ 5
785
        #else
786
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
787
            #define CODED_SECP384R1_SZ 5
788
        #endif
789
        #ifndef WOLFSSL_ECC_CURVE_STATIC
790
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
791
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
792
        #else
793
            #define ecc_oid_secp384r1 CODED_SECP384R1
794
        #endif
795
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
796
    #endif /* !NO_ECC_SECP */
797
    #ifdef HAVE_ECC_BRAINPOOL
798
        #ifdef HAVE_OID_ENCODING
799
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
800
            #define CODED_BRAINPOOLP384R1_SZ 10
801
        #else
802
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
803
            #define CODED_BRAINPOOLP384R1_SZ 9
804
        #endif
805
        #ifndef WOLFSSL_ECC_CURVE_STATIC
806
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
807
        #else
808
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
809
        #endif
810
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
811
    #endif /* HAVE_ECC_BRAINPOOL */
812
#endif /* ECC384 */
813
#ifdef ECC512
814
    #ifdef HAVE_ECC_BRAINPOOL
815
        #ifdef HAVE_OID_ENCODING
816
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
817
            #define CODED_BRAINPOOLP512R1_SZ 10
818
        #else
819
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
820
            #define CODED_BRAINPOOLP512R1_SZ 9
821
        #endif
822
        #ifndef WOLFSSL_ECC_CURVE_STATIC
823
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
824
        #else
825
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
826
        #endif
827
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
828
    #endif /* HAVE_ECC_BRAINPOOL */
829
#endif /* ECC512 */
830
#ifdef ECC521
831
    #ifndef NO_ECC_SECP
832
        #ifdef HAVE_OID_ENCODING
833
            #define CODED_SECP521R1     {1,3,132,0,35}
834
            #define CODED_SECP521R1_SZ 5
835
        #else
836
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
837
            #define CODED_SECP521R1_SZ 5
838
        #endif
839
        #ifndef WOLFSSL_ECC_CURVE_STATIC
840
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
841
        #else
842
            #define ecc_oid_secp521r1 CODED_SECP521R1
843
        #endif
844
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
845
    #endif /* !NO_ECC_SECP */
846
#endif /* ECC521 */
847
848
849
/* This holds the key settings.
850
   ***MUST*** be organized by size from smallest to largest. */
851
852
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
853
    #undef ecc_sets
854
    #undef ecc_sets_count
855
#endif
856
857
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
858
static
859
#endif
860
const ecc_set_type ecc_sets[] = {
861
#ifdef ECC112
862
    #ifndef NO_ECC_SECP
863
    {
864
        14,                             /* size/bytes */
865
        ECC_SECP112R1,                  /* ID         */
866
        "SECP112R1",                    /* curve name */
867
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
868
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
869
        "659EF8BA043916EEDE8911702B22", /* B          */
870
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
871
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
872
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
873
        ecc_oid_secp112r1,              /* oid/oidSz  */
874
        ecc_oid_secp112r1_sz,
875
        ECC_SECP112R1_OID,              /* oid sum    */
876
        1,                              /* cofactor   */
877
    },
878
    #endif /* !NO_ECC_SECP */
879
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
880
    {
881
        14,                             /* size/bytes */
882
        ECC_SECP112R2,                  /* ID         */
883
        "SECP112R2",                    /* curve name */
884
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
885
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
886
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
887
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
888
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
889
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
890
        ecc_oid_secp112r2,              /* oid/oidSz  */
891
        ecc_oid_secp112r2_sz,
892
        ECC_SECP112R2_OID,              /* oid sum    */
893
        4,                              /* cofactor   */
894
    },
895
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
896
#endif /* ECC112 */
897
#ifdef ECC128
898
    #ifndef NO_ECC_SECP
899
    {
900
        16,                                 /* size/bytes */
901
        ECC_SECP128R1,                      /* ID         */
902
        "SECP128R1",                        /* curve name */
903
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
904
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
905
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
906
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
907
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
908
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
909
        ecc_oid_secp128r1,                  /* oid/oidSz  */
910
        ecc_oid_secp128r1_sz,
911
        ECC_SECP128R1_OID,                  /* oid sum    */
912
        1,                                  /* cofactor   */
913
    },
914
    #endif /* !NO_ECC_SECP */
915
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
916
    {
917
        16,                                 /* size/bytes */
918
        ECC_SECP128R2,                      /* ID         */
919
        "SECP128R2",                        /* curve name */
920
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
921
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
922
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
923
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
924
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
925
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
926
        ecc_oid_secp128r2,                  /* oid/oidSz  */
927
        ecc_oid_secp128r2_sz,
928
        ECC_SECP128R2_OID,                  /* oid sum    */
929
        4,                                  /* cofactor   */
930
    },
931
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
932
#endif /* ECC128 */
933
#ifdef ECC160
934
#ifndef FP_ECC
935
    #ifndef NO_ECC_SECP
936
    {
937
        20,                                         /* size/bytes */
938
        ECC_SECP160R1,                              /* ID         */
939
        "SECP160R1",                                /* curve name */
940
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
941
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
942
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
943
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
944
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
945
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
946
        ecc_oid_secp160r1,                          /* oid/oidSz  */
947
        ecc_oid_secp160r1_sz,
948
        ECC_SECP160R1_OID,                          /* oid sum    */
949
        1,                                          /* cofactor   */
950
    },
951
    #endif /* !NO_ECC_SECP */
952
    #ifdef HAVE_ECC_SECPR2
953
    {
954
        20,                                         /* size/bytes */
955
        ECC_SECP160R2,                              /* ID         */
956
        "SECP160R2",                                /* curve name */
957
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
958
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
959
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
960
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
961
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
962
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
963
        ecc_oid_secp160r2,                          /* oid/oidSz  */
964
        ecc_oid_secp160r2_sz,
965
        ECC_SECP160R2_OID,                          /* oid sum    */
966
        1,                                          /* cofactor   */
967
    },
968
    #endif /* HAVE_ECC_SECPR2 */
969
    #ifdef HAVE_ECC_KOBLITZ
970
    {
971
        20,                                         /* size/bytes */
972
        ECC_SECP160K1,                              /* ID         */
973
        "SECP160K1",                                /* curve name */
974
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
975
        "0000000000000000000000000000000000000000", /* A          */
976
        "0000000000000000000000000000000000000007", /* B          */
977
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
978
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
979
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
980
        ecc_oid_secp160k1,                          /* oid/oidSz  */
981
        ecc_oid_secp160k1_sz,
982
        ECC_SECP160K1_OID,                          /* oid sum    */
983
        1,                                          /* cofactor   */
984
    },
985
    #endif /* HAVE_ECC_KOBLITZ */
986
#endif /* !FP_ECC */
987
    #ifdef HAVE_ECC_BRAINPOOL
988
    {
989
        20,                                         /* size/bytes */
990
        ECC_BRAINPOOLP160R1,                        /* ID         */
991
        "BRAINPOOLP160R1",                          /* curve name */
992
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
993
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
994
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
995
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
996
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
997
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
998
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
999
        ecc_oid_brainpoolp160r1_sz,
1000
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1001
        1,                                          /* cofactor   */
1002
    },
1003
    #endif /* HAVE_ECC_BRAINPOOL */
1004
#endif /* ECC160 */
1005
#ifdef ECC192
1006
    #ifndef NO_ECC_SECP
1007
    {
1008
        24,                                                 /* size/bytes */
1009
        ECC_SECP192R1,                                      /* ID         */
1010
        "SECP192R1",                                        /* curve name */
1011
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1012
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1013
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1014
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1015
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1016
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1017
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1018
        ecc_oid_secp192r1_sz,
1019
        ECC_SECP192R1_OID,                                  /* oid sum    */
1020
        1,                                                  /* cofactor   */
1021
    },
1022
    #endif /* !NO_ECC_SECP */
1023
    #ifdef HAVE_ECC_SECPR2
1024
    {
1025
        24,                                                 /* size/bytes */
1026
        ECC_PRIME192V2,                                     /* ID         */
1027
        "PRIME192V2",                                       /* curve name */
1028
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1029
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1030
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1031
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1032
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1033
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1034
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1035
        ecc_oid_prime192v2_sz,
1036
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1037
        1,                                                  /* cofactor   */
1038
    },
1039
    #endif /* HAVE_ECC_SECPR2 */
1040
    #ifdef HAVE_ECC_SECPR3
1041
    {
1042
        24,                                                 /* size/bytes */
1043
        ECC_PRIME192V3,                                     /* ID         */
1044
        "PRIME192V3",                                       /* curve name */
1045
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1046
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1047
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1048
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1049
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1050
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1051
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1052
        ecc_oid_prime192v3_sz,
1053
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1054
        1,                                                  /* cofactor   */
1055
    },
1056
    #endif /* HAVE_ECC_SECPR3 */
1057
    #ifdef HAVE_ECC_KOBLITZ
1058
    {
1059
        24,                                                 /* size/bytes */
1060
        ECC_SECP192K1,                                      /* ID         */
1061
        "SECP192K1",                                        /* curve name */
1062
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1063
        "000000000000000000000000000000000000000000000000", /* A          */
1064
        "000000000000000000000000000000000000000000000003", /* B          */
1065
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1066
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1067
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1068
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1069
        ecc_oid_secp192k1_sz,
1070
        ECC_SECP192K1_OID,                                  /* oid sum    */
1071
        1,                                                  /* cofactor   */
1072
    },
1073
    #endif /* HAVE_ECC_KOBLITZ */
1074
    #ifdef HAVE_ECC_BRAINPOOL
1075
    {
1076
        24,                                                 /* size/bytes */
1077
        ECC_BRAINPOOLP192R1,                                /* ID         */
1078
        "BRAINPOOLP192R1",                                  /* curve name */
1079
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1080
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1081
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1082
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1083
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1084
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1085
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1086
        ecc_oid_brainpoolp192r1_sz,
1087
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1088
        1,                                                  /* cofactor   */
1089
    },
1090
    #endif /* HAVE_ECC_BRAINPOOL */
1091
#endif /* ECC192 */
1092
#ifdef ECC224
1093
    #ifndef NO_ECC_SECP
1094
    {
1095
        28,                                                         /* size/bytes */
1096
        ECC_SECP224R1,                                              /* ID         */
1097
        "SECP224R1",                                                /* curve name */
1098
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1099
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1100
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1101
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1102
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1103
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1104
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1105
        ecc_oid_secp224r1_sz,
1106
        ECC_SECP224R1_OID,                                          /* oid sum    */
1107
        1,                                                          /* cofactor   */
1108
    },
1109
    #endif /* !NO_ECC_SECP */
1110
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1111
    {
1112
        28,                                                         /* size/bytes */
1113
        ECC_SECP224K1,                                              /* ID         */
1114
        "SECP224K1",                                                /* curve name */
1115
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1116
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1117
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1118
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1119
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1120
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1121
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1122
        ecc_oid_secp224k1_sz,
1123
        ECC_SECP224K1_OID,                                          /* oid sum    */
1124
        1,                                                          /* cofactor   */
1125
    },
1126
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1127
    #ifdef HAVE_ECC_BRAINPOOL
1128
    {
1129
        28,                                                         /* size/bytes */
1130
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1131
        "BRAINPOOLP224R1",                                          /* curve name */
1132
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1133
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1134
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1135
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1136
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1137
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1138
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1139
        ecc_oid_brainpoolp224r1_sz,
1140
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1141
        1,                                                          /* cofactor   */
1142
    },
1143
    #endif /* HAVE_ECC_BRAINPOOL */
1144
#endif /* ECC224 */
1145
#ifdef ECC239
1146
    #ifndef NO_ECC_SECP
1147
    {
1148
        30,                                                             /* size/bytes */
1149
        ECC_PRIME239V1,                                                 /* ID         */
1150
        "PRIME239V1",                                                   /* curve name */
1151
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1152
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1153
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1154
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1155
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1156
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1157
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1158
        ecc_oid_prime239v1_sz,
1159
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1160
        1,                                                              /* cofactor   */
1161
    },
1162
    #endif /* !NO_ECC_SECP */
1163
    #ifdef HAVE_ECC_SECPR2
1164
    {
1165
        30,                                                             /* size/bytes */
1166
        ECC_PRIME239V2,                                                 /* ID         */
1167
        "PRIME239V2",                                                   /* curve name */
1168
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1169
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1170
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1171
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1172
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1173
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1174
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1175
        ecc_oid_prime239v2_sz,
1176
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1177
        1,                                                              /* cofactor   */
1178
    },
1179
    #endif /* HAVE_ECC_SECPR2 */
1180
    #ifdef HAVE_ECC_SECPR3
1181
    {
1182
        30,                                                             /* size/bytes */
1183
        ECC_PRIME239V3,                                                 /* ID         */
1184
        "PRIME239V3",                                                   /* curve name */
1185
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1186
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1187
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1188
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1189
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1190
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1191
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1192
        ecc_oid_prime239v3_sz,
1193
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1194
        1,                                                              /* cofactor   */
1195
    },
1196
    #endif /* HAVE_ECC_SECPR3 */
1197
#endif /* ECC239 */
1198
#ifdef ECC256
1199
    #ifndef NO_ECC_SECP
1200
    {
1201
        32,                                                                 /* size/bytes */
1202
        ECC_SECP256R1,                                                      /* ID         */
1203
        "SECP256R1",                                                        /* curve name */
1204
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1205
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1206
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1207
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1208
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1209
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1210
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1211
        ecc_oid_secp256r1_sz,
1212
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1213
        1,                                                                  /* cofactor   */
1214
    },
1215
    #endif /* !NO_ECC_SECP */
1216
    #ifdef HAVE_ECC_KOBLITZ
1217
    {
1218
        32,                                                                 /* size/bytes */
1219
        ECC_SECP256K1,                                                      /* ID         */
1220
        "SECP256K1",                                                        /* curve name */
1221
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1222
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1223
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1224
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1225
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1226
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1227
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1228
        ecc_oid_secp256k1_sz,
1229
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1230
        1,                                                                  /* cofactor   */
1231
    },
1232
    #endif /* HAVE_ECC_KOBLITZ */
1233
    #ifdef HAVE_ECC_BRAINPOOL
1234
    {
1235
        32,                                                                 /* size/bytes */
1236
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1237
        "BRAINPOOLP256R1",                                                  /* curve name */
1238
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1239
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1240
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1241
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1242
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1243
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1244
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1245
        ecc_oid_brainpoolp256r1_sz,
1246
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1247
        1,                                                                  /* cofactor   */
1248
    },
1249
    #endif /* HAVE_ECC_BRAINPOOL */
1250
#endif /* ECC256 */
1251
    #if defined(WOLFSSL_SM2)
1252
    {
1253
        32,                                                     /* size/bytes */
1254
        ECC_SM2P256V1,                                          /* ID         */
1255
        "SM2P256V1",                                            /* curve name */
1256
1257
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1258
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1259
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1260
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1261
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1262
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1263
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1264
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1265
        ecc_oid_sm2p256v1_sz,
1266
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1267
        1,                                                      /* cofactor   */
1268
    },
1269
    #endif /* WOLFSSL_SM2 */
1270
#ifdef ECC320
1271
    #ifdef HAVE_ECC_BRAINPOOL
1272
    {
1273
        40,                                                                                 /* size/bytes */
1274
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1275
        "BRAINPOOLP320R1",                                                                  /* curve name */
1276
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1277
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1278
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1279
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1280
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1281
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1282
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1283
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1284
        1,                                                                                  /* cofactor   */
1285
    },
1286
    #endif /* HAVE_ECC_BRAINPOOL */
1287
#endif /* ECC320 */
1288
#ifdef ECC384
1289
    #ifndef NO_ECC_SECP
1290
    {
1291
        48,                                                                                                 /* size/bytes */
1292
        ECC_SECP384R1,                                                                                      /* ID         */
1293
        "SECP384R1",                                                                                        /* curve name */
1294
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1295
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1296
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1297
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1298
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1299
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1300
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1301
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1302
        1,                                                                                                  /* cofactor   */
1303
    },
1304
    #endif /* !NO_ECC_SECP */
1305
    #ifdef HAVE_ECC_BRAINPOOL
1306
    {
1307
        48,                                                                                                 /* size/bytes */
1308
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1309
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1310
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1311
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1312
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1313
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1314
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1315
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1316
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1317
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1318
        1,                                                                                                  /* cofactor   */
1319
    },
1320
    #endif /* HAVE_ECC_BRAINPOOL */
1321
#endif /* ECC384 */
1322
#ifdef ECC512
1323
    #ifdef HAVE_ECC_BRAINPOOL
1324
    {
1325
        64,                                                                                                                                 /* size/bytes */
1326
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1327
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1328
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1329
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1330
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1331
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1332
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1333
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1334
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1335
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1336
        1,                                                                                                                                  /* cofactor   */
1337
    },
1338
    #endif /* HAVE_ECC_BRAINPOOL */
1339
#endif /* ECC512 */
1340
#ifdef ECC521
1341
    #ifndef NO_ECC_SECP
1342
    {
1343
        66,                                                                                                                                    /* size/bytes */
1344
        ECC_SECP521R1,                                                                                                                         /* ID         */
1345
        "SECP521R1",                                                                                                                           /* curve name */
1346
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1347
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1348
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1349
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1350
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1351
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1352
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1353
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1354
        1,                                                                                                                                     /* cofactor   */
1355
    },
1356
    #endif /* !NO_ECC_SECP */
1357
#endif /* ECC521 */
1358
#ifdef WOLFCRYPT_HAVE_SAKKE
1359
    {
1360
        128,
1361
        ECC_SAKKE_1,
1362
        "SAKKE1",
1363
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1364
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1365
        "0",
1366
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1367
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1368
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1369
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1370
            NULL, 0,
1371
        #else
1372
            {0}, 0,
1373
        #endif
1374
        0,
1375
        4,
1376
    },
1377
#endif
1378
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1379
    /* place holder for custom curve index for cache */
1380
    {
1381
        1, /* non-zero */
1382
        ECC_CURVE_CUSTOM,
1383
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1384
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1385
        #else
1386
            {0},{0},{0},{0},{0},{0},{0},{0},
1387
        #endif
1388
        0, 0, 0
1389
    },
1390
#endif
1391
    {
1392
        0,
1393
        ECC_CURVE_INVALID,
1394
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1395
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1396
        #else
1397
            {0},{0},{0},{0},{0},{0},{0},{0},
1398
        #endif
1399
        0, 0, 0
1400
    }
1401
};
1402
0
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1403
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1404
static
1405
#endif
1406
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1407
1408
0
const ecc_set_type *wc_ecc_get_sets(void) {
1409
0
    return ecc_sets;
1410
0
}
1411
0
size_t wc_ecc_get_sets_count(void) {
1412
0
    return ecc_sets_count;
1413
0
}
1414
1415
#ifdef HAVE_OID_ENCODING
1416
    /* encoded OID cache */
1417
    typedef struct {
1418
        word32 oidSz;
1419
        byte oid[ECC_MAX_OID_LEN];
1420
    } oid_cache_t;
1421
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1422
1423
    static wolfSSL_Mutex ecc_oid_cache_lock
1424
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1425
#ifndef WOLFSSL_MUTEX_INITIALIZER
1426
    static volatile int eccOidLockInit = 0;
1427
#endif
1428
#endif /* HAVE_OID_ENCODING */
1429
1430
/* Forward declarations */
1431
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1432
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1433
#endif
1434
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1435
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1436
    mp_int* prime, mp_int* order);
1437
#endif
1438
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1439
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1440
    !defined(WOLFSSL_KCAPI_ECC)
1441
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1442
#endif
1443
1444
1445
#ifdef HAVE_COMP_KEY
1446
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1447
    !defined(WOLFSSL_CRYPTOCELL)
1448
1449
#ifndef WOLFSSL_SP_MATH
1450
#if !defined(SQRTMOD_USE_MOD_EXP)
1451
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1452
#endif
1453
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1454
#endif
1455
#endif
1456
#endif
1457
1458
1459
/* Curve Specs */
1460
typedef struct ecc_curve_spec {
1461
    const ecc_set_type* dp;
1462
1463
    mp_int* prime;
1464
    mp_int* Af;
1465
    #ifdef USE_ECC_B_PARAM
1466
        mp_int* Bf;
1467
    #endif
1468
    mp_int* order;
1469
    mp_int* Gx;
1470
    mp_int* Gy;
1471
1472
#ifdef ECC_CACHE_CURVE
1473
    mp_int prime_lcl;
1474
    mp_int Af_lcl;
1475
    #ifdef USE_ECC_B_PARAM
1476
        mp_int Bf_lcl;
1477
    #endif
1478
    mp_int order_lcl;
1479
    mp_int Gx_lcl;
1480
    mp_int Gy_lcl;
1481
#else
1482
#ifdef WOLFSSL_SP_MATH_ALL
1483
    unsigned char* spec_ints;
1484
#else
1485
    mp_int* spec_ints;
1486
#endif
1487
    word32 spec_count;
1488
    word32 spec_use;
1489
#endif
1490
1491
    byte load_mask;
1492
} ecc_curve_spec;
1493
1494
    #define ECC_CURVE_FIELD_NONE    0x00
1495
0
    #define ECC_CURVE_FIELD_PRIME   0x01
1496
0
    #define ECC_CURVE_FIELD_AF      0x02
1497
#ifdef USE_ECC_B_PARAM
1498
    #define ECC_CURVE_FIELD_BF      0x04
1499
#endif
1500
0
    #define ECC_CURVE_FIELD_ORDER   0x08
1501
0
    #define ECC_CURVE_FIELD_GX      0x10
1502
0
    #define ECC_CURVE_FIELD_GY      0x20
1503
#ifdef USE_ECC_B_PARAM
1504
    #define ECC_CURVE_FIELD_ALL     0x3F
1505
    #define ECC_CURVE_FIELD_COUNT   6
1506
#else
1507
0
    #define ECC_CURVE_FIELD_ALL     0x3B
1508
    #define ECC_CURVE_FIELD_COUNT   5
1509
#endif
1510
1511
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1512
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1513
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1514
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1515
};
1516
1517
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1518
{
1519
    word32 up, down;
1520
    up = 0;
1521
    down = len - 1;
1522
    while (up < len)
1523
        outbuf[up++] = inbuf[down--];
1524
}
1525
1526
static int xil_mpi_import(mp_int *mpi,
1527
                          const byte *inbuf,
1528
                          word32 len,
1529
                          void* heap)
1530
{
1531
    int err;
1532
#ifdef WOLFSSL_SMALL_STACK
1533
    byte* buf = NULL;
1534
#else
1535
    byte buf[MAX_ECC_BYTES];
1536
1537
    if (len > MAX_ECC_BYTES)
1538
        return BUFFER_E;
1539
#endif
1540
1541
#ifdef WOLFSSL_SMALL_STACK
1542
    buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1543
    if (buf == NULL)
1544
        return MEMORY_E;
1545
#endif
1546
    buf_reverse(buf, inbuf, len);
1547
1548
    err = mp_read_unsigned_bin(mpi, buf, len);
1549
    ForceZero(buf, len);
1550
#ifdef WOLFSSL_SMALL_STACK
1551
    XFREE(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1552
#endif
1553
    return err;
1554
}
1555
#endif
1556
1557
#ifdef ECC_CACHE_CURVE
1558
    /* cache (mp_int) of the curve parameters */
1559
    #ifdef WOLFSSL_NO_MALLOC
1560
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1561
    #else
1562
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1563
    #endif
1564
    #ifndef SINGLE_THREADED
1565
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1566
    #endif
1567
1568
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1569
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1570
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1571
#elif defined(WOLFSSL_SMALL_STACK)
1572
#ifdef WOLFSSL_SP_MATH_ALL
1573
    #define DECLARE_CURVE_SPECS(intcount)                               \
1574
        unsigned char* spec_ints = NULL;                                \
1575
        ecc_curve_spec curve_lcl;                                       \
1576
        ecc_curve_spec* curve = &curve_lcl;                             \
1577
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1578
        curve->spec_count = intcount
1579
1580
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1581
    do {                                                                \
1582
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1583
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1584
            DYNAMIC_TYPE_ECC);                                          \
1585
        if (spec_ints == NULL)                                          \
1586
            (err) = MEMORY_E;                                           \
1587
        else {                                                          \
1588
            curve->spec_ints = spec_ints;                               \
1589
            (err) = MP_OKAY;                                            \
1590
        }                                                               \
1591
    } while (0)
1592
#else
1593
    #define DECLARE_CURVE_SPECS(intcount)                               \
1594
        mp_int* spec_ints = NULL;                                       \
1595
        ecc_curve_spec curve_lcl;                                       \
1596
        ecc_curve_spec* curve = &curve_lcl;                             \
1597
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1598
        curve->spec_count = intcount
1599
1600
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1601
    do {                                                                \
1602
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1603
                            DYNAMIC_TYPE_ECC);                          \
1604
        if (spec_ints == NULL)                                          \
1605
            (err) = MEMORY_E;                                           \
1606
        else {                                                          \
1607
            curve->spec_ints = spec_ints;                               \
1608
            (err) = MP_OKAY;                                            \
1609
        }                                                               \
1610
    } while (0)
1611
#endif
1612
    #define FREE_CURVE_SPECS()                                          \
1613
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1614
#else
1615
#ifdef WOLFSSL_SP_MATH_ALL
1616
    #define DECLARE_CURVE_SPECS(intcount)                               \
1617
0
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1618
0
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1619
0
        ecc_curve_spec curve_lcl;                                       \
1620
0
        ecc_curve_spec* curve = &curve_lcl;                             \
1621
0
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1622
0
        curve->spec_ints = spec_ints;                                   \
1623
0
        curve->spec_count = (intcount)
1624
#else
1625
    #define DECLARE_CURVE_SPECS(intcount)                               \
1626
        mp_int spec_ints[(intcount)];                                   \
1627
        ecc_curve_spec curve_lcl;                                       \
1628
        ecc_curve_spec* curve = &curve_lcl;                             \
1629
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1630
        curve->spec_ints = spec_ints;                                   \
1631
        curve->spec_count = (intcount)
1632
#endif
1633
0
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1634
0
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1635
#endif /* ECC_CACHE_CURVE */
1636
1637
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1638
    byte mask)
1639
0
{
1640
0
    if (item) {
1641
    #ifdef HAVE_WOLF_BIGINT
1642
        wc_bigint_free(&item->raw);
1643
    #endif
1644
0
        mp_clear(item);
1645
0
    }
1646
0
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1647
0
}
1648
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1649
0
{
1650
0
    if (curve == NULL) {
1651
0
        return;
1652
0
    }
1653
1654
0
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1655
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1656
0
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1657
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1658
#ifdef USE_ECC_B_PARAM
1659
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1660
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1661
#endif
1662
0
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1663
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1664
0
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1665
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1666
0
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1667
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1668
1669
0
    curve->load_mask = 0;
1670
0
}
1671
1672
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1673
0
{
1674
0
    if (curve) {
1675
    #ifdef ECC_CACHE_CURVE
1676
        #ifdef WOLFSSL_CUSTOM_CURVES
1677
        /* only free custom curves (rest are globally cached) */
1678
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1679
            wc_ecc_curve_cache_free_spec(curve);
1680
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1681
        }
1682
        #endif
1683
    #else
1684
0
        wc_ecc_curve_cache_free_spec(curve);
1685
0
    #endif
1686
0
    }
1687
0
}
1688
1689
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1690
    mp_int** dst, byte mask)
1691
0
{
1692
0
    int err;
1693
1694
0
#ifndef ECC_CACHE_CURVE
1695
    /* get mp_int from temp */
1696
0
    if (curve->spec_use >= curve->spec_count) {
1697
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1698
0
        return ECC_BAD_ARG_E;
1699
0
    }
1700
0
#ifdef WOLFSSL_SP_MATH_ALL
1701
0
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1702
0
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1703
#else
1704
    *dst = &curve->spec_ints[curve->spec_use++];
1705
#endif
1706
0
#endif
1707
1708
0
#ifdef WOLFSSL_SP_MATH_ALL
1709
0
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1710
#else
1711
    err = mp_init(*dst);
1712
#endif
1713
0
    if (err == MP_OKAY) {
1714
0
        curve->load_mask |= mask;
1715
1716
0
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1717
1718
    #ifdef HAVE_WOLF_BIGINT
1719
        if (err == MP_OKAY)
1720
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1721
    #endif
1722
0
    }
1723
0
    return err;
1724
0
}
1725
1726
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1727
    byte load_mask)
1728
0
{
1729
0
    int ret = 0;
1730
0
    ecc_curve_spec* curve;
1731
0
    byte load_items = 0; /* mask of items to load */
1732
#ifdef ECC_CACHE_CURVE
1733
    int x;
1734
#endif
1735
1736
0
    if (dp == NULL || pCurve == NULL)
1737
0
        return BAD_FUNC_ARG;
1738
1739
#ifdef ECC_CACHE_CURVE
1740
    x = wc_ecc_get_curve_idx(dp->id);
1741
    if (x == ECC_CURVE_INVALID)
1742
        return ECC_BAD_ARG_E;
1743
1744
#if !defined(SINGLE_THREADED)
1745
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1746
    if (ret != 0) {
1747
        return ret;
1748
    }
1749
#endif
1750
1751
#ifdef WOLFSSL_NO_MALLOC
1752
    curve = &ecc_curve_spec_cache[x];
1753
#else
1754
    /* make sure cache has been allocated */
1755
    if (ecc_curve_spec_cache[x] == NULL
1756
    #ifdef WOLFSSL_CUSTOM_CURVES
1757
        || dp->id == ECC_CURVE_CUSTOM
1758
    #endif
1759
    ) {
1760
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1761
        if (curve == NULL) {
1762
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1763
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1764
        #endif
1765
            return MEMORY_E;
1766
        }
1767
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1768
1769
        /* set curve pointer to cache */
1770
    #ifdef WOLFSSL_CUSTOM_CURVES
1771
        if (dp->id != ECC_CURVE_CUSTOM)
1772
    #endif
1773
        {
1774
            ecc_curve_spec_cache[x] = curve;
1775
        }
1776
    }
1777
    else {
1778
        curve = ecc_curve_spec_cache[x];
1779
    }
1780
#endif /* WOLFSSL_NO_MALLOC */
1781
1782
    /* return new or cached curve */
1783
    *pCurve = curve;
1784
#else
1785
0
    curve = *pCurve;
1786
0
#endif /* ECC_CACHE_CURVE */
1787
1788
    /* make sure the curve is initialized */
1789
0
    if (curve->dp != dp) {
1790
0
        curve->load_mask = 0;
1791
1792
    #ifdef ECC_CACHE_CURVE
1793
        curve->prime = &curve->prime_lcl;
1794
        curve->Af = &curve->Af_lcl;
1795
        #ifdef USE_ECC_B_PARAM
1796
            curve->Bf = &curve->Bf_lcl;
1797
        #endif
1798
        curve->order = &curve->order_lcl;
1799
        curve->Gx = &curve->Gx_lcl;
1800
        curve->Gy = &curve->Gy_lcl;
1801
    #endif
1802
0
    }
1803
0
    curve->dp = dp; /* set dp info */
1804
1805
    /* determine items to load */
1806
0
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1807
0
    curve->load_mask |= load_items;
1808
1809
    /* load items */
1810
0
    if (load_items & ECC_CURVE_FIELD_PRIME)
1811
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1812
0
            ECC_CURVE_FIELD_PRIME);
1813
0
    if (load_items & ECC_CURVE_FIELD_AF)
1814
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1815
0
            ECC_CURVE_FIELD_AF);
1816
#ifdef USE_ECC_B_PARAM
1817
    if (load_items & ECC_CURVE_FIELD_BF)
1818
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1819
            ECC_CURVE_FIELD_BF);
1820
#endif
1821
0
    if (load_items & ECC_CURVE_FIELD_ORDER)
1822
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1823
0
            ECC_CURVE_FIELD_ORDER);
1824
0
    if (load_items & ECC_CURVE_FIELD_GX)
1825
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1826
0
            ECC_CURVE_FIELD_GX);
1827
0
    if (load_items & ECC_CURVE_FIELD_GY)
1828
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1829
0
            ECC_CURVE_FIELD_GY);
1830
1831
    /* check for error */
1832
0
    if (ret != 0) {
1833
0
        wc_ecc_curve_free(curve);
1834
0
        ret = MP_READ_E;
1835
0
    }
1836
1837
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1838
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1839
#endif
1840
1841
0
    return ret;
1842
0
}
1843
1844
#ifdef ECC_CACHE_CURVE
1845
int wc_ecc_curve_cache_init(void)
1846
{
1847
    int ret = 0;
1848
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1849
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1850
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1851
#endif
1852
    return ret;
1853
}
1854
1855
void wc_ecc_curve_cache_free(void)
1856
{
1857
    int x;
1858
1859
    /* free all ECC curve caches */
1860
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1861
    #ifdef WOLFSSL_NO_MALLOC
1862
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1863
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1864
    #else
1865
        if (ecc_curve_spec_cache[x]) {
1866
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1867
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1868
            ecc_curve_spec_cache[x] = NULL;
1869
        }
1870
    #endif /* WOLFSSL_NO_MALLOC */
1871
    }
1872
1873
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1874
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1875
    wc_FreeMutex(&ecc_curve_cache_mutex);
1876
#endif
1877
}
1878
#endif /* ECC_CACHE_CURVE */
1879
1880
1881
/* Retrieve the curve name for the ECC curve id.
1882
 *
1883
 * curve_id  The id of the curve.
1884
 * returns the name stored from the curve if available, otherwise NULL.
1885
 */
1886
const char* wc_ecc_get_name(int curve_id)
1887
0
{
1888
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1889
0
    if (curve_idx == ECC_CURVE_INVALID)
1890
0
        return NULL;
1891
0
    return ecc_sets[curve_idx].name;
1892
0
}
1893
1894
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1895
0
{
1896
0
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1897
0
        return BAD_FUNC_ARG;
1898
0
    }
1899
1900
0
    if (keysize > ECC_MAXSIZE) {
1901
0
        return ECC_BAD_ARG_E;
1902
0
    }
1903
1904
    /* handle custom case */
1905
0
    if (key->idx != ECC_CUSTOM_IDX) {
1906
0
        int x;
1907
1908
        /* default values */
1909
0
        key->idx = 0;
1910
0
        key->dp = NULL;
1911
1912
        /* find ecc_set based on curve_id or key size */
1913
0
        for (x = 0; ecc_sets[x].size != 0; x++) {
1914
0
            if (curve_id > ECC_CURVE_DEF) {
1915
0
                if (curve_id == ecc_sets[x].id)
1916
0
                  break;
1917
0
            }
1918
0
            else if (keysize <= ecc_sets[x].size) {
1919
0
                break;
1920
0
            }
1921
0
        }
1922
0
        if (ecc_sets[x].size == 0) {
1923
0
            WOLFSSL_MSG("ECC Curve not found");
1924
0
            return ECC_CURVE_OID_E;
1925
0
        }
1926
1927
0
        key->idx = x;
1928
0
        key->dp  = &ecc_sets[x];
1929
0
    }
1930
1931
0
    return 0;
1932
0
}
1933
1934
1935
#ifdef ALT_ECC_SIZE
1936
static void alt_fp_init(mp_int* a)
1937
{
1938
    a->size = FP_SIZE_ECC;
1939
    mp_zero(a);
1940
}
1941
#endif /* ALT_ECC_SIZE */
1942
1943
1944
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1945
    !defined(WOLFSSL_CRYPTOCELL) && \
1946
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
1947
      defined(WOLFSSL_IMXRT1170_CAAM))
1948
1949
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
1950
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
1951
                                     mp_int* modulus, mp_digit mp);
1952
1953
/**
1954
   Add two ECC points
1955
   P        The point to add
1956
   Q        The point to add
1957
   R        [out] The destination of the double
1958
   a        ECC curve parameter a
1959
   modulus  The modulus of the field the ECC curve is in
1960
   mp       The "b" value from montgomery_setup()
1961
   return   MP_OKAY on success
1962
*/
1963
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
1964
                                     mp_int* a, mp_int* modulus, mp_digit mp)
1965
0
{
1966
0
#if !defined(WOLFSSL_SP_MATH)
1967
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1968
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1969
#ifdef ALT_ECC_SIZE
1970
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1971
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1972
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1973
#endif
1974
0
   mp_int  *x, *y, *z;
1975
0
   int     err;
1976
1977
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1978
0
   if (Q == R) {
1979
0
      ecc_point* tPt  = P;
1980
0
      P = Q;
1981
0
      Q = tPt;
1982
0
   }
1983
1984
#ifdef WOLFSSL_SMALL_STACK
1985
#ifdef WOLFSSL_SMALL_STACK_CACHE
1986
   if (R->key != NULL) {
1987
       t1 = R->key->t1;
1988
       t2 = R->key->t2;
1989
#ifdef ALT_ECC_SIZE
1990
       rx = R->key->x;
1991
       ry = R->key->y;
1992
       rz = R->key->z;
1993
#endif
1994
   }
1995
   else
1996
#endif /* WOLFSSL_SMALL_STACK_CACHE */
1997
#endif /* WOLFSSL_SMALL_STACK */
1998
0
   {
1999
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2000
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2001
   #ifdef MP_INT_SIZE_CHECK_NULL
2002
      if (t1 == NULL || t2 == NULL) {
2003
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2004
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2005
         return MEMORY_E;
2006
      }
2007
   #endif
2008
#ifdef ALT_ECC_SIZE
2009
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2010
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2011
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2012
   #ifdef MP_INT_SIZE_CHECK_NULL
2013
      if (rx == NULL || ry == NULL || rz == NULL) {
2014
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2015
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2016
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2017
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2018
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2019
         return MEMORY_E;
2020
      }
2021
   #endif
2022
#endif
2023
0
   }
2024
2025
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2026
0
   if (err == MP_OKAY) {
2027
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2028
0
   }
2029
0
   if (err != MP_OKAY) {
2030
#ifdef WOLFSSL_SMALL_STACK
2031
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2032
      if (R->key == NULL)
2033
   #endif
2034
#endif
2035
0
      {
2036
      #ifdef ALT_ECC_SIZE
2037
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2038
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2039
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2040
      #endif
2041
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2042
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2043
0
      }
2044
0
      return err;
2045
0
   }
2046
2047
   /* should we dbl instead? */
2048
0
   if (err == MP_OKAY) {
2049
0
#ifdef ECC_TIMING_RESISTANT
2050
0
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2051
#else
2052
      err = mp_sub(modulus, Q->y, t1);
2053
#endif
2054
0
   }
2055
0
   if (err == MP_OKAY) {
2056
0
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2057
0
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2058
0
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2059
0
          mp_clear(t1);
2060
0
          mp_clear(t2);
2061
   #ifdef WOLFSSL_SMALL_STACK
2062
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2063
         if (R->key == NULL)
2064
      #endif
2065
   #endif
2066
0
         {
2067
         #ifdef ALT_ECC_SIZE
2068
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2069
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2070
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2071
         #endif
2072
0
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2073
0
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2074
0
         }
2075
0
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2076
0
      }
2077
0
   }
2078
2079
0
   if (err != MP_OKAY) {
2080
0
      goto done;
2081
0
   }
2082
2083
/* If use ALT_ECC_SIZE we need to use local stack variable since
2084
   ecc_point x,y,z is reduced size */
2085
#ifdef ALT_ECC_SIZE
2086
   /* Use local stack variable */
2087
   x = rx;
2088
   y = ry;
2089
   z = rz;
2090
2091
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2092
   if (err == MP_OKAY) {
2093
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2094
   }
2095
   if (err == MP_OKAY) {
2096
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2097
   }
2098
   if (err != MP_OKAY) {
2099
      goto done;
2100
   }
2101
#else
2102
   /* Use destination directly */
2103
0
   x = R->x;
2104
0
   y = R->y;
2105
0
   z = R->z;
2106
0
#endif
2107
2108
0
   if (err == MP_OKAY)
2109
0
       err = mp_copy(P->x, x);
2110
0
   if (err == MP_OKAY)
2111
0
       err = mp_copy(P->y, y);
2112
0
   if (err == MP_OKAY)
2113
0
       err = mp_copy(P->z, z);
2114
2115
   /* if Z is one then these are no-operations */
2116
0
   if (err == MP_OKAY) {
2117
0
       if (!mp_iszero(Q->z)) {
2118
           /* T1 = Z' * Z' */
2119
0
           err = mp_sqr(Q->z, t1);
2120
0
           if (err == MP_OKAY)
2121
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2122
2123
           /* X = X * T1 */
2124
0
           if (err == MP_OKAY)
2125
0
               err = mp_mul(t1, x, x);
2126
0
           if (err == MP_OKAY)
2127
0
               err = mp_montgomery_reduce(x, modulus, mp);
2128
2129
           /* T1 = Z' * T1 */
2130
0
           if (err == MP_OKAY)
2131
0
               err = mp_mul(Q->z, t1, t1);
2132
0
           if (err == MP_OKAY)
2133
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2134
2135
           /* Y = Y * T1 */
2136
0
           if (err == MP_OKAY)
2137
0
               err = mp_mul(t1, y, y);
2138
0
           if (err == MP_OKAY)
2139
0
               err = mp_montgomery_reduce(y, modulus, mp);
2140
0
       }
2141
0
   }
2142
2143
   /* T1 = Z*Z */
2144
0
   if (err == MP_OKAY)
2145
0
       err = mp_sqr(z, t1);
2146
0
   if (err == MP_OKAY)
2147
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2148
2149
   /* T2 = X' * T1 */
2150
0
   if (err == MP_OKAY)
2151
0
       err = mp_mul(Q->x, t1, t2);
2152
0
   if (err == MP_OKAY)
2153
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2154
2155
   /* T1 = Z * T1 */
2156
0
   if (err == MP_OKAY)
2157
0
       err = mp_mul(z, t1, t1);
2158
0
   if (err == MP_OKAY)
2159
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2160
2161
   /* T1 = Y' * T1 */
2162
0
   if (err == MP_OKAY)
2163
0
       err = mp_mul(Q->y, t1, t1);
2164
0
   if (err == MP_OKAY)
2165
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2166
2167
   /* Y = Y - T1 */
2168
0
   if (err == MP_OKAY)
2169
0
       err = mp_submod_ct(y, t1, modulus, y);
2170
   /* T1 = 2T1 */
2171
0
   if (err == MP_OKAY)
2172
0
       err = mp_addmod_ct(t1, t1, modulus, t1);
2173
   /* T1 = Y + T1 */
2174
0
   if (err == MP_OKAY)
2175
0
       err = mp_addmod_ct(t1, y, modulus, t1);
2176
   /* X = X - T2 */
2177
0
   if (err == MP_OKAY)
2178
0
       err = mp_submod_ct(x, t2, modulus, x);
2179
   /* T2 = 2T2 */
2180
0
   if (err == MP_OKAY)
2181
0
       err = mp_addmod_ct(t2, t2, modulus, t2);
2182
   /* T2 = X + T2 */
2183
0
   if (err == MP_OKAY)
2184
0
       err = mp_addmod_ct(t2, x, modulus, t2);
2185
2186
0
   if (err == MP_OKAY) {
2187
0
       if (!mp_iszero(Q->z)) {
2188
           /* Z = Z * Z' */
2189
0
           err = mp_mul(z, Q->z, z);
2190
0
           if (err == MP_OKAY)
2191
0
               err = mp_montgomery_reduce(z, modulus, mp);
2192
0
       }
2193
0
   }
2194
2195
   /* Z = Z * X */
2196
0
   if (err == MP_OKAY)
2197
0
       err = mp_mul(z, x, z);
2198
0
   if (err == MP_OKAY)
2199
0
       err = mp_montgomery_reduce(z, modulus, mp);
2200
2201
   /* T1 = T1 * X  */
2202
0
   if (err == MP_OKAY)
2203
0
       err = mp_mul(t1, x, t1);
2204
0
   if (err == MP_OKAY)
2205
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2206
2207
   /* X = X * X */
2208
0
   if (err == MP_OKAY)
2209
0
       err = mp_sqr(x, x);
2210
0
   if (err == MP_OKAY)
2211
0
       err = mp_montgomery_reduce(x, modulus, mp);
2212
2213
   /* T2 = T2 * x */
2214
0
   if (err == MP_OKAY)
2215
0
       err = mp_mul(t2, x, t2);
2216
0
   if (err == MP_OKAY)
2217
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2218
2219
   /* T1 = T1 * X  */
2220
0
   if (err == MP_OKAY)
2221
0
       err = mp_mul(t1, x, t1);
2222
0
   if (err == MP_OKAY)
2223
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2224
2225
   /* X = Y*Y */
2226
0
   if (err == MP_OKAY)
2227
0
       err = mp_sqr(y, x);
2228
0
   if (err == MP_OKAY)
2229
0
       err = mp_montgomery_reduce(x, modulus, mp);
2230
2231
   /* X = X - T2 */
2232
0
   if (err == MP_OKAY)
2233
0
       err = mp_submod_ct(x, t2, modulus, x);
2234
   /* T2 = T2 - X */
2235
0
   if (err == MP_OKAY)
2236
0
       err = mp_submod_ct(t2, x, modulus, t2);
2237
   /* T2 = T2 - X */
2238
0
   if (err == MP_OKAY)
2239
0
       err = mp_submod_ct(t2, x, modulus, t2);
2240
   /* T2 = T2 * Y */
2241
0
   if (err == MP_OKAY)
2242
0
       err = mp_mul(t2, y, t2);
2243
0
   if (err == MP_OKAY)
2244
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2245
2246
   /* Y = T2 - T1 */
2247
0
   if (err == MP_OKAY)
2248
0
       err = mp_submod_ct(t2, t1, modulus, y);
2249
   /* Y = Y/2 */
2250
0
   if (err == MP_OKAY)
2251
0
       err = mp_div_2_mod_ct(y, modulus, y);
2252
2253
#ifdef ALT_ECC_SIZE
2254
   if (err == MP_OKAY)
2255
       err = mp_copy(x, R->x);
2256
   if (err == MP_OKAY)
2257
       err = mp_copy(y, R->y);
2258
   if (err == MP_OKAY)
2259
       err = mp_copy(z, R->z);
2260
#endif
2261
2262
0
done:
2263
2264
   /* clean up */
2265
0
   mp_clear(t1);
2266
0
   mp_clear(t2);
2267
#ifdef WOLFSSL_SMALL_STACK
2268
#ifdef WOLFSSL_SMALL_STACK_CACHE
2269
   if (R->key == NULL)
2270
#endif
2271
#endif
2272
0
   {
2273
   #ifdef ALT_ECC_SIZE
2274
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2275
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2276
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2277
   #endif
2278
0
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2279
0
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2280
0
   }
2281
2282
0
   return err;
2283
#else
2284
    int modBits = mp_count_bits(modulus);
2285
2286
    (void)a;
2287
    (void)mp;
2288
2289
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2290
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2291
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2292
                                            R->x, R->y, R->z);
2293
    }
2294
#endif
2295
#ifndef WOLFSSL_SP_NO_256
2296
    if (modBits == 256) {
2297
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2298
                                         R->x, R->y, R->z);
2299
    }
2300
#endif
2301
#ifdef WOLFSSL_SP_384
2302
    if (modBits == 384) {
2303
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2304
                                         R->x, R->y, R->z);
2305
    }
2306
#endif
2307
#ifdef WOLFSSL_SP_521
2308
    if (modBits == 521) {
2309
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2310
                                         R->x, R->y, R->z);
2311
    }
2312
#endif
2313
    return ECC_BAD_ARG_E;
2314
#endif
2315
0
}
2316
2317
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2318
                             mp_int* a, mp_int* modulus, mp_digit mp)
2319
0
{
2320
0
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2321
0
        return ECC_BAD_ARG_E;
2322
0
    }
2323
2324
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2325
0
        mp_cmp(P->y, modulus) != MP_LT ||
2326
0
        mp_cmp(P->z, modulus) != MP_LT ||
2327
0
        mp_cmp(Q->x, modulus) != MP_LT ||
2328
0
        mp_cmp(Q->y, modulus) != MP_LT ||
2329
0
        mp_cmp(Q->z, modulus) != MP_LT) {
2330
0
        return ECC_OUT_OF_RANGE_E;
2331
0
    }
2332
2333
0
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2334
0
}
2335
2336
/* ### Point doubling in Jacobian coordinate system ###
2337
 *
2338
 * let us have a curve:                 y^2 = x^3 + a*x + b
2339
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2340
 *
2341
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2342
 * Xr = M^2 - 2*S
2343
 * Yr = M * (S - Xr) - 8*T
2344
 * Zr = 2 * Yp * Zp
2345
 *
2346
 * M = 3 * Xp^2 + a*Zp^4
2347
 * T = Yp^4
2348
 * S = 4 * Xp * Yp^2
2349
 *
2350
 * SPECIAL CASE: when a == 3 we can compute M as
2351
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2352
 */
2353
2354
/**
2355
   Double an ECC point
2356
   P   The point to double
2357
   R   [out] The destination of the double
2358
   a   ECC curve parameter a
2359
   modulus  The modulus of the field the ECC curve is in
2360
   mp       The "b" value from montgomery_setup()
2361
   return   MP_OKAY on success
2362
*/
2363
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2364
                                     mp_int* modulus, mp_digit mp)
2365
0
{
2366
0
#if !defined(WOLFSSL_SP_MATH)
2367
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2368
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2369
#ifdef ALT_ECC_SIZE
2370
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2371
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2372
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2373
#endif
2374
0
   mp_int *x, *y, *z;
2375
0
   int    err;
2376
2377
#ifdef WOLFSSL_SMALL_STACK
2378
#ifdef WOLFSSL_SMALL_STACK_CACHE
2379
   if (R->key != NULL) {
2380
       t1 = R->key->t1;
2381
       t2 = R->key->t2;
2382
   #ifdef ALT_ECC_SIZE
2383
       rx = R->key->x;
2384
       ry = R->key->y;
2385
       rz = R->key->z;
2386
   #endif
2387
   }
2388
   else
2389
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2390
#endif
2391
0
   {
2392
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2393
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2394
   #ifdef MP_INT_SIZE_CHECK_NULL
2395
      if (t1 == NULL || t2 == NULL) {
2396
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2397
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2398
         return MEMORY_E;
2399
      }
2400
   #endif
2401
   #ifdef ALT_ECC_SIZE
2402
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2403
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2404
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2405
   #ifdef MP_INT_SIZE_CHECK_NULL
2406
      if (rx == NULL || ry == NULL || rz == NULL) {
2407
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2408
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2409
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2410
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2411
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2412
          return MEMORY_E;
2413
      }
2414
   #endif
2415
   #endif
2416
0
   }
2417
2418
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2419
0
   if (err == MP_OKAY) {
2420
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2421
0
   }
2422
0
   if (err != MP_OKAY) {
2423
#ifdef WOLFSSL_SMALL_STACK
2424
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2425
      if (R->key == NULL)
2426
   #endif
2427
#endif
2428
0
      {
2429
      #ifdef ALT_ECC_SIZE
2430
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2431
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2432
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2433
      #endif
2434
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2435
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2436
0
      }
2437
0
      return err;
2438
0
   }
2439
2440
/* If use ALT_ECC_SIZE we need to use local stack variable since
2441
   ecc_point x,y,z is reduced size */
2442
#ifdef ALT_ECC_SIZE
2443
   /* Use local stack variable */
2444
   x = rx;
2445
   y = ry;
2446
   z = rz;
2447
2448
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2449
   if (err == MP_OKAY) {
2450
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2451
   }
2452
   if (err == MP_OKAY) {
2453
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2454
   }
2455
   if (err != MP_OKAY) {
2456
#ifdef WOLFSSL_SMALL_STACK
2457
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2458
      if (R->key == NULL)
2459
   #endif
2460
#endif
2461
      {
2462
      #ifdef ALT_ECC_SIZE
2463
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2464
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2465
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2466
      #endif
2467
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2468
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2469
      }
2470
      return err;
2471
   }
2472
#else
2473
   /* Use destination directly */
2474
0
   x = R->x;
2475
0
   y = R->y;
2476
0
   z = R->z;
2477
0
#endif
2478
2479
0
   if (err == MP_OKAY)
2480
0
       err = mp_copy(P->x, x);
2481
0
   if (err == MP_OKAY)
2482
0
       err = mp_copy(P->y, y);
2483
0
   if (err == MP_OKAY)
2484
0
       err = mp_copy(P->z, z);
2485
2486
   /* T1 = Z * Z */
2487
0
   if (err == MP_OKAY)
2488
0
       err = mp_sqr(z, t1);
2489
0
   if (err == MP_OKAY)
2490
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2491
2492
   /* Z = Y * Z */
2493
0
   if (err == MP_OKAY)
2494
0
       err = mp_mul(z, y, z);
2495
0
   if (err == MP_OKAY)
2496
0
       err = mp_montgomery_reduce(z, modulus, mp);
2497
2498
   /* Z = 2Z */
2499
0
   if (err == MP_OKAY)
2500
0
       err = mp_addmod_ct(z, z, modulus, z);
2501
2502
   /* Determine if curve "a" should be used in calc */
2503
#ifdef WOLFSSL_CUSTOM_CURVES
2504
   if (err == MP_OKAY) {
2505
      /* Use a and prime to determine if a == 3 */
2506
      err = mp_submod(modulus, a, modulus, t2);
2507
   }
2508
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2509
      /* T2 = X * X */
2510
      err = mp_sqr(x, t2);
2511
      if (err == MP_OKAY)
2512
          err = mp_montgomery_reduce(t2, modulus, mp);
2513
      /* T1 = T2 + T1 */
2514
      if (err == MP_OKAY)
2515
          err = mp_addmod_ct(t2, t2, modulus, t1);
2516
      /* T1 = T2 + T1 */
2517
      if (err == MP_OKAY)
2518
          err = mp_addmod_ct(t1, t2, modulus, t1);
2519
   }
2520
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2521
      /* use "a" in calc */
2522
2523
      /* T2 = T1 * T1 */
2524
      err = mp_sqr(t1, t2);
2525
      if (err == MP_OKAY)
2526
          err = mp_montgomery_reduce(t2, modulus, mp);
2527
      /* T1 = T2 * a */
2528
      if (err == MP_OKAY)
2529
          err = mp_mulmod(t2, a, modulus, t1);
2530
      /* T2 = X * X */
2531
      if (err == MP_OKAY)
2532
          err = mp_sqr(x, t2);
2533
      if (err == MP_OKAY)
2534
          err = mp_montgomery_reduce(t2, modulus, mp);
2535
      /* T1 = T2 + T1 */
2536
      if (err == MP_OKAY)
2537
          err = mp_addmod_ct(t1, t2, modulus, t1);
2538
      /* T1 = T2 + T1 */
2539
      if (err == MP_OKAY)
2540
          err = mp_addmod_ct(t1, t2, modulus, t1);
2541
      /* T1 = T2 + T1 */
2542
      if (err == MP_OKAY)
2543
          err = mp_addmod_ct(t1, t2, modulus, t1);
2544
   }
2545
   else
2546
#endif /* WOLFSSL_CUSTOM_CURVES */
2547
0
   {
2548
      /* assumes "a" == 3 */
2549
0
      (void)a;
2550
2551
      /* T2 = X - T1 */
2552
0
      if (err == MP_OKAY)
2553
0
          err = mp_submod_ct(x, t1, modulus, t2);
2554
      /* T1 = X + T1 */
2555
0
      if (err == MP_OKAY)
2556
0
          err = mp_addmod_ct(t1, x, modulus, t1);
2557
      /* T2 = T1 * T2 */
2558
0
      if (err == MP_OKAY)
2559
0
          err = mp_mul(t1, t2, t2);
2560
0
      if (err == MP_OKAY)
2561
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2562
2563
      /* T1 = 2T2 */
2564
0
      if (err == MP_OKAY)
2565
0
          err = mp_addmod_ct(t2, t2, modulus, t1);
2566
      /* T1 = T1 + T2 */
2567
0
      if (err == MP_OKAY)
2568
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2569
0
   }
2570
2571
   /* Y = 2Y */
2572
0
   if (err == MP_OKAY)
2573
0
       err = mp_addmod_ct(y, y, modulus, y);
2574
   /* Y = Y * Y */
2575
0
   if (err == MP_OKAY)
2576
0
       err = mp_sqr(y, y);
2577
0
   if (err == MP_OKAY)
2578
0
       err = mp_montgomery_reduce(y, modulus, mp);
2579
2580
   /* T2 = Y * Y */
2581
0
   if (err == MP_OKAY)
2582
0
       err = mp_sqr(y, t2);
2583
0
   if (err == MP_OKAY)
2584
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2585
2586
   /* T2 = T2/2 */
2587
0
   if (err == MP_OKAY)
2588
0
       err = mp_div_2_mod_ct(t2, modulus, t2);
2589
2590
   /* Y = Y * X */
2591
0
   if (err == MP_OKAY)
2592
0
       err = mp_mul(y, x, y);
2593
0
   if (err == MP_OKAY)
2594
0
       err = mp_montgomery_reduce(y, modulus, mp);
2595
2596
   /* X = T1 * T1 */
2597
0
   if (err == MP_OKAY)
2598
0
       err = mp_sqr(t1, x);
2599
0
   if (err == MP_OKAY)
2600
0
       err = mp_montgomery_reduce(x, modulus, mp);
2601
2602
   /* X = X - Y */
2603
0
   if (err == MP_OKAY)
2604
0
       err = mp_submod_ct(x, y, modulus, x);
2605
   /* X = X - Y */
2606
0
   if (err == MP_OKAY)
2607
0
       err = mp_submod_ct(x, y, modulus, x);
2608
2609
   /* Y = Y - X */
2610
0
   if (err == MP_OKAY)
2611
0
       err = mp_submod_ct(y, x, modulus, y);
2612
   /* Y = Y * T1 */
2613
0
   if (err == MP_OKAY)
2614
0
       err = mp_mul(y, t1, y);
2615
0
   if (err == MP_OKAY)
2616
0
       err = mp_montgomery_reduce(y, modulus, mp);
2617
2618
   /* Y = Y - T2 */
2619
0
   if (err == MP_OKAY)
2620
0
       err = mp_submod_ct(y, t2, modulus, y);
2621
2622
#ifdef ALT_ECC_SIZE
2623
   if (err == MP_OKAY)
2624
       err = mp_copy(x, R->x);
2625
   if (err == MP_OKAY)
2626
       err = mp_copy(y, R->y);
2627
   if (err == MP_OKAY)
2628
       err = mp_copy(z, R->z);
2629
#endif
2630
2631
   /* clean up */
2632
0
   mp_clear(t1);
2633
0
   mp_clear(t2);
2634
2635
#ifdef WOLFSSL_SMALL_STACK
2636
#ifdef WOLFSSL_SMALL_STACK_CACHE
2637
   if (R->key == NULL)
2638
#endif
2639
#endif
2640
0
   {
2641
    #ifdef ALT_ECC_SIZE
2642
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2643
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2644
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2645
    #endif
2646
0
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2647
0
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2648
0
    }
2649
2650
0
   return err;
2651
#else
2652
    int modBits = mp_count_bits(modulus);
2653
2654
    (void)a;
2655
    (void)mp;
2656
2657
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2658
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2659
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2660
    }
2661
#endif
2662
#ifndef WOLFSSL_SP_NO_256
2663
    if (modBits == 256) {
2664
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2665
    }
2666
#endif
2667
#ifdef WOLFSSL_SP_384
2668
    if (modBits == 384) {
2669
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2670
    }
2671
#endif
2672
#ifdef WOLFSSL_SP_521
2673
    if (modBits == 521) {
2674
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2675
    }
2676
#endif
2677
    return ECC_BAD_ARG_E;
2678
#endif
2679
0
}
2680
2681
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2682
                             mp_int* modulus, mp_digit mp)
2683
0
{
2684
0
    if (P == NULL || R == NULL || modulus == NULL)
2685
0
        return ECC_BAD_ARG_E;
2686
2687
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2688
0
        mp_cmp(P->y, modulus) != MP_LT ||
2689
0
        mp_cmp(P->z, modulus) != MP_LT) {
2690
0
        return ECC_OUT_OF_RANGE_E;
2691
0
    }
2692
2693
0
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2694
0
}
2695
2696
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2697
    !defined(WOLFSSL_CRYPTOCELL)
2698
2699
2700
/**
2701
  Map a projective Jacobian point back to affine space
2702
  P        [in/out] The point to map
2703
  modulus  The modulus of the field the ECC curve is in
2704
  mp       The "b" value from montgomery_setup()
2705
  ct       Operation should be constant time.
2706
  return   MP_OKAY on success
2707
*/
2708
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2709
0
{
2710
0
   int err = MP_OKAY;
2711
0
#if !defined(WOLFSSL_SP_MATH)
2712
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2713
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2714
#ifdef ALT_ECC_SIZE
2715
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2716
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2717
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2718
#endif
2719
0
   mp_int *x, *y, *z;
2720
2721
0
   (void)ct;
2722
2723
0
   if (P == NULL || modulus == NULL)
2724
0
       return ECC_BAD_ARG_E;
2725
2726
   /* special case for point at infinity */
2727
0
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2728
0
       err = mp_set(P->x, 0);
2729
0
       if (err == MP_OKAY)
2730
0
           err = mp_set(P->y, 0);
2731
0
       if (err == MP_OKAY)
2732
0
           err = mp_set(P->z, 1);
2733
0
       return err;
2734
0
   }
2735
2736
#ifdef WOLFSSL_SMALL_STACK
2737
#ifdef WOLFSSL_SMALL_STACK_CACHE
2738
   if (P->key != NULL) {
2739
       t1 = P->key->t1;
2740
       t2 = P->key->t2;
2741
   #ifdef ALT_ECC_SIZE
2742
       rx = P->key->x;
2743
       ry = P->key->y;
2744
       rz = P->key->z;
2745
   #endif
2746
   }
2747
   else
2748
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2749
#endif
2750
0
   {
2751
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2752
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2753
   #ifdef MP_INT_SIZE_CHECK_NULL
2754
      if (t1 == NULL || t2 == NULL) {
2755
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2756
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2757
         return MEMORY_E;
2758
      }
2759
   #endif
2760
   #ifdef ALT_ECC_SIZE
2761
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2762
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2763
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2764
   #ifdef MP_INT_SIZE_CHECK_NULL
2765
      if (rx == NULL || ry == NULL || rz == NULL) {
2766
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2767
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2768
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2769
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2770
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2771
          return MEMORY_E;
2772
      }
2773
   #endif
2774
   #endif
2775
0
   }
2776
2777
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2778
0
   if (err == MP_OKAY) {
2779
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2780
0
   }
2781
0
   if (err != MP_OKAY) {
2782
#ifdef WOLFSSL_SMALL_STACK
2783
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2784
      if (P->key == NULL)
2785
   #endif
2786
#endif
2787
0
      {
2788
      #ifdef ALT_ECC_SIZE
2789
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2790
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2791
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2792
      #endif
2793
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2794
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2795
0
      }
2796
0
      return MEMORY_E;
2797
0
   }
2798
2799
#ifdef ALT_ECC_SIZE
2800
   /* Use local stack variable */
2801
   x = rx;
2802
   y = ry;
2803
   z = rz;
2804
2805
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2806
   if (err == MP_OKAY) {
2807
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2808
   }
2809
   if (err == MP_OKAY) {
2810
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2811
   }
2812
   if (err != MP_OKAY) {
2813
      goto done;
2814
   }
2815
2816
   if (err == MP_OKAY)
2817
      err = mp_copy(P->x, x);
2818
   if (err == MP_OKAY)
2819
      err = mp_copy(P->y, y);
2820
   if (err == MP_OKAY)
2821
      err = mp_copy(P->z, z);
2822
2823
   if (err != MP_OKAY) {
2824
      goto done;
2825
   }
2826
#else
2827
   /* Use destination directly */
2828
0
   x = P->x;
2829
0
   y = P->y;
2830
0
   z = P->z;
2831
0
#endif
2832
2833
   /* get 1/z */
2834
0
   if (err == MP_OKAY) {
2835
0
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2836
0
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2837
0
       if (ct) {
2838
0
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2839
0
           if (err == MP_OKAY)
2840
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2841
0
       }
2842
0
       else
2843
0
#endif
2844
0
       {
2845
           /* first map z back to normal */
2846
0
           err = mp_montgomery_reduce(z, modulus, mp);
2847
0
           if (err == MP_OKAY)
2848
0
               err = mp_invmod(z, modulus, t1);
2849
0
       }
2850
0
   }
2851
2852
   /* get 1/z^2 and 1/z^3 */
2853
0
   if (err == MP_OKAY)
2854
0
       err = mp_sqr(t1, t2);
2855
0
   if (err == MP_OKAY)
2856
0
       err = mp_mod(t2, modulus, t2);
2857
0
   if (err == MP_OKAY)
2858
0
       err = mp_mul(t1, t2, t1);
2859
0
   if (err == MP_OKAY)
2860
0
       err = mp_mod(t1, modulus, t1);
2861
2862
   /* multiply against x/y */
2863
0
   if (err == MP_OKAY)
2864
0
       err = mp_mul(x, t2, x);
2865
0
   if (err == MP_OKAY)
2866
0
       err = mp_montgomery_reduce(x, modulus, mp);
2867
0
   if (err == MP_OKAY)
2868
0
       err = mp_mul(y, t1, y);
2869
0
   if (err == MP_OKAY)
2870
0
       err = mp_montgomery_reduce(y, modulus, mp);
2871
2872
0
   if (err == MP_OKAY)
2873
0
       err = mp_set(z, 1);
2874
2875
#ifdef ALT_ECC_SIZE
2876
   /* return result */
2877
   if (err == MP_OKAY)
2878
      err = mp_copy(x, P->x);
2879
   if (err == MP_OKAY)
2880
      err = mp_copy(y, P->y);
2881
   if (err == MP_OKAY)
2882
      err = mp_copy(z, P->z);
2883
2884
done:
2885
#endif
2886
2887
   /* clean up */
2888
0
   mp_clear(t1);
2889
0
   mp_clear(t2);
2890
2891
#ifdef WOLFSSL_SMALL_STACK
2892
#ifdef WOLFSSL_SMALL_STACK_CACHE
2893
   if (P->key == NULL)
2894
#endif
2895
#endif
2896
0
   {
2897
   #ifdef ALT_ECC_SIZE
2898
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2899
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2900
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2901
   #endif
2902
0
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2903
0
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2904
0
   }
2905
2906
0
   return err;
2907
   /* end !defined(WOLFSSL_SP_MATH) */
2908
2909
#else
2910
   /* begin defined(WOLFSSL_SP_MATH) */
2911
   if (P == NULL || modulus == NULL)
2912
       return ECC_BAD_ARG_E;
2913
2914
   (void)mp;
2915
   (void)ct;
2916
2917
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2918
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
2919
       err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
2920
   }
2921
#elif !defined(WOLFSSL_SP_NO_256)
2922
   if (mp_count_bits(modulus) == 256) {
2923
       err = sp_ecc_map_256(P->x, P->y, P->z);
2924
   }
2925
#elif defined(WOLFSSL_SP_384)
2926
   if (mp_count_bits(modulus) == 384) {
2927
       err = sp_ecc_map_384(P->x, P->y, P->z);
2928
   }
2929
#elif defined(WOLFSSL_SP_521)
2930
   if (mp_count_bits(modulus) == 521) {
2931
       err = sp_ecc_map_521(P->x, P->y, P->z);
2932
   }
2933
#else
2934
   err = ECC_BAD_ARG_E;
2935
#endif
2936
2937
   WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
2938
   return err;
2939
#endif /* WOLFSSL_SP_MATH */
2940
0
}
2941
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2942
2943
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2944
0
{
2945
0
    return ecc_map_ex(P, modulus, mp, 0);
2946
0
}
2947
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2948
2949
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2950
    !defined(WOLFSSL_CRYPTOCELL)
2951
#if !defined(WOLFSSL_SP_MATH)
2952
2953
#ifndef ECC_TIMING_RESISTANT
2954
2955
/* size of sliding window, don't change this! */
2956
#define WINSIZE  4
2957
#define M_POINTS 8
2958
2959
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2960
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2961
{
2962
   int      err = MP_OKAY;
2963
   int      i;
2964
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2965
   int      bitcnt = 0, mode = 0, digidx = 0;
2966
   mp_digit buf;
2967
   int      infinity;
2968
2969
   (void)rng;
2970
2971
   /* calc the M tab, which holds kG for k==8..15 */
2972
   /* M[0] == 8G */
2973
   if (err == MP_OKAY)
2974
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2975
   if (err == MP_OKAY)
2976
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2977
   if (err == MP_OKAY)
2978
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2979
2980
   /* now find (8+k)G for k=1..7 */
2981
   if (err == MP_OKAY)
2982
       for (j = 9; j < 16; j++) {
2983
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2984
                                                        modulus, mp, &infinity);
2985
           if (err != MP_OKAY) break;
2986
       }
2987
2988
   /* setup sliding window */
2989
   if (err == MP_OKAY) {
2990
       mode   = 0;
2991
       bitcnt = 1;
2992
       buf    = 0;
2993
       digidx = mp_get_digit_count(k) - 1;
2994
       bitcpy = bitbuf = 0;
2995
       first  = 1;
2996
2997
       /* perform ops */
2998
       for (;;) {
2999
           /* grab next digit as required */
3000
           if (--bitcnt == 0) {
3001
               if (digidx == -1) {
3002
                   break;
3003
               }
3004
               buf    = mp_get_digit(k, digidx);
3005
               bitcnt = (int) DIGIT_BIT;
3006
               --digidx;
3007
           }
3008
3009
           /* grab the next msb from the ltiplicand */
3010
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3011
           buf <<= 1;
3012
3013
           /* skip leading zero bits */
3014
           if (mode == 0 && i == 0)
3015
               continue;
3016
3017
           /* if the bit is zero and mode == 1 then we double */
3018
           if (mode == 1 && i == 0) {
3019
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3020
               if (err != MP_OKAY) break;
3021
               continue;
3022
           }
3023
3024
           /* else we add it to the window */
3025
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3026
           mode = 2;
3027
3028
           if (bitcpy == WINSIZE) {
3029
               /* if this is the first window we do a simple copy */
3030
               if (first == 1) {
3031
                   /* R = kG [k = first window] */
3032
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3033
                   if (err != MP_OKAY) break;
3034
3035
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3036
                   if (err != MP_OKAY) break;
3037
3038
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3039
                   first = 0;
3040
               } else {
3041
                   /* normal window */
3042
                   /* ok window is filled so double as required and add  */
3043
                   /* double first */
3044
                   for (j = 0; j < WINSIZE; j++) {
3045
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3046
                                                                            mp);
3047
                       if (err != MP_OKAY) break;
3048
                   }
3049
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3050
3051
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3052
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3053
                                                     a, modulus, mp, &infinity);
3054
               }
3055
               if (err != MP_OKAY) break;
3056
               /* empty window and reset */
3057
               bitcpy = bitbuf = 0;
3058
               mode = 1;
3059
           }
3060
       }
3061
   }
3062
3063
   /* if bits remain then double/add */
3064
   if (err == MP_OKAY) {
3065
       if (mode == 2 && bitcpy > 0) {
3066
           /* double then add */
3067
           for (j = 0; j < bitcpy; j++) {
3068
               /* only double if we have had at least one add first */
3069
               if (first == 0) {
3070
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3071
                   if (err != MP_OKAY) break;
3072
               }
3073
3074
               bitbuf <<= 1;
3075
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3076
                   if (first == 1) {
3077
                       /* first add, so copy */
3078
                       err = mp_copy(tG->x, R->x);
3079
                       if (err != MP_OKAY) break;
3080
3081
                       err = mp_copy(tG->y, R->y);
3082
                       if (err != MP_OKAY) break;
3083
3084
                       err = mp_copy(tG->z, R->z);
3085
                       if (err != MP_OKAY) break;
3086
                       first = 0;
3087
                   } else {
3088
                       /* then add */
3089
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3090
                                                                 mp, &infinity);
3091
                       if (err != MP_OKAY) break;
3092
                   }
3093
               }
3094
           }
3095
       }
3096
   }
3097
3098
   #undef WINSIZE
3099
3100
   return err;
3101
}
3102
3103
#else
3104
3105
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3106
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3107
0
{
3108
0
    int err = MP_OKAY;
3109
3110
0
    err = mp_montgomery_calc_normalization(mu, modulus);
3111
    /* Generate random value to multiply into p->z. */
3112
0
    if (err == MP_OKAY)
3113
0
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3114
    /* Convert to montogmery form. */
3115
0
    if (err == MP_OKAY)
3116
0
        err = mp_mulmod(ty, mu, modulus, ty);
3117
    /* Multiply random value into p->z. */
3118
0
    if (err == MP_OKAY)
3119
0
        err = mp_mul(p->z, ty, p->z);
3120
0
    if (err == MP_OKAY)
3121
0
        err = mp_montgomery_reduce(p->z, modulus, mp);
3122
    /* Square random value for X (X' = X / Z^2). */
3123
0
    if (err == MP_OKAY)
3124
0
        err = mp_sqr(ty, tx);
3125
0
    if (err == MP_OKAY)
3126
0
        err = mp_montgomery_reduce(tx, modulus, mp);
3127
    /* Multiply square of random by random value for Y. */
3128
0
    if (err == MP_OKAY)
3129
0
        err = mp_mul(ty, tx, ty);
3130
0
    if (err == MP_OKAY)
3131
0
        err = mp_montgomery_reduce(ty, modulus, mp);
3132
    /* Multiply square into X. */
3133
0
    if (err == MP_OKAY)
3134
0
        err = mp_mul(p->x, tx, p->x);
3135
0
    if (err == MP_OKAY)
3136
0
        err = mp_montgomery_reduce(p->x, modulus, mp);
3137
    /* Multiply cube into Y (Y' = Y / Z^3). */
3138
0
    if (err == MP_OKAY)
3139
0
        err = mp_mul(p->y, ty, p->y);
3140
0
    if (err == MP_OKAY)
3141
0
        err = mp_montgomery_reduce(p->y, modulus, mp);
3142
3143
0
    return err;
3144
0
}
3145
3146
#ifndef WC_PROTECT_ENCRYPTED_MEM
3147
0
#define M_POINTS 3
3148
3149
/* Joye double-add ladder.
3150
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3151
 * by Marc Joye (2007)
3152
 *
3153
 * Algorithm 1':
3154
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3155
 *   Output: Q = kP
3156
 *   1: R[0] = P; R[1] = P
3157
 *   2: for j = 1 to t-1 do
3158
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3159
 *   4: end for
3160
 *   5: b = k[0]; R[b] = R[b] - P
3161
 *   6: return R[0]
3162
 *
3163
 * Assumes: k < order.
3164
 */
3165
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3166
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3167
0
{
3168
0
    int      err = MP_OKAY;
3169
0
    int      bytes = (mp_count_bits(modulus) + 7) / 8;
3170
0
    int      i;
3171
0
    int      j = 1;
3172
0
    int      cnt = DIGIT_BIT;
3173
0
    int      t = 0;
3174
0
    mp_digit b;
3175
0
    mp_digit v = 0;
3176
0
    mp_int*  kt = R[2]->x;
3177
0
#ifndef WC_NO_CACHE_RESISTANT
3178
    /* First bit always 1 (fix at end) and swap equals first bit */
3179
0
    int      swap = 1;
3180
#ifdef WOLFSSL_SMALL_STACK
3181
    mp_int*  tmp = NULL;
3182
#else
3183
0
    mp_int   tmp[1];
3184
0
#endif
3185
0
#endif
3186
0
    int      infinity;
3187
3188
0
#ifndef WC_NO_CACHE_RESISTANT
3189
#ifdef WOLFSSL_SMALL_STACK
3190
    tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
3191
    if (tmp == NULL) {
3192
        err = MEMORY_E;
3193
    }
3194
#endif
3195
0
    if (err == MP_OKAY)
3196
0
        err = mp_init(tmp);
3197
0
#endif
3198
3199
    /* Step 1: R[0] = P; R[1] = P */
3200
    /* R[0] = P */
3201
0
    if (err == MP_OKAY)
3202
0
        err = mp_copy(P->x, R[0]->x);
3203
0
    if (err == MP_OKAY)
3204
0
        err = mp_copy(P->y, R[0]->y);
3205
0
    if (err == MP_OKAY)
3206
0
        err = mp_copy(P->z, R[0]->z);
3207
3208
    /* R[1] = P */
3209
0
    if (err == MP_OKAY)
3210
0
        err = mp_copy(P->x, R[1]->x);
3211
0
    if (err == MP_OKAY)
3212
0
        err = mp_copy(P->y, R[1]->y);
3213
0
    if (err == MP_OKAY)
3214
0
        err = mp_copy(P->z, R[1]->z);
3215
3216
    /* Randomize z ordinates to obfuscate timing. */
3217
0
    if ((err == MP_OKAY) && (rng != NULL))
3218
0
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3219
0
    if ((err == MP_OKAY) && (rng != NULL))
3220
0
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3221
3222
0
    if (err == MP_OKAY) {
3223
        /* Order could be one greater than the size of the modulus. */
3224
0
        t = mp_count_bits(modulus) + 1;
3225
0
        v = k->dp[0] >> 1;
3226
0
        if (cnt > t) {
3227
0
            cnt = t;
3228
0
        }
3229
0
        err = mp_copy(k, kt);
3230
0
    }
3231
0
    if (err == MP_OKAY) {
3232
0
        err = mp_grow(kt, (int)modulus->used + 1);
3233
0
    }
3234
    /* Step 2: for j = 1 to t-1 do */
3235
0
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3236
0
        if (--cnt == 0) {
3237
0
            v = kt->dp[j++];
3238
0
            cnt = DIGIT_BIT;
3239
0
        }
3240
3241
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3242
0
        b = v & 1;
3243
0
        v >>= 1;
3244
#ifdef WC_NO_CACHE_RESISTANT
3245
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3246
        if (err == MP_OKAY) {
3247
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3248
                                                        modulus, mp, &infinity);
3249
        }
3250
#else
3251
        /* Swap R[0] and R[1] if other index is needed. */
3252
0
        swap ^= (int)b;
3253
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3254
0
            tmp);
3255
0
        if (err == MP_OKAY) {
3256
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3257
0
                tmp);
3258
0
        }
3259
0
        if (err == MP_OKAY) {
3260
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3261
0
                tmp);
3262
0
        }
3263
0
        swap = (int)b;
3264
3265
0
        if (err == MP_OKAY)
3266
0
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3267
0
        if (err == MP_OKAY) {
3268
0
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3269
0
                                                                 mp, &infinity);
3270
0
        }
3271
0
#endif /* WC_NO_CACHE_RESISTANT */
3272
0
    }
3273
    /* Step 4: end for */
3274
0
#ifndef WC_NO_CACHE_RESISTANT
3275
    /* Swap back if last bit is 0. */
3276
0
    swap ^= 1;
3277
0
    if (err == MP_OKAY) {
3278
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3279
0
            tmp);
3280
0
    }
3281
0
    if (err == MP_OKAY) {
3282
0
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3283
0
            tmp);
3284
0
    }
3285
0
    if (err == MP_OKAY) {
3286
0
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3287
0
            tmp);
3288
0
    }
3289
0
#endif
3290
3291
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3292
    /* R[2] = -P */
3293
0
    if (err == MP_OKAY)
3294
0
        err = mp_copy(P->x, R[2]->x);
3295
0
    if (err == MP_OKAY)
3296
0
        err = mp_sub(modulus, P->y, R[2]->y);
3297
0
    if (err == MP_OKAY)
3298
0
        err = mp_copy(P->z, R[2]->z);
3299
    /* Subtract point by adding negative. */
3300
0
    if (err == MP_OKAY) {
3301
0
        b = k->dp[0] & 1;
3302
#ifdef WC_NO_CACHE_RESISTANT
3303
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3304
                                                                     &infinity);
3305
#else
3306
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3307
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3308
0
            tmp);
3309
0
        if (err == MP_OKAY) {
3310
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3311
0
                (int)b, tmp);
3312
0
        }
3313
0
        if (err == MP_OKAY) {
3314
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3315
0
                (int)b, tmp);
3316
0
        }
3317
0
        if (err == MP_OKAY)
3318
0
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3319
0
                                                                 mp, &infinity);
3320
        /* Swap back if necessary. */
3321
0
        if (err == MP_OKAY) {
3322
0
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3323
0
                (int)b, tmp);
3324
0
        }
3325
0
        if (err == MP_OKAY) {
3326
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3327
0
                (int)b, tmp);
3328
0
        }
3329
0
        if (err == MP_OKAY) {
3330
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3331
0
                (int)b, tmp);
3332
0
        }
3333
0
#endif
3334
0
    }
3335
3336
    /* Step 6: return R[0] */
3337
0
    if (err == MP_OKAY)
3338
0
        err = mp_copy(R[0]->x, Q->x);
3339
0
    if (err == MP_OKAY)
3340
0
        err = mp_copy(R[0]->y, Q->y);
3341
0
    if (err == MP_OKAY)
3342
0
        err = mp_copy(R[0]->z, Q->z);
3343
3344
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3345
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3346
#endif
3347
3348
0
    return err;
3349
0
}
3350
3351
#else
3352
/* Number of points to allocate for use during scalar multiplication. */
3353
#define M_POINTS        5
3354
/* Last of the points is used as a temporary during calculations. */
3355
#define TMP_IDX         M_POINTS - 1
3356
3357
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3358
    int digits, int m)
3359
{
3360
    int i;
3361
3362
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3363
    /* Only using positive numbers in ECC operations. */
3364
    ra->sign = 0;
3365
    rb->sign = 0;
3366
#endif
3367
    /* Don't store 0 when mask is 0, it will be in a register. */
3368
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3369
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3370
    for (i = 0; i < digits; i++) {
3371
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3372
                    a->dp[i];
3373
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3374
                    b->dp[i];
3375
    }
3376
}
3377
3378
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3379
    ecc_point* b, int digits, int m)
3380
{
3381
    /* Conditionally swap each ordinate. */
3382
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3383
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3384
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3385
}
3386
3387
/* Joye double-add ladder.
3388
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3389
 * by Marc Joye (2007)
3390
 *
3391
 * Algorithm 1':
3392
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3393
 *   Output: Q = kP
3394
 *   1: R[0] = P; R[1] = P
3395
 *   2: for j = 1 to t-1 do
3396
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3397
 *   4: end for
3398
 *   5: b = k[0]; R[b] = R[b] - P
3399
 *   6: return R[0]
3400
 *
3401
 * Assumes: k < order.
3402
 */
3403
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3404
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3405
{
3406
    int          err = MP_OKAY;
3407
    int          bytes = (mp_count_bits(modulus) + 7) / 8;
3408
    int          i;
3409
    int          j = 1;
3410
    int          cnt;
3411
    int          t = 0;
3412
    mp_int*      kt = R[TMP_IDX]->x;
3413
    /* First bit always 1 (fix at end) and swap equals first bit */
3414
    register int swap = 1;
3415
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3416
    int          set = 0;
3417
    int          infinity;
3418
3419
    /* Step 1: R[0] = P; R[1] = P */
3420
    /* R[0] = P */
3421
    if (err == MP_OKAY)
3422
        err = mp_copy(P->x, R[0]->x);
3423
    if (err == MP_OKAY)
3424
        err = mp_copy(P->y, R[0]->y);
3425
    if (err == MP_OKAY)
3426
        err = mp_copy(P->z, R[0]->z);
3427
3428
    /* R[1] = P */
3429
    if (err == MP_OKAY)
3430
        err = mp_copy(P->x, R[1]->x);
3431
    if (err == MP_OKAY)
3432
        err = mp_copy(P->y, R[1]->y);
3433
    if (err == MP_OKAY)
3434
        err = mp_copy(P->z, R[1]->z);
3435
3436
    /* Randomize z ordinates to obfuscate timing. */
3437
    if ((err == MP_OKAY) && (rng != NULL))
3438
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3439
                           R[TMP_IDX]->y, kt);
3440
    if ((err == MP_OKAY) && (rng != NULL))
3441
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3442
                           R[TMP_IDX]->y, kt);
3443
3444
    if (err == MP_OKAY) {
3445
        /* Order could be one greater than the size of the modulus. */
3446
        t = mp_count_bits(modulus) + 1;
3447
        err = mp_copy(k, kt);
3448
    }
3449
    if (err == MP_OKAY) {
3450
        err = mp_grow(kt, modulus->used + 1);
3451
    }
3452
    /* Step 2: for j = 1 to t-1 do */
3453
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3454
        if (++cnt == DIGIT_BIT) {
3455
            j++;
3456
            cnt = 0;
3457
        }
3458
3459
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3460
        /* Swap R[0] and R[1] if other index is needed. */
3461
        /* Ensure 'swap' changes when shifted word is 0. */
3462
        swap += (kt->dp[j] >> cnt) + 2;
3463
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3464
                              R[set + 0], R[set + 1], modulus->used, swap);
3465
        /* Change to operate on set copied into. */
3466
        set = 2 - set;
3467
        /* Ensure 'swap' changes to a previously unseen value. */
3468
        swap += (kt->dp[j] >> cnt) + swap;
3469
3470
        /* R[0] = 2*R[0] */
3471
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3472
                                            mp);
3473
        if (err == MP_OKAY) {
3474
            /* R[0] = R[1] + R[0] */
3475
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3476
                                         R[set + 0], a, modulus, mp, &infinity);
3477
        }
3478
        /*  R[1]->z * 2 - same point. */
3479
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3480
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3481
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3482
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3483
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3484
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3485
    }
3486
    /* Step 4: end for */
3487
    /* Swap back if last bit is 0. */
3488
    /* Ensure 'swap' changes. */
3489
    swap += 1;
3490
    if (err == MP_OKAY) {
3491
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3492
                              R[set + 0], R[set + 1], modulus->used, swap);
3493
        set = 2 - set;
3494
    }
3495
3496
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3497
    /* R[TMP_IDX] = -P */
3498
    if (err == MP_OKAY)
3499
        err = mp_copy(P->x, R[TMP_IDX]->x);
3500
    if (err == MP_OKAY)
3501
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3502
    if (err == MP_OKAY)
3503
        err = mp_copy(P->z, R[TMP_IDX]->z);
3504
    /* Subtract point by adding negative. */
3505
    if (err == MP_OKAY) {
3506
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3507
         * Last bit of k->dp[0] is being used to make decision to swap.
3508
         */
3509
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3510
                              R[set + 0], R[set + 1], modulus->used,
3511
                              (int)k->dp[0]);
3512
        set = 2 - set;
3513
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3514
                                            a, modulus, mp, &infinity);
3515
        /* Swap back if necessary. */
3516
        if (err == MP_OKAY) {
3517
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3518
                                  R[set + 0], R[set + 1], modulus->used,
3519
                                  (int)k->dp[0]);
3520
            set = 2 - set;
3521
        }
3522
    }
3523
3524
    /* Step 6: return R[0] */
3525
    if (err == MP_OKAY)
3526
        err = mp_copy(R[set + 0]->x, Q->x);
3527
    if (err == MP_OKAY)
3528
        err = mp_copy(R[set + 0]->y, Q->y);
3529
    if (err == MP_OKAY)
3530
        err = mp_copy(R[set + 0]->z, Q->z);
3531
3532
    return err;
3533
}
3534
3535
#endif
3536
3537
#endif
3538
3539
/* Convert the point to montgomery form.
3540
 *
3541
 * @param  [in]   p        Point to convert.
3542
 * @param  [out]  r        Point in montgomery form.
3543
 * @param  [in]   modulus  Modulus of ordinates.
3544
 * @return  0 on success.
3545
 * @return  -ve on failure.
3546
 */
3547
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3548
                             void* heap)
3549
0
{
3550
0
   int err = MP_OKAY;
3551
0
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3552
3553
0
   (void)heap;
3554
3555
0
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3556
#ifdef MP_INT_SIZE_CHECK_NULL
3557
   if (mu == NULL)
3558
       err = MEMORY_E;
3559
#endif
3560
0
   if (err == MP_OKAY)
3561
0
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3562
0
   if (err == MP_OKAY) {
3563
0
       err = mp_montgomery_calc_normalization(mu, modulus);
3564
3565
0
       if (err == MP_OKAY) {
3566
0
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3567
0
               err = mp_copy(p->x, r->x);
3568
0
               if (err == MP_OKAY)
3569
0
                   err = mp_copy(p->y, r->y);
3570
0
               if (err == MP_OKAY)
3571
0
                   err = mp_copy(p->z, r->z);
3572
0
           }
3573
0
           else {
3574
0
               err = mp_mulmod(p->x, mu, modulus, r->x);
3575
0
               if (err == MP_OKAY)
3576
0
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3577
0
               if (err == MP_OKAY)
3578
0
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3579
0
           }
3580
0
       }
3581
3582
0
       mp_clear(mu);
3583
0
   }
3584
3585
0
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3586
0
   return err;
3587
0
}
3588
3589
#ifdef WOLFSSL_SMALL_STACK_CACHE
3590
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3591
{
3592
   int err = MP_OKAY;
3593
3594
   (void)heap;
3595
3596
   if (key == NULL) {
3597
       return ECC_BAD_ARG_E;
3598
   }
3599
3600
   XMEMSET(key, 0, sizeof(*key));
3601
3602
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3603
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3604
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3605
#ifdef ALT_ECC_SIZE
3606
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3607
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3608
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3609
#endif
3610
   if (key->t1 == NULL || key->t2 == NULL
3611
#ifdef ALT_ECC_SIZE
3612
      || key->x == NULL || key->y == NULL || key->z == NULL
3613
#endif
3614
   ) {
3615
       err = MEMORY_E;
3616
   }
3617
   if (err == 0) {
3618
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3619
   }
3620
   if (err == 0) {
3621
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3622
   }
3623
#ifdef ALT_ECC_SIZE
3624
   if (err == 0) {
3625
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3626
   }
3627
   if (err == 0) {
3628
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3629
   }
3630
   if (err == 0) {
3631
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3632
   }
3633
#endif
3634
#else
3635
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3636
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3637
#ifdef ALT_ECC_SIZE
3638
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3639
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3640
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3641
#endif
3642
   if (key->t1 == NULL || key->t2 == NULL
3643
#ifdef ALT_ECC_SIZE
3644
      || key->x == NULL || key->y == NULL || key->z == NULL
3645
#endif
3646
   ) {
3647
       err = MEMORY_E;
3648
   }
3649
#endif
3650
3651
   return err;
3652
}
3653
3654
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3655
{
3656
    (void)heap;
3657
3658
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3659
#ifdef ALT_ECC_SIZE
3660
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3661
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3662
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3663
#endif
3664
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3665
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3666
#else
3667
#ifdef ALT_ECC_SIZE
3668
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3669
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3670
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3671
#endif
3672
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3673
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3674
#endif
3675
}
3676
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3677
#endif /* !WOLFSSL_SP_MATH */
3678
3679
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3680
/**
3681
   Perform a point multiplication
3682
   k    The scalar to multiply by
3683
   G    The base point
3684
   R    [out] Destination for kG
3685
   a    ECC curve parameter a
3686
   modulus  The modulus of the field the ECC curve is in
3687
   map      Boolean whether to map back to affine or not
3688
                (1==map, 0 == leave in projective)
3689
   return MP_OKAY on success
3690
*/
3691
#ifdef FP_ECC
3692
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3693
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3694
                             void* heap)
3695
#else
3696
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3697
                     mp_int* modulus, int map, void* heap)
3698
#endif
3699
#if !defined(WOLFSSL_SP_MATH)
3700
0
{
3701
0
   ecc_point     *tG, *M[M_POINTS];
3702
#ifdef WOLFSSL_NO_MALLOC
3703
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3704
#endif
3705
0
   int           i, err;
3706
#ifdef WOLFSSL_SMALL_STACK_CACHE
3707
   ecc_key       *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3708
#endif
3709
0
   mp_digit      mp;
3710
3711
   /* init variables */
3712
0
   tG = NULL;
3713
0
   XMEMSET(M, 0, sizeof(M));
3714
3715
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3716
0
       err = ECC_BAD_ARG_E;
3717
0
       goto exit;
3718
0
   }
3719
3720
   /* k can't have more bits than modulus count plus 1 */
3721
0
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3722
0
       err = ECC_OUT_OF_RANGE_E;
3723
0
       goto exit;
3724
0
   }
3725
3726
#ifdef WOLFSSL_SMALL_STACK_CACHE
3727
   if (key == NULL) {
3728
       err = MP_MEM;
3729
       goto exit;
3730
   }
3731
   err = ecc_key_tmp_init(key, heap);
3732
   if (err != MP_OKAY)
3733
      goto exit;
3734
   R->key = key;
3735
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3736
3737
  /* alloc ram for window temps */
3738
0
  for (i = 0; i < M_POINTS; i++) {
3739
  #ifdef WOLFSSL_NO_MALLOC
3740
      M[i] = &lcl_M[i];
3741
  #endif
3742
0
      err = wc_ecc_new_point_ex(&M[i], heap);
3743
0
      if (err != MP_OKAY) {
3744
0
         goto exit;
3745
0
      }
3746
#ifdef WOLFSSL_SMALL_STACK_CACHE
3747
      M[i]->key = key;
3748
#endif
3749
0
  }
3750
3751
   /* make a copy of G in case R==G */
3752
#ifdef WOLFSSL_NO_MALLOC
3753
   tG = &lcl_tG;
3754
#endif
3755
0
   err = wc_ecc_new_point_ex(&tG, heap);
3756
0
   if (err != MP_OKAY) {
3757
0
       goto exit;
3758
0
   }
3759
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3760
0
       goto exit;
3761
0
   }
3762
3763
   /* init montgomery reduction */
3764
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3765
0
       goto exit;
3766
0
   }
3767
3768
#ifdef FP_ECC
3769
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3770
#else
3771
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3772
0
#endif
3773
   /* map R back from projective space */
3774
0
   if (err == MP_OKAY && map)
3775
0
       err = ecc_map(R, modulus, mp);
3776
3777
0
exit:
3778
3779
   /* done */
3780
0
   wc_ecc_del_point_ex(tG, heap);
3781
0
   for (i = 0; i < M_POINTS; i++) {
3782
0
       wc_ecc_del_point_ex(M[i], heap);
3783
0
   }
3784
3785
#ifdef WOLFSSL_SMALL_STACK_CACHE
3786
   if (key) {
3787
       if (R)
3788
           R->key = NULL;
3789
       if (err == MP_OKAY)
3790
           ecc_key_tmp_final(key, heap);
3791
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3792
   }
3793
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3794
3795
0
   return err;
3796
0
}
3797
#else
3798
{
3799
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3800
       return ECC_BAD_ARG_E;
3801
   }
3802
3803
   (void)a;
3804
3805
   /* For supported curves the order is the same length in bits as the modulus.
3806
    * Can't have more than order bits for the scalar.
3807
    */
3808
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3809
       return ECC_OUT_OF_RANGE_E;
3810
   }
3811
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3812
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3813
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3814
       return IS_POINT_E;
3815
   }
3816
3817
#ifdef WOLFSSL_HAVE_SP_ECC
3818
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3819
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3820
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3821
   }
3822
#endif
3823
#ifndef WOLFSSL_SP_NO_256
3824
   if (mp_count_bits(modulus) == 256) {
3825
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3826
   }
3827
#endif
3828
#ifdef WOLFSSL_SP_384
3829
   if (mp_count_bits(modulus) == 384) {
3830
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3831
   }
3832
#endif
3833
#ifdef WOLFSSL_SP_521
3834
   if (mp_count_bits(modulus) == 521) {
3835
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3836
   }
3837
#endif
3838
#else
3839
   (void)map;
3840
   (void)map;
3841
   (void)heap;
3842
#endif
3843
   return ECC_BAD_ARG_E;
3844
}
3845
#endif
3846
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3847
3848
#ifndef FP_ECC
3849
#if !defined(WOLFSSL_SP_MATH)
3850
#ifdef ECC_TIMING_RESISTANT
3851
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3852
   mp_int* modulus, mp_int* order)
3853
0
{
3854
0
    int err;
3855
0
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3856
3857
0
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3858
#ifdef MP_INT_SIZE_CHECK_NULL
3859
    if (t == NULL) {
3860
        err = MEMORY_E;
3861
    }
3862
    else
3863
#endif
3864
0
    {
3865
0
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3866
0
    }
3867
0
    if (err == MP_OKAY) {
3868
        /* Check for k == order - 1. Result will be 0 point which is not correct
3869
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3870
         * (with constant time implementation)
3871
         */
3872
0
        err = mp_sub_d(order, 1, t);
3873
0
        if (err == MP_OKAY) {
3874
0
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3875
0
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3876
0
            if (err == MP_OKAY) {
3877
0
                err = mp_sub(modulus, tG->y, t);
3878
0
            }
3879
0
            if (err == MP_OKAY) {
3880
0
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3881
0
            }
3882
0
            if (err == MP_OKAY) {
3883
0
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3884
0
            }
3885
0
        }
3886
3887
0
        mp_free(t);
3888
0
    }
3889
3890
0
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3891
0
    return err;
3892
0
}
3893
#endif /* ECC_TIMING_RESISTANT */
3894
#endif
3895
3896
/**
3897
   Perform a point multiplication
3898
   k    The scalar to multiply by
3899
   G    The base point
3900
   R    [out] Destination for kG
3901
   a    ECC curve parameter a
3902
   modulus  The modulus of the field the ECC curve is in
3903
   map      Boolean whether to map back to affine or not
3904
                (1==map, 0 == leave in projective)
3905
   return MP_OKAY on success
3906
*/
3907
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
3908
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3909
                      void* heap)
3910
#if !defined(WOLFSSL_SP_MATH)
3911
0
{
3912
0
   ecc_point     *tG, *M[M_POINTS];
3913
#ifdef WOLFSSL_NO_MALLOC
3914
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3915
#endif
3916
0
   int           i, err;
3917
#ifdef WOLFSSL_SMALL_STACK_CACHE
3918
   ecc_key       *key = NULL;
3919
#endif
3920
0
   mp_digit      mp;
3921
3922
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3923
0
      return ECC_BAD_ARG_E;
3924
0
   }
3925
3926
#ifdef HAVE_ECC_CDH
3927
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
3928
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
3929
          return ECC_OUT_OF_RANGE_E;
3930
      }
3931
   }
3932
   else
3933
#endif
3934
   /* k can't have more bits than order */
3935
0
   if (mp_count_bits(k) > mp_count_bits(order)) {
3936
0
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3937
0
      return ECC_OUT_OF_RANGE_E;
3938
0
   }
3939
3940
   /* init variables */
3941
0
   tG = NULL;
3942
0
   XMEMSET(M, 0, sizeof(M));
3943
3944
#ifdef WOLFSSL_SMALL_STACK_CACHE
3945
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3946
   if (key == NULL)
3947
       return MEMORY_E;
3948
   err = ecc_key_tmp_init(key, heap);
3949
   if (err != MP_OKAY)
3950
      goto exit;
3951
   R->key = key;
3952
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3953
3954
   /* alloc ram for window temps */
3955
0
   for (i = 0; i < M_POINTS; i++) {
3956
   #ifdef WOLFSSL_NO_MALLOC
3957
      M[i] = &lcl_M[i];
3958
   #endif
3959
0
      err = wc_ecc_new_point_ex(&M[i], heap);
3960
0
      if (err != MP_OKAY) {
3961
0
         goto exit;
3962
0
      }
3963
#ifdef WOLFSSL_SMALL_STACK_CACHE
3964
      M[i]->key = key;
3965
#endif
3966
0
  }
3967
3968
   /* make a copy of G in case R==G */
3969
#ifdef WOLFSSL_NO_MALLOC
3970
   tG = &lcl_tG;
3971
#endif
3972
0
   err = wc_ecc_new_point_ex(&tG, heap);
3973
0
   if (err != MP_OKAY) {
3974
0
       goto exit;
3975
0
   }
3976
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3977
0
       goto exit;
3978
0
   }
3979
3980
   /* init montgomery reduction */
3981
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3982
0
      goto exit;
3983
0
   }
3984
3985
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3986
0
#ifdef ECC_TIMING_RESISTANT
3987
0
   if (err == MP_OKAY) {
3988
0
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3989
0
   }
3990
#else
3991
   (void)order;
3992
#endif
3993
   /* map R back from projective space */
3994
0
   if (err == MP_OKAY && map)
3995
0
      err = ecc_map(R, modulus, mp);
3996
3997
0
exit:
3998
3999
   /* done */
4000
0
   wc_ecc_del_point_ex(tG, heap);
4001
0
   for (i = 0; i < M_POINTS; i++) {
4002
0
      wc_ecc_del_point_ex(M[i], heap);
4003
0
   }
4004
#ifdef WOLFSSL_SMALL_STACK_CACHE
4005
   R->key = NULL;
4006
   ecc_key_tmp_final(key, heap);
4007
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
4008
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4009
4010
0
   return err;
4011
0
}
4012
#else
4013
{
4014
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4015
       return ECC_BAD_ARG_E;
4016
   }
4017
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4018
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4019
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4020
       return IS_POINT_E;
4021
   }
4022
4023
   (void)a;
4024
   (void)order;
4025
   (void)rng;
4026
4027
#ifdef WOLFSSL_HAVE_SP_ECC
4028
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4029
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4030
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4031
   }
4032
#endif
4033
#ifndef WOLFSSL_SP_NO_256
4034
   if (mp_count_bits(modulus) == 256) {
4035
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4036
   }
4037
#endif
4038
#ifdef WOLFSSL_SP_384
4039
   if (mp_count_bits(modulus) == 384) {
4040
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4041
   }
4042
#endif
4043
#ifdef WOLFSSL_SP_521
4044
   if (mp_count_bits(modulus) == 521) {
4045
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4046
   }
4047
#endif
4048
#else
4049
   (void)map;
4050
   (void)heap;
4051
#endif
4052
   return ECC_BAD_ARG_E;
4053
}
4054
#endif /* !WOLFSSL_SP_MATH */
4055
#endif /* !FP_ECC */
4056
4057
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4058
4059
/** ECC Fixed Point mulmod global
4060
    k        The multiplicand
4061
    G        Base point to multiply
4062
    R        [out] Destination of product
4063
    a        ECC curve parameter a
4064
    modulus  The modulus for the curve
4065
    map      [boolean] If non-zero maps the point back to affine coordinates,
4066
             otherwise it's left in jacobian-montgomery form
4067
    return MP_OKAY if successful
4068
*/
4069
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4070
                  mp_int* modulus, int map)
4071
0
{
4072
0
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4073
0
        mp_zero(R->x);
4074
0
        mp_zero(R->y);
4075
0
        mp_set(R->z, 1);
4076
0
        return MP_OKAY;
4077
0
    }
4078
0
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4079
0
}
4080
4081
#endif
4082
4083
/**
4084
 * Allocate a new ECC point (if one not provided)
4085
 * use a heap hint when creating new ecc_point
4086
 * return an allocated point on success or NULL on failure
4087
*/
4088
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4089
0
{
4090
0
   int err = MP_OKAY;
4091
0
   ecc_point* p;
4092
4093
0
   if (point == NULL) {
4094
0
       return BAD_FUNC_ARG;
4095
0
   }
4096
4097
0
   p = *point;
4098
0
   if (p == NULL) {
4099
0
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4100
0
   }
4101
0
   if (p == NULL) {
4102
0
      return MEMORY_E;
4103
0
   }
4104
0
   XMEMSET(p, 0, sizeof(ecc_point));
4105
4106
0
   if (*point == NULL)
4107
0
       p->isAllocated = 1;
4108
4109
0
#ifndef ALT_ECC_SIZE
4110
0
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4111
0
   if (err != MP_OKAY) {
4112
0
      WOLFSSL_MSG("mp_init_multi failed.");
4113
0
      if (p->isAllocated)
4114
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4115
0
      p = NULL;
4116
0
   }
4117
#else
4118
   p->x = (mp_int*)&p->xyz[0];
4119
   p->y = (mp_int*)&p->xyz[1];
4120
   p->z = (mp_int*)&p->xyz[2];
4121
   alt_fp_init(p->x);
4122
   alt_fp_init(p->y);
4123
   alt_fp_init(p->z);
4124
#endif
4125
4126
0
   *point = p;
4127
0
   (void)heap;
4128
0
   return err;
4129
0
} /* wc_ecc_new_point_ex */
4130
4131
ecc_point* wc_ecc_new_point_h(void* heap)
4132
0
{
4133
0
    ecc_point* p = NULL;
4134
0
    (void)wc_ecc_new_point_ex(&p, heap);
4135
0
    return p;
4136
0
}
4137
4138
ecc_point* wc_ecc_new_point(void)
4139
0
{
4140
0
   ecc_point* p = NULL;
4141
0
   (void)wc_ecc_new_point_ex(&p, NULL);
4142
0
   return p;
4143
0
}
4144
4145
/** Free an ECC point from memory
4146
  p   The point to free
4147
*/
4148
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4149
0
{
4150
0
   if (p != NULL) {
4151
0
      mp_clear(p->x);
4152
0
      mp_clear(p->y);
4153
0
      mp_clear(p->z);
4154
0
      if (p->isAllocated)
4155
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4156
0
   }
4157
0
   (void)heap;
4158
0
}
4159
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4160
0
{
4161
0
   wc_ecc_del_point_ex(p, heap);
4162
0
}
4163
void wc_ecc_del_point(ecc_point* p)
4164
0
{
4165
0
    wc_ecc_del_point_ex(p, NULL);
4166
0
}
4167
4168
void wc_ecc_forcezero_point(ecc_point* p)
4169
0
{
4170
0
    if (p != NULL) {
4171
0
        mp_forcezero(p->x);
4172
0
        mp_forcezero(p->y);
4173
0
        mp_forcezero(p->z);
4174
0
    }
4175
0
}
4176
4177
4178
/** Copy the value of a point to an other one
4179
  p    The point to copy
4180
  r    The created point
4181
*/
4182
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4183
0
{
4184
0
    int ret;
4185
4186
    /* prevents null arguments */
4187
0
    if (p == NULL || r == NULL)
4188
0
        return ECC_BAD_ARG_E;
4189
4190
0
    ret = mp_copy(p->x, r->x);
4191
0
    if (ret != MP_OKAY)
4192
0
        return ret;
4193
0
    ret = mp_copy(p->y, r->y);
4194
0
    if (ret != MP_OKAY)
4195
0
        return ret;
4196
0
    ret = mp_copy(p->z, r->z);
4197
0
    if (ret != MP_OKAY)
4198
0
        return ret;
4199
4200
0
    return MP_OKAY;
4201
0
}
4202
4203
/** Compare the value of a point with an other one
4204
 a    The point to compare
4205
 b    The other point to compare
4206
4207
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4208
 */
4209
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4210
0
{
4211
0
    int ret;
4212
4213
    /* prevents null arguments */
4214
0
    if (a == NULL || b == NULL)
4215
0
        return BAD_FUNC_ARG;
4216
4217
0
    ret = mp_cmp(a->x, b->x);
4218
0
    if (ret != MP_EQ)
4219
0
        return ret;
4220
0
    ret = mp_cmp(a->y, b->y);
4221
0
    if (ret != MP_EQ)
4222
0
        return ret;
4223
0
    ret = mp_cmp(a->z, b->z);
4224
0
    if (ret != MP_EQ)
4225
0
        return ret;
4226
4227
0
    return MP_EQ;
4228
0
}
4229
4230
4231
/** Returns whether an ECC idx is valid or not
4232
  n      The idx number to check
4233
  return 1 if valid, 0 if not
4234
*/
4235
int wc_ecc_is_valid_idx(int n)
4236
0
{
4237
0
   int x;
4238
4239
0
   if (n >= (int)ECC_SET_COUNT)
4240
0
       return 0;
4241
4242
0
   for (x = 0; ecc_sets[x].size != 0; x++)
4243
0
       ;
4244
   /* -1 is a valid index --- indicating that the domain params
4245
      were supplied by the user */
4246
0
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4247
0
      return 1;
4248
0
   }
4249
4250
0
   return 0;
4251
0
}
4252
4253
int wc_ecc_get_curve_idx(int curve_id)
4254
0
{
4255
0
    int curve_idx;
4256
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4257
0
        if (curve_id == ecc_sets[curve_idx].id)
4258
0
            break;
4259
0
    }
4260
0
    if (ecc_sets[curve_idx].size == 0) {
4261
0
        return ECC_CURVE_INVALID;
4262
0
    }
4263
0
    return curve_idx;
4264
0
}
4265
4266
int wc_ecc_get_curve_id(int curve_idx)
4267
0
{
4268
0
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4269
0
        return ecc_sets[curve_idx].id;
4270
0
    }
4271
0
    return ECC_CURVE_INVALID;
4272
0
}
4273
4274
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4275
 *
4276
 * id      curve id, from ecc_curve_id enum in ecc.h
4277
 * return  curve size, from ecc_sets[] on success, negative on error
4278
 */
4279
int wc_ecc_get_curve_size_from_id(int curve_id)
4280
0
{
4281
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4282
0
    if (curve_idx == ECC_CURVE_INVALID)
4283
0
        return ECC_BAD_ARG_E;
4284
0
    return ecc_sets[curve_idx].size;
4285
0
}
4286
4287
/* Returns the curve index that corresponds to a given curve name in
4288
 * ecc_sets[] of ecc.c
4289
 *
4290
 * name    curve name, from ecc_sets[].name in ecc.c
4291
 * return  curve index in ecc_sets[] on success, negative on error
4292
 */
4293
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4294
0
{
4295
0
    int curve_idx;
4296
4297
0
    if (curveName == NULL)
4298
0
        return BAD_FUNC_ARG;
4299
4300
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4301
0
        if (
4302
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4303
0
            ecc_sets[curve_idx].name &&
4304
0
        #endif
4305
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4306
0
            break;
4307
0
        }
4308
0
    }
4309
0
    if (ecc_sets[curve_idx].size == 0) {
4310
0
        WOLFSSL_MSG("ecc_set curve name not found");
4311
0
        return ECC_CURVE_INVALID;
4312
0
    }
4313
0
    return curve_idx;
4314
0
}
4315
4316
/* Returns the curve size that corresponds to a given curve name,
4317
 * as listed in ecc_sets[] of ecc.c.
4318
 *
4319
 * name    curve name, from ecc_sets[].name in ecc.c
4320
 * return  curve size, from ecc_sets[] on success, negative on error
4321
 */
4322
int wc_ecc_get_curve_size_from_name(const char* curveName)
4323
0
{
4324
0
    int curve_idx;
4325
4326
0
    if (curveName == NULL)
4327
0
        return BAD_FUNC_ARG;
4328
4329
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4330
0
    if (curve_idx < 0)
4331
0
        return curve_idx;
4332
4333
0
    return ecc_sets[curve_idx].size;
4334
0
}
4335
4336
/* Returns the curve id that corresponds to a given curve name,
4337
 * as listed in ecc_sets[] of ecc.c.
4338
 *
4339
 * name   curve name, from ecc_sets[].name in ecc.c
4340
 * return curve id, from ecc_sets[] on success, negative on error
4341
 */
4342
int wc_ecc_get_curve_id_from_name(const char* curveName)
4343
0
{
4344
0
    int curve_idx;
4345
4346
0
    if (curveName == NULL)
4347
0
        return BAD_FUNC_ARG;
4348
4349
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4350
0
    if (curve_idx < 0)
4351
0
        return curve_idx;
4352
4353
0
    return ecc_sets[curve_idx].id;
4354
0
}
4355
4356
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4357
 * parameter for equality.
4358
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4359
 * Returns MP_EQ on success, negative on error */
4360
static int wc_ecc_cmp_param(const char* curveParam,
4361
                            const byte* param, word32 paramSz, int encType)
4362
0
{
4363
0
    int err = MP_OKAY;
4364
#ifdef WOLFSSL_SMALL_STACK
4365
    mp_int* a = NULL;
4366
    mp_int* b = NULL;
4367
#else
4368
0
    mp_int  a[1], b[1];
4369
0
#endif
4370
4371
0
    if (param == NULL || curveParam == NULL)
4372
0
        return BAD_FUNC_ARG;
4373
4374
0
    if (encType == WC_TYPE_HEX_STR) {
4375
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4376
0
            return -1;
4377
0
        return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1;
4378
0
    }
4379
4380
#ifdef WOLFSSL_SMALL_STACK
4381
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4382
    if (a == NULL)
4383
        return MEMORY_E;
4384
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4385
    if (b == NULL) {
4386
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4387
        return MEMORY_E;
4388
    }
4389
#endif
4390
4391
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4392
    #ifdef WOLFSSL_SMALL_STACK
4393
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4394
        XFREE(b, NULL, DYNAMIC_TYPE_ECC);
4395
    #endif
4396
0
        return err;
4397
0
    }
4398
4399
0
    if (err == MP_OKAY) {
4400
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4401
0
    }
4402
0
    if (err == MP_OKAY)
4403
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4404
4405
0
    if (err == MP_OKAY) {
4406
0
        if (mp_cmp(a, b) != MP_EQ) {
4407
0
            err = -1;
4408
0
        } else {
4409
0
            err = MP_EQ;
4410
0
        }
4411
0
    }
4412
4413
0
    mp_clear(a);
4414
0
    mp_clear(b);
4415
#ifdef WOLFSSL_SMALL_STACK
4416
    XFREE(b, NULL, DYNAMIC_TYPE_ECC);
4417
    XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4418
#endif
4419
4420
0
    return err;
4421
0
}
4422
4423
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4424
 * curve parameters.
4425
 *
4426
 * fieldSize  the field size in bits
4427
 * prime      prime of the finite field
4428
 * primeSz    size of prime in octets
4429
 * Af         first coefficient a of the curve
4430
 * AfSz       size of Af in octets
4431
 * Bf         second coefficient b of the curve
4432
 * BfSz       size of Bf in octets
4433
 * order      curve order
4434
 * orderSz    size of curve in octets
4435
 * Gx         affine x coordinate of base point
4436
 * GxSz       size of Gx in octets
4437
 * Gy         affine y coordinate of base point
4438
 * GySz       size of Gy in octets
4439
 * cofactor   curve cofactor
4440
 *
4441
 * return curve id, from ecc_sets[] on success, negative on error
4442
 */
4443
int wc_ecc_get_curve_id_from_params(int fieldSize,
4444
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4445
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4446
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4447
0
{
4448
0
    int idx;
4449
0
    int curveSz;
4450
4451
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4452
0
        Gx == NULL || Gy == NULL)
4453
0
        return BAD_FUNC_ARG;
4454
4455
0
    curveSz = (fieldSize + 1) / 8;    /* round up */
4456
4457
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4458
0
        if (curveSz == ecc_sets[idx].size) {
4459
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4460
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4461
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4462
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4463
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4464
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4465
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4466
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4467
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4468
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4469
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4470
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4471
0
                (cofactor == ecc_sets[idx].cofactor)) {
4472
0
                    break;
4473
0
            }
4474
0
        }
4475
0
    }
4476
4477
0
    if (ecc_sets[idx].size == 0)
4478
0
        return ECC_CURVE_INVALID;
4479
4480
0
    return ecc_sets[idx].id;
4481
0
}
4482
4483
/* Returns the curve id in ecc_sets[] that corresponds
4484
 * to a given domain parameters pointer.
4485
 *
4486
 * dp   domain parameters pointer
4487
 *
4488
 * return curve id, from ecc_sets[] on success, negative on error
4489
 */
4490
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4491
0
{
4492
0
    int idx;
4493
4494
0
    if (dp == NULL
4495
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4496
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4497
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4498
0
    #endif
4499
0
    ) {
4500
0
        return BAD_FUNC_ARG;
4501
0
    }
4502
4503
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4504
0
        if (dp->size == ecc_sets[idx].size) {
4505
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4506
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4507
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4508
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4509
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4510
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4511
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4512
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4513
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4514
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4515
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4516
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4517
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4518
0
                    break;
4519
0
            }
4520
0
        }
4521
0
    }
4522
4523
0
    if (ecc_sets[idx].size == 0)
4524
0
        return ECC_CURVE_INVALID;
4525
4526
0
    return ecc_sets[idx].id;
4527
0
}
4528
4529
/* Returns the curve id that corresponds to a given OID,
4530
 * as listed in ecc_sets[] of ecc.c.
4531
 *
4532
 * oid   OID, from ecc_sets[].name in ecc.c
4533
 * len   OID len, from ecc_sets[].name in ecc.c
4534
 * return curve id, from ecc_sets[] on success, negative on error
4535
 */
4536
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4537
0
{
4538
0
    int curve_idx;
4539
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4540
    int ret;
4541
    #ifdef HAVE_OID_DECODING
4542
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4543
    #else
4544
    byte  decOid[MAX_OID_SZ];
4545
    #endif
4546
    word32 decOidSz;
4547
#endif
4548
4549
0
    if (oid == NULL)
4550
0
        return BAD_FUNC_ARG;
4551
4552
#ifdef HAVE_OID_DECODING
4553
    decOidSz = (word32)sizeof(decOid);
4554
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4555
    if (ret != 0) {
4556
        return ret;
4557
    }
4558
#endif
4559
4560
0
    if (len == 0) {
4561
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4562
0
        WOLFSSL_MSG("zero oidSz");
4563
0
        return ECC_CURVE_INVALID;
4564
0
    }
4565
4566
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4567
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4568
        decOidSz = (word32)sizeof(decOid);
4569
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4570
            decOid, &decOidSz);
4571
        if (ret != 0) {
4572
            continue;
4573
        }
4574
    #endif
4575
4576
0
        if (
4577
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4578
0
            ecc_sets[curve_idx].oid &&
4579
0
        #endif
4580
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4581
            decOidSz == len &&
4582
                XMEMCMP(decOid, oid, len) == 0
4583
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4584
            /* We double because decOidSz is a count of word16 elements. */
4585
            ecc_sets[curve_idx].oidSz == decOidSz &&
4586
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4587
        #else
4588
0
            ecc_sets[curve_idx].oidSz == len &&
4589
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4590
0
        #endif
4591
0
        ) {
4592
0
            break;
4593
0
        }
4594
0
    }
4595
0
    if (ecc_sets[curve_idx].size == 0) {
4596
0
        WOLFSSL_MSG("ecc_set curve name not found");
4597
0
        return ECC_CURVE_INVALID;
4598
0
    }
4599
4600
0
    return ecc_sets[curve_idx].id;
4601
0
}
4602
4603
/* Get curve parameters using curve index */
4604
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4605
0
{
4606
0
    const ecc_set_type* ecc_set = NULL;
4607
4608
0
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4609
0
        ecc_set = &ecc_sets[curve_idx];
4610
0
    }
4611
0
    return ecc_set;
4612
0
}
4613
4614
4615
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4616
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4617
{
4618
   if (key == NULL || mp == NULL)
4619
      return BAD_FUNC_ARG;
4620
   if (*mp == NULL) {
4621
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4622
      if (*mp == NULL) {
4623
         return MEMORY_E;
4624
      }
4625
      XMEMSET(*mp, 0, sizeof(mp_int));
4626
   }
4627
   return 0;
4628
}
4629
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4630
{
4631
   if (key && mp && *mp) {
4632
      mp_clear(*mp);
4633
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4634
      *mp = NULL;
4635
   }
4636
}
4637
4638
static int wc_ecc_alloc_async(ecc_key* key)
4639
{
4640
    int err = wc_ecc_alloc_mpint(key, &key->r);
4641
    if (err == 0)
4642
        err = wc_ecc_alloc_mpint(key, &key->s);
4643
    return err;
4644
}
4645
4646
static void wc_ecc_free_async(ecc_key* key)
4647
{
4648
    wc_ecc_free_mpint(key, &key->r);
4649
    wc_ecc_free_mpint(key, &key->s);
4650
#ifdef HAVE_CAVIUM_V
4651
    wc_ecc_free_mpint(key, &key->e);
4652
    wc_ecc_free_mpint(key, &key->signK);
4653
#endif /* HAVE_CAVIUM_V */
4654
}
4655
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4656
4657
4658
#ifdef HAVE_ECC_DHE
4659
/**
4660
  Create an ECC shared secret between two keys
4661
  private_key      The private ECC key (heap hint based off of private key)
4662
  public_key       The public key
4663
  out              [out] Destination of the shared secret
4664
                         Conforms to EC-DH from ANSI X9.63
4665
  outlen           [in/out] The max size and resulting size of the shared secret
4666
  return           MP_OKAY if successful
4667
*/
4668
WOLFSSL_ABI
4669
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4670
                      word32* outlen)
4671
0
{
4672
0
   int err = 0;
4673
4674
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4675
   !defined(WOLFSSL_ATECC608A)
4676
   CRYS_ECDH_TempData_t tempBuff;
4677
#endif
4678
4679
0
   (void)err;
4680
4681
0
   if (private_key == NULL || public_key == NULL || out == NULL ||
4682
0
                                                            outlen == NULL) {
4683
0
       return BAD_FUNC_ARG;
4684
0
   }
4685
4686
#ifdef WOLF_CRYPTO_CB
4687
    #ifndef WOLF_CRYPTO_CB_FIND
4688
    if (private_key->devId != INVALID_DEVID)
4689
    #endif
4690
    {
4691
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4692
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4693
            return err;
4694
        /* fall-through when unavailable */
4695
    }
4696
#endif
4697
4698
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4699
    return NO_VALID_DEVID;
4700
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4701
   /* type valid? */
4702
0
   if (private_key->type != ECC_PRIVATEKEY &&
4703
0
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4704
0
      return ECC_BAD_ARG_E;
4705
0
   }
4706
4707
   /* Verify domain params supplied */
4708
0
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4709
0
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4710
0
      return ECC_BAD_ARG_E;
4711
0
   }
4712
4713
   /* Verify curve id matches */
4714
0
   if (private_key->dp->id != public_key->dp->id) {
4715
0
      return ECC_BAD_ARG_E;
4716
0
   }
4717
4718
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4719
   /* For SECP256R1 use hardware */
4720
   if (private_key->dp->id == ECC_SECP256R1) {
4721
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4722
       *outlen = private_key->dp->size;
4723
   }
4724
   else {
4725
      err = NOT_COMPILED_IN;
4726
   }
4727
#elif defined(WOLFSSL_CRYPTOCELL)
4728
4729
    /* generate a secret*/
4730
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4731
                            &private_key->ctx.privKey,
4732
                            out,
4733
                            (uint32_t*)outlen,
4734
                            &tempBuff);
4735
4736
    if (err != SA_SILIB_RET_OK){
4737
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4738
        return err;
4739
    }
4740
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4741
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4742
#elif defined(WOLFSSL_KCAPI_ECC)
4743
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4744
#elif defined(WOLFSSL_SE050)
4745
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4746
#else
4747
0
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4748
0
#endif /* WOLFSSL_ATECC508A */
4749
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4750
4751
0
   return err;
4752
0
}
4753
4754
4755
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4756
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4757
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4758
4759
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4760
                               byte* out, word32* outlen)
4761
0
{
4762
0
    int err = MP_OKAY;
4763
0
    mp_int* k = ecc_get_k(private_key);
4764
#ifdef HAVE_ECC_CDH
4765
#ifdef WOLFSSL_SMALL_STACK
4766
    mp_int *k_lcl = NULL;
4767
#else
4768
    mp_int k_lcl[1];
4769
#endif
4770
#endif
4771
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4772
    defined(WC_ECC_NONBLOCK_ONLY)
4773
    ecc_nb_ctx_t nb_ctx;
4774
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4775
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4776
4777
#ifdef HAVE_ECC_CDH
4778
    /* if cofactor flag has been set */
4779
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4780
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4781
        /* only perform cofactor calc if not equal to 1 */
4782
        if (cofactor != 1) {
4783
#ifdef WOLFSSL_SMALL_STACK
4784
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4785
                return MEMORY_E;
4786
#endif
4787
            k = k_lcl;
4788
            if (mp_init(k) != MP_OKAY) {
4789
                err = MEMORY_E;
4790
                goto errout;
4791
            }
4792
            /* multiply cofactor times private key "k" */
4793
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4794
            if (err != MP_OKAY)
4795
                goto errout;
4796
        }
4797
    }
4798
#endif
4799
4800
#ifdef WOLFSSL_HAVE_SP_ECC
4801
4802
#ifndef WOLFSSL_SP_NO_256
4803
    if (private_key->idx != ECC_CUSTOM_IDX &&
4804
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4805
    #ifndef WC_ECC_NONBLOCK
4806
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4807
    #else
4808
        if (private_key->nb_ctx) {
4809
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4810
                                           point, out, outlen,
4811
                                           private_key->heap);
4812
        }
4813
        else {
4814
        #ifdef WC_ECC_NONBLOCK_ONLY
4815
            do { /* perform blocking call to non-blocking function */
4816
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4817
                                               outlen, private_key->heap);
4818
            } while (err == FP_WOULDBLOCK);
4819
        #else
4820
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4821
                                        private_key->heap);
4822
        #endif /* WC_ECC_NONBLOCK_ONLY */
4823
        }
4824
    #endif /* !WC_ECC_NONBLOCK */
4825
    }
4826
    else
4827
#endif /* ! WOLFSSL_SP_NO_256 */
4828
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4829
    if (private_key->idx != ECC_CUSTOM_IDX &&
4830
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4831
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4832
                                                             private_key->heap);
4833
    }
4834
    else
4835
#endif
4836
#ifdef WOLFSSL_SP_384
4837
    if (private_key->idx != ECC_CUSTOM_IDX &&
4838
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4839
    #ifndef WC_ECC_NONBLOCK
4840
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4841
    #else
4842
        if (private_key->nb_ctx) {
4843
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4844
                                           point, out, outlen,
4845
                                           private_key->heap);
4846
        }
4847
        else {
4848
        #ifdef WC_ECC_NONBLOCK_ONLY
4849
            do { /* perform blocking call to non-blocking function */
4850
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4851
                                               outlen, private_key->heap);
4852
            } while (err == FP_WOULDBLOCK);
4853
        #else
4854
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4855
                                        private_key->heap);
4856
        #endif /* WC_ECC_NONBLOCK_ONLY */
4857
        }
4858
    #endif /* !WC_ECC_NONBLOCK */
4859
    }
4860
    else
4861
#endif /* WOLFSSL_SP_384 */
4862
#ifdef WOLFSSL_SP_521
4863
    if (private_key->idx != ECC_CUSTOM_IDX &&
4864
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4865
    #ifndef WC_ECC_NONBLOCK
4866
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4867
    #else
4868
        if (private_key->nb_ctx) {
4869
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4870
                                           point, out, outlen,
4871
                                           private_key->heap);
4872
        }
4873
        else {
4874
        #ifdef WC_ECC_NONBLOCK_ONLY
4875
            do { /* perform blocking call to non-blocking function */
4876
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4877
                                               outlen, private_key->heap);
4878
            } while (err == FP_WOULDBLOCK);
4879
        #else
4880
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4881
                                        private_key->heap);
4882
        #endif /* WC_ECC_NONBLOCK_ONLY */
4883
        }
4884
    #endif /* !WC_ECC_NONBLOCK */
4885
    }
4886
    else
4887
#endif /* WOLFSSL_SP_521 */
4888
#else
4889
0
    (void)point;
4890
0
    (void)out;
4891
0
    (void)outlen;
4892
0
    (void)k;
4893
0
#endif
4894
#if defined(WOLFSSL_SP_MATH)
4895
    {
4896
        err = WC_KEY_SIZE_E;
4897
        goto errout;
4898
    }
4899
#else
4900
0
    {
4901
0
        ecc_point* result = NULL;
4902
        #ifdef WOLFSSL_NO_MALLOC
4903
        ecc_point  lcl_result;
4904
        #endif
4905
0
        int x = 0;
4906
0
        mp_digit mp = 0;
4907
0
        DECLARE_CURVE_SPECS(3);
4908
4909
        /* load curve info */
4910
0
        ALLOC_CURVE_SPECS(3, err);
4911
0
        if (err == MP_OKAY) {
4912
0
            err = wc_ecc_curve_load(private_key->dp, &curve,
4913
0
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4914
0
                 ECC_CURVE_FIELD_ORDER));
4915
0
        }
4916
4917
0
        if (err != MP_OKAY) {
4918
0
            FREE_CURVE_SPECS();
4919
0
            goto errout;
4920
0
        }
4921
4922
        /* make new point */
4923
    #ifdef WOLFSSL_NO_MALLOC
4924
        result = &lcl_result;
4925
    #endif
4926
0
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4927
0
        if (err != MP_OKAY) {
4928
0
            wc_ecc_curve_free(curve);
4929
0
            FREE_CURVE_SPECS();
4930
0
            goto errout;
4931
0
        }
4932
4933
0
#ifdef ECC_TIMING_RESISTANT
4934
0
        if (private_key->rng == NULL) {
4935
0
            err = MISSING_RNG_E;
4936
0
        }
4937
0
#endif
4938
4939
0
        if (err == MP_OKAY) {
4940
            /* Map in a separate call as this should be constant time */
4941
0
#ifdef ECC_TIMING_RESISTANT
4942
0
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4943
0
                                              curve->order, private_key->rng, 0,
4944
0
                                              private_key->heap);
4945
#else
4946
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4947
                                      curve->order, NULL, 0, private_key->heap);
4948
#endif
4949
0
        }
4950
0
        if (err == MP_OKAY) {
4951
        #ifdef WOLFSSL_CHECK_MEM_ZERO
4952
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
4953
                result->x);
4954
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
4955
                result->y);
4956
        #endif
4957
0
            err = mp_montgomery_setup(curve->prime, &mp);
4958
0
        }
4959
0
        if (err == MP_OKAY) {
4960
            /* Use constant time map if compiled in */
4961
0
            err = ecc_map_ex(result, curve->prime, mp, 1);
4962
0
        }
4963
0
        if (err == MP_OKAY) {
4964
0
            x = mp_unsigned_bin_size(curve->prime);
4965
0
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4966
0
                err = BUFFER_E;
4967
0
            }
4968
0
        }
4969
4970
0
        if (err == MP_OKAY) {
4971
0
            XMEMSET(out, 0, (size_t)x);
4972
0
            err = mp_to_unsigned_bin(result->x, out +
4973
0
                                     (x - mp_unsigned_bin_size(result->x)));
4974
0
        }
4975
0
        *outlen = (word32)x;
4976
4977
0
        mp_forcezero(result->x);
4978
0
        mp_forcezero(result->y);
4979
0
        wc_ecc_del_point_ex(result, private_key->heap);
4980
4981
0
        wc_ecc_curve_free(curve);
4982
0
        FREE_CURVE_SPECS();
4983
0
    }
4984
0
#endif
4985
4986
0
  errout:
4987
4988
#ifdef HAVE_ECC_CDH
4989
    if (k == k_lcl)
4990
        mp_clear(k);
4991
#ifdef WOLFSSL_SMALL_STACK
4992
    XFREE(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
4993
#endif
4994
#endif
4995
4996
0
    return err;
4997
0
}
4998
4999
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5000
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
5001
            ecc_point* point, byte* out, word32 *outlen)
5002
{
5003
    int err = 0;
5004
5005
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5006
    DECLARE_CURVE_SPECS(3);
5007
5008
    /* load curve info */
5009
    ALLOC_CURVE_SPECS(3, err);
5010
    if (err == MP_OKAY) {
5011
        err = wc_ecc_curve_load(private_key->dp, &curve,
5012
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5013
             ECC_CURVE_FIELD_ORDER));
5014
    }
5015
5016
    if (err != MP_OKAY) {
5017
        FREE_CURVE_SPECS();
5018
        return err;
5019
    }
5020
5021
    if (private_key->dp
5022
    #ifdef WOLFSSL_CUSTOM_CURVES
5023
        && private_key->dp->id != ECC_CURVE_CUSTOM
5024
    #endif
5025
    #ifdef HAVE_CAVIUM_V
5026
        /* verify the curve is supported by hardware */
5027
        && NitroxEccIsCurveSupported(private_key)
5028
    #endif
5029
    ) {
5030
        word32 keySz = private_key->dp->size;
5031
5032
        /* sync public key x/y */
5033
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5034
            &ecc_get_k(private_key)->raw, keySz);
5035
        if (err == MP_OKAY)
5036
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5037
        if (err == MP_OKAY)
5038
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5039
    #ifdef HAVE_CAVIUM_V
5040
        /* allocate buffer for output */
5041
        if (err == MP_OKAY)
5042
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5043
        if (err == MP_OKAY)
5044
            err = wc_bigint_alloc(&private_key->e->raw,
5045
                NitroxEccGetSize(private_key)*2);
5046
        if (err == MP_OKAY)
5047
            err = NitroxEcdh(private_key,
5048
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5049
                private_key->e->raw.buf, &private_key->e->raw.len,
5050
                &curve->prime->raw);
5051
    #else
5052
        if (err == MP_OKAY)
5053
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5054
        if (err == MP_OKAY)
5055
            err = IntelQaEcdh(&private_key->asyncDev,
5056
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5057
                out, outlen,
5058
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5059
                private_key->dp->cofactor);
5060
    #endif
5061
    }
5062
    else
5063
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5064
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5065
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5066
        sw->eccSharedSec.private_key = private_key;
5067
        sw->eccSharedSec.public_point = point;
5068
        sw->eccSharedSec.out = out;
5069
        sw->eccSharedSec.outLen = outlen;
5070
        err = WC_PENDING_E;
5071
    }
5072
    else
5073
#endif
5074
    {
5075
        /* use sync in other cases */
5076
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5077
    }
5078
5079
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5080
        private_key->state++;
5081
    }
5082
5083
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5084
    wc_ecc_curve_free(curve);
5085
    FREE_CURVE_SPECS();
5086
#endif
5087
5088
    return err;
5089
}
5090
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5091
5092
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5093
/**
5094
 Create an ECC shared secret between private key and public point
5095
 private_key      The private ECC key (heap hint based on private key)
5096
 point            The point to use (public key)
5097
 out              [out] Destination of the shared secret
5098
                        Conforms to EC-DH from ANSI X9.63
5099
 outlen           [in/out] The max size and resulting size of the shared secret
5100
 return           MP_OKAY if successful
5101
*/
5102
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5103
                            byte* out, word32 *outlen)
5104
0
{
5105
0
    int err;
5106
5107
0
    if (private_key == NULL || point == NULL || out == NULL ||
5108
0
                                                            outlen == NULL) {
5109
0
        return BAD_FUNC_ARG;
5110
0
    }
5111
5112
    /* type valid? */
5113
0
    if (private_key->type != ECC_PRIVATEKEY &&
5114
0
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5115
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5116
0
        return ECC_BAD_ARG_E;
5117
0
    }
5118
5119
    /* Verify domain params supplied */
5120
0
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5121
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5122
0
        return ECC_BAD_ARG_E;
5123
0
    }
5124
5125
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5126
5127
0
    switch (private_key->state) {
5128
0
        case ECC_STATE_NONE:
5129
0
        case ECC_STATE_SHARED_SEC_GEN:
5130
0
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5131
5132
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5133
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5134
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5135
                    out, outlen);
5136
            }
5137
            else
5138
        #endif
5139
0
            {
5140
0
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5141
0
                    out, outlen);
5142
0
            }
5143
0
            if (err < 0) {
5144
0
                break;
5145
0
            }
5146
0
            FALL_THROUGH;
5147
5148
0
        case ECC_STATE_SHARED_SEC_RES:
5149
0
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5150
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5151
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5152
            #ifdef HAVE_CAVIUM_V
5153
                /* verify the curve is supported by hardware */
5154
                if (NitroxEccIsCurveSupported(private_key)) {
5155
                    /* copy output */
5156
                    *outlen = private_key->dp->size;
5157
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5158
                }
5159
            #endif /* HAVE_CAVIUM_V */
5160
            }
5161
        #endif /* WOLFSSL_ASYNC_CRYPT */
5162
0
            err = 0;
5163
0
            break;
5164
5165
0
        default:
5166
0
            err = BAD_STATE_E;
5167
0
    } /* switch */
5168
5169
0
    RESTORE_VECTOR_REGISTERS();
5170
5171
    /* if async pending then return and skip done cleanup below */
5172
0
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5173
0
        return err;
5174
0
    }
5175
5176
    /* cleanup */
5177
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5178
    wc_ecc_free_async(private_key);
5179
#endif
5180
0
    private_key->state = ECC_STATE_NONE;
5181
5182
0
    return err;
5183
0
}
5184
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5185
#elif defined(WOLFSSL_KCAPI_ECC)
5186
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5187
                            byte* out, word32 *outlen)
5188
{
5189
    int err;
5190
    ecc_key public_key;
5191
5192
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
5193
    if (err == MP_OKAY) {
5194
        #if FIPS_VERSION3_GE(6,0,0)
5195
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5196
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5197
         * keysize here when relying on default selection */
5198
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5199
            if (private_key->dp->size == 0 &&
5200
                (private_key->dp->id == ECC_SECP256R1 ||
5201
                private_key->dp->id == ECC_SECP224R1 ||
5202
                private_key->dp->id == ECC_SECP384R1 ||
5203
                private_key->dp->id == ECC_SECP521R1)) {
5204
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5205
                err = 0;
5206
            } else {
5207
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5208
                err = ECC_CURVE_OID_E;
5209
            }
5210
        }
5211
        if (err == 0) { /* FIPS specific check */
5212
        #endif
5213
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
5214
                               private_key->dp->id);
5215
        if (err == MP_OKAY) {
5216
            err = mp_copy(point->x, public_key.pubkey.x);
5217
        }
5218
        #if FIPS_VERSION3_GE(6,0,0)
5219
        } /* end FIPS specific check */
5220
        #endif
5221
        if (err == MP_OKAY) {
5222
            err = mp_copy(point->y, public_key.pubkey.y);
5223
        }
5224
        if (err == MP_OKAY) {
5225
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
5226
        }
5227
5228
        wc_ecc_free(&public_key);
5229
    }
5230
5231
    return err;
5232
}
5233
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5234
#endif /* HAVE_ECC_DHE */
5235
5236
#ifdef USE_ECC_B_PARAM
5237
/* Checks if a point p lies on the curve with index curve_idx */
5238
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5239
{
5240
    int err = MP_OKAY;
5241
    DECLARE_CURVE_SPECS(3);
5242
5243
    if (p == NULL)
5244
        return BAD_FUNC_ARG;
5245
5246
    /* is the IDX valid ?  */
5247
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5248
       return ECC_BAD_ARG_E;
5249
    }
5250
5251
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5252
5253
    ALLOC_CURVE_SPECS(3, err);
5254
    if (err == MP_OKAY) {
5255
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5256
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5257
                                ECC_CURVE_FIELD_BF);
5258
    }
5259
5260
    if (err == MP_OKAY) {
5261
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5262
    }
5263
5264
    wc_ecc_curve_free(curve);
5265
    FREE_CURVE_SPECS();
5266
5267
    RESTORE_VECTOR_REGISTERS();
5268
5269
    return err;
5270
}
5271
#endif /* USE_ECC_B_PARAM */
5272
5273
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5274
    !defined(WOLFSSL_CRYPTOCELL) && \
5275
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5276
      defined(WOLFSSL_IMXRT1170_CAAM))
5277
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5278
int wc_ecc_point_is_at_infinity(ecc_point* p)
5279
0
{
5280
0
    if (p == NULL)
5281
0
        return BAD_FUNC_ARG;
5282
0
    if (mp_iszero(p->x) && mp_iszero(p->y))
5283
0
        return 1;
5284
5285
0
    return 0;
5286
0
}
5287
#endif
5288
5289
/* generate random and ensure its greater than 0 and less than order */
5290
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5291
0
{
5292
0
#ifndef WC_NO_RNG
5293
0
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5294
0
    int err;
5295
0
    byte buf[ECC_MAXSIZE_GEN];
5296
5297
0
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5298
0
                                                                order == NULL) {
5299
0
        return BAD_FUNC_ARG;
5300
0
    }
5301
5302
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5303
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5304
0
    size += 8;
5305
5306
    /* make up random string */
5307
0
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5308
#ifdef WOLFSSL_CHECK_MEM_ZERO
5309
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5310
#endif
5311
5312
    /* load random buffer data into k */
5313
0
    if (err == 0)
5314
0
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5315
5316
    /* the key should be smaller than the order of base point */
5317
0
    if (err == MP_OKAY) {
5318
0
        if (mp_cmp(k, order) != MP_LT) {
5319
0
            err = mp_mod(k, order, k);
5320
0
        }
5321
0
    }
5322
5323
    /* quick sanity check to make sure we're not dealing with a 0 key */
5324
0
    if (err == MP_OKAY) {
5325
0
        if (mp_iszero(k) == MP_YES)
5326
0
          err = MP_ZERO_E;
5327
0
    }
5328
5329
0
    ForceZero(buf, ECC_MAXSIZE_GEN);
5330
#ifdef WOLFSSL_CHECK_MEM_ZERO
5331
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5332
#endif
5333
5334
0
    return err;
5335
#else
5336
    int err;
5337
    byte buf[ECC_MAXSIZE_GEN];
5338
    int bits;
5339
5340
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5341
            (k == NULL) || (order == NULL)) {
5342
        return BAD_FUNC_ARG;
5343
    }
5344
5345
    /* Get actual bit count of order. */
5346
    bits = mp_count_bits(order);
5347
    size = (bits + 7) >> 3;
5348
5349
    /* generate number in range of order through rejection sampling. */
5350
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5351
    do {
5352
        /* A.2.2 step 3: make up random string */
5353
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5354
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5355
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5356
    #endif
5357
        /* Generated multiple of 8 bits but now make it size of order. */
5358
        if ((bits & 0x7) > 0) {
5359
            buf[0] &= (1 << (bits & 0x7)) - 1;
5360
        }
5361
5362
        /* A.2.2 step 4: convert to integer. */
5363
        /* A.4.2 step 3: Convert the bit string to integer x. */
5364
        if (err == 0) {
5365
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5366
        }
5367
5368
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5369
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5370
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5371
            break;
5372
        }
5373
    }
5374
    while (err == MP_OKAY);
5375
5376
    ForceZero(buf, ECC_MAXSIZE_GEN);
5377
#ifdef WOLFSSL_CHECK_MEM_ZERO
5378
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5379
#endif
5380
5381
    return err;
5382
#endif
5383
#else
5384
    (void)rng;
5385
    (void)size;
5386
    (void)k;
5387
    (void)order;
5388
    return NOT_COMPILED_IN;
5389
#endif /* !WC_NO_RNG */
5390
0
}
5391
5392
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5393
0
{
5394
    /* make sure required key variables are reset */
5395
0
    key->state = ECC_STATE_NONE;
5396
0
}
5397
5398
5399
/* create the public ECC key from a private key
5400
 *
5401
 * key     an initialized private key to generate public part from
5402
 * curve   [in]curve for key, cannot be NULL
5403
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5404
 *         is cached in key instead.
5405
 *
5406
 * Note this function is local to the file because of the argument type
5407
 *      ecc_curve_spec. Having this argument allows for not having to load the
5408
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5409
 * For async the results are placed directly into pubOut, so this function
5410
 *      does not need to be called again
5411
 *
5412
 * returns MP_OKAY on success
5413
 */
5414
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5415
        ecc_point* pubOut, WC_RNG* rng)
5416
0
{
5417
0
    int err = MP_OKAY;
5418
0
#ifdef HAVE_ECC_MAKE_PUB
5419
0
    ecc_point* pub;
5420
0
#endif /* HAVE_ECC_MAKE_PUB */
5421
5422
0
    (void)rng;
5423
5424
0
    if (key == NULL) {
5425
0
        return BAD_FUNC_ARG;
5426
0
    }
5427
5428
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5429
5430
0
#ifdef HAVE_ECC_MAKE_PUB
5431
    /* if ecc_point passed in then use it as output for public key point */
5432
0
    if (pubOut != NULL) {
5433
0
        pub = pubOut;
5434
0
    }
5435
0
    else {
5436
        /* caching public key making it a ECC_PRIVATEKEY instead of
5437
           ECC_PRIVATEKEY_ONLY */
5438
0
        pub = &key->pubkey;
5439
0
        key->type = ECC_PRIVATEKEY_ONLY;
5440
0
    }
5441
5442
0
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5443
0
            mp_isneg(ecc_get_k(key)) ||
5444
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5445
0
        err = ECC_PRIV_KEY_E;
5446
0
    }
5447
5448
0
    if (err == MP_OKAY) {
5449
0
    #ifndef ALT_ECC_SIZE
5450
0
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5451
    #else
5452
        pub->x = (mp_int*)&pub->xyz[0];
5453
        pub->y = (mp_int*)&pub->xyz[1];
5454
        pub->z = (mp_int*)&pub->xyz[2];
5455
        alt_fp_init(pub->x);
5456
        alt_fp_init(pub->y);
5457
        alt_fp_init(pub->z);
5458
    #endif
5459
0
    }
5460
5461
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5462
    defined(HAVE_INTEL_QA)
5463
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5464
        word32 keySz = key->dp->size;
5465
        /* sync private key to raw */
5466
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5467
        if (err == MP_OKAY) {
5468
            err = IntelQaEccPointMul(&key->asyncDev,
5469
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5470
                &curve->Gx->raw, &curve->Gy->raw,
5471
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5472
                key->dp->cofactor);
5473
        }
5474
    }
5475
    else
5476
#endif
5477
0
    { /* BEGIN: Software Crypto */
5478
#ifdef WOLFSSL_HAVE_SP_ECC
5479
    /* Single-Precision Math (optimized for specific curves) */
5480
    if (err != MP_OKAY) {
5481
    }
5482
    else
5483
#ifndef WOLFSSL_SP_NO_256
5484
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5485
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5486
    }
5487
    else
5488
#endif /* WOLFSSL_SP_NO_256 */
5489
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5490
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5491
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5492
    }
5493
    else
5494
#endif
5495
#ifdef WOLFSSL_SP_384
5496
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5497
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5498
    }
5499
    else
5500
#endif
5501
#ifdef WOLFSSL_SP_521
5502
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5503
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5504
    }
5505
    else
5506
#endif
5507
#endif /* WOLFSSL_HAVE_SP_ECC */
5508
5509
#if defined(WOLFSSL_SP_MATH)
5510
        err = WC_KEY_SIZE_E;
5511
#else
5512
0
    if (err == MP_OKAY) {
5513
        /* Multi-Precision Math: compute public curve */
5514
0
        mp_digit mp = 0;
5515
0
        ecc_point* base = NULL;
5516
    #ifdef WOLFSSL_NO_MALLOC
5517
        ecc_point  lcl_base;
5518
        base = &lcl_base;
5519
    #endif
5520
0
        err = wc_ecc_new_point_ex(&base, key->heap);
5521
5522
        /* read in the x/y for this key */
5523
0
        if (err == MP_OKAY)
5524
0
            err = mp_copy(curve->Gx, base->x);
5525
0
        if (err == MP_OKAY)
5526
0
            err = mp_copy(curve->Gy, base->y);
5527
0
        if (err == MP_OKAY)
5528
0
            err = mp_montgomery_setup(curve->prime, &mp);
5529
0
        if (err == MP_OKAY)
5530
0
            err = mp_set(base->z, 1);
5531
5532
        /* make the public key */
5533
0
        if (err == MP_OKAY) {
5534
            /* Map in a separate call as this should be constant time */
5535
0
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5536
0
                                 curve->prime, curve->order, rng, 0, key->heap);
5537
0
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5538
0
               err = MEMORY_E;
5539
0
            }
5540
0
        }
5541
0
        if (err == MP_OKAY) {
5542
            /* Use constant time map if compiled in */
5543
0
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5544
0
        }
5545
5546
0
        wc_ecc_del_point_ex(base, key->heap);
5547
0
    }
5548
0
#endif /* WOLFSSL_SP_MATH */
5549
0
    } /* END: Software Crypto */
5550
5551
0
    if (err != MP_OKAY
5552
    #ifdef WOLFSSL_ASYNC_CRYPT
5553
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5554
    #endif
5555
0
    ) {
5556
        /* clean up if failed */
5557
0
    #ifndef ALT_ECC_SIZE
5558
0
        mp_clear(pub->x);
5559
0
        mp_clear(pub->y);
5560
0
        mp_clear(pub->z);
5561
0
    #endif
5562
0
    }
5563
5564
#else
5565
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5566
    (void)curve;
5567
    err = NOT_COMPILED_IN;
5568
#endif /* HAVE_ECC_MAKE_PUB */
5569
5570
    /* change key state if public part is cached */
5571
0
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5572
0
        key->type = ECC_PRIVATEKEY;
5573
0
    }
5574
5575
0
    RESTORE_VECTOR_REGISTERS();
5576
5577
0
    return err;
5578
0
}
5579
5580
5581
/* create the public ECC key from a private key
5582
 *
5583
 * key     an initialized private key to generate public part from
5584
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5585
 *         is cached in key instead.
5586
 *
5587
 *
5588
 * returns MP_OKAY on success
5589
 */
5590
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5591
0
{
5592
0
    WOLFSSL_ENTER("wc_ecc_make_pub");
5593
5594
0
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5595
0
}
5596
5597
/* create the public ECC key from a private key - mask timing use random z
5598
 *
5599
 * key     an initialized private key to generate public part from
5600
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5601
 *         is cached in key instead.
5602
 *
5603
 *
5604
 * returns MP_OKAY on success
5605
 */
5606
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5607
0
{
5608
0
    int err = MP_OKAY;
5609
0
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5610
5611
0
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5612
5613
0
    if (key == NULL) {
5614
0
        return BAD_FUNC_ARG;
5615
0
    }
5616
5617
    /* load curve info */
5618
0
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5619
0
    if (err == MP_OKAY) {
5620
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5621
0
    }
5622
0
    if (err == MP_OKAY) {
5623
0
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5624
0
    }
5625
5626
0
    wc_ecc_curve_free(curve);
5627
0
    FREE_CURVE_SPECS();
5628
5629
0
    return err;
5630
0
}
5631
5632
5633
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5634
        int curve_id, int flags)
5635
0
{
5636
0
    int err = 0;
5637
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5638
    !defined(WOLFSSL_ATECC608A)
5639
    const CRYS_ECPKI_Domain_t*  pDomain;
5640
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5641
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5642
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5643
    word32 raw_size = 0;
5644
#endif
5645
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5646
    defined(WC_ECC_NONBLOCK_ONLY)
5647
    ecc_nb_ctx_t nb_ctx;
5648
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5649
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5650
5651
0
    if (key == NULL || rng == NULL) {
5652
0
        return BAD_FUNC_ARG;
5653
0
    }
5654
5655
    /* make sure required variables are reset */
5656
0
    wc_ecc_reset(key);
5657
5658
    #if FIPS_VERSION3_GE(6,0,0)
5659
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5660
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5661
     * keysize here when relying on default selection */
5662
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5663
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5664
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5665
             curve_id == ECC_SECP521R1)) {
5666
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5667
            err = 0;
5668
        } else {
5669
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5670
            err = ECC_CURVE_OID_E;
5671
        }
5672
    }
5673
    if (err == 0) { /* FIPS specific check */
5674
    #endif
5675
0
    err = wc_ecc_set_curve(key, keysize, curve_id);
5676
0
    if (err != 0) {
5677
0
        return err;
5678
0
    }
5679
    #if FIPS_VERSION3_GE(6,0,0)
5680
    } /* end FIPS specific check */
5681
    #endif
5682
0
    key->flags = (byte)flags;
5683
5684
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5685
    #ifndef WOLF_CRYPTO_CB_FIND
5686
    if (key->devId != INVALID_DEVID)
5687
    #endif
5688
    {
5689
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5690
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5691
            return err;
5692
        /* fall-through when unavailable */
5693
    }
5694
#endif
5695
5696
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5697
    return NO_VALID_DEVID;
5698
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5699
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5700
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5701
    #ifdef HAVE_CAVIUM
5702
        /* TODO: Not implemented */
5703
    #elif defined(HAVE_INTEL_QA)
5704
        /* Implemented in ecc_make_pub_ex for the pub calc */
5705
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5706
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5707
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5708
            sw->eccMake.rng = rng;
5709
            sw->eccMake.key = key;
5710
            sw->eccMake.size = keysize;
5711
            sw->eccMake.curve_id = curve_id;
5712
            return WC_PENDING_E;
5713
        }
5714
    #endif
5715
    }
5716
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5717
5718
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5719
   if (key->dp->id == ECC_SECP256R1) {
5720
       key->type = ECC_PRIVATEKEY;
5721
       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5722
       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
5723
5724
       /* populate key->pubkey */
5725
       if (err == 0
5726
       #ifdef ALT_ECC_SIZE
5727
          && key->pubkey.x
5728
       #endif
5729
       ) {
5730
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5731
                                      ECC_MAX_CRYPTO_HW_SIZE);
5732
       }
5733
       if (err == 0
5734
       #ifdef ALT_ECC_SIZE
5735
          && key->pubkey.y
5736
       #endif
5737
       ) {
5738
           err = mp_read_unsigned_bin(key->pubkey.y,
5739
                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
5740
                                      ECC_MAX_CRYPTO_HW_SIZE);
5741
       }
5742
   }
5743
   else {
5744
      err = NOT_COMPILED_IN;
5745
   }
5746
#elif defined(WOLFSSL_SE050)
5747
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5748
    key->type = ECC_PRIVATEKEY;
5749
#elif defined(WOLFSSL_CRYPTOCELL)
5750
5751
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5752
    raw_size = (word32)(key->dp->size)*2 + 1;
5753
5754
    /* generate first key pair */
5755
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5756
                                wc_rndGenVectFunc,
5757
                                pDomain,
5758
                                &key->ctx.privKey,
5759
                                &key->ctx.pubKey,
5760
                                &tempBuff,
5761
                                &fipsCtx);
5762
5763
    if (err != SA_SILIB_RET_OK){
5764
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5765
        return err;
5766
    }
5767
    key->type = ECC_PRIVATEKEY;
5768
5769
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5770
                                   CRYS_EC_PointUncompressed,
5771
                                   &ucompressed_key[0],
5772
                                   (uint32_t*)&raw_size);
5773
5774
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5775
        err = mp_read_unsigned_bin(key->pubkey.x,
5776
                                   &ucompressed_key[1], key->dp->size);
5777
        if (err == MP_OKAY) {
5778
            err = mp_read_unsigned_bin(key->pubkey.y,
5779
                            &ucompressed_key[1+key->dp->size],key->dp->size);
5780
        }
5781
    }
5782
    raw_size = key->dp->size;
5783
    if (err == MP_OKAY) {
5784
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
5785
                                       ucompressed_key,
5786
                                       (uint32_t*)&raw_size);
5787
    }
5788
5789
    if (err == SA_SILIB_RET_OK) {
5790
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
5791
#ifdef WOLFSSL_ECC_BLIND_K
5792
        if (err == MP_OKAY) {
5793
            err = ecc_blind_k_rng(key, rng);
5794
        }
5795
#endif
5796
    }
5797
5798
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5799
    return silabs_ecc_make_key(key, keysize);
5800
#elif defined(WOLFSSL_KCAPI_ECC)
5801
5802
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
5803
    (void)rng;
5804
5805
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
5806
    if (xil_curve_type[key->dp->id] == 0)
5807
        return ECC_CURVE_OID_E;
5808
5809
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
5810
    if (err)
5811
        return err;
5812
    /* Make sure that private key is max. 521 bits */
5813
    if (key->dp->size == 66)
5814
        key->privKey[65] &= 0x1U;
5815
5816
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
5817
5818
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5819
                                        2 * key->dp->size);
5820
5821
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
5822
                                      xil_curve_type[key->dp->id],
5823
                                      XIL_CAST_U64(key->privKey),
5824
                                      XIL_CAST_U64(key->keyRaw));
5825
    if (err != XST_SUCCESS) {
5826
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
5827
        err = WC_HW_E;
5828
    }
5829
5830
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5831
                                        2 * key->dp->size);
5832
5833
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
5834
    if (err == 0)
5835
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
5836
                                          xil_curve_type[key->dp->id],
5837
                                          XIL_CAST_U64(key->keyRaw));
5838
#endif
5839
5840
    if (err == 0)
5841
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
5842
                             key->heap);
5843
    if (err == 0)
5844
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
5845
                             key->dp->size, key->heap);
5846
    if (err == 0)
5847
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
5848
                             key->heap);
5849
#ifdef WOLFSSL_ECC_BLIND_K
5850
    if (err == 0)
5851
        err = ecc_blind_k_rng(key, rng);
5852
#endif
5853
    if (err == 0)
5854
        err = mp_set(key->pubkey.z, 1);
5855
    if (err) {
5856
        key->privKey = NULL;
5857
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
5858
        return err;
5859
    }
5860
5861
    key->type = ECC_PRIVATEKEY;
5862
5863
#else
5864
5865
#ifdef WOLFSSL_HAVE_SP_ECC
5866
5867
#ifndef WOLFSSL_SP_NO_256
5868
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5869
    #ifndef WC_ECC_NONBLOCK
5870
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5871
    #else
5872
        if (key->nb_ctx) {
5873
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5874
                                         &key->pubkey, key->heap);
5875
        }
5876
        else {
5877
        #ifdef WC_ECC_NONBLOCK_ONLY
5878
            do { /* perform blocking call to non-blocking function */
5879
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
5880
                                             &key->pubkey, key->heap);
5881
            } while (err == FP_WOULDBLOCK);
5882
        #else
5883
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5884
        #endif /* WC_ECC_NONBLOCK_ONLY */
5885
        }
5886
    #endif /* !WC_ECC_NONBLOCK */
5887
5888
        if (err == MP_OKAY) {
5889
            key->type = ECC_PRIVATEKEY;
5890
        }
5891
    }
5892
    else
5893
#endif /* !WOLFSSL_SP_NO_256 */
5894
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5895
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5896
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
5897
        if (err == MP_OKAY) {
5898
            key->type = ECC_PRIVATEKEY;
5899
        }
5900
    }
5901
    else
5902
#endif
5903
#ifdef WOLFSSL_SP_384
5904
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5905
    #ifndef WC_ECC_NONBLOCK
5906
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5907
    #else
5908
        if (key->nb_ctx) {
5909
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5910
                                         &key->pubkey, key->heap);
5911
        }
5912
        else {
5913
        #ifdef WC_ECC_NONBLOCK_ONLY
5914
            do { /* perform blocking call to non-blocking function */
5915
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
5916
                                             &key->pubkey, key->heap);
5917
            } while (err == FP_WOULDBLOCK);
5918
        #else
5919
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5920
        #endif /* WC_ECC_NONBLOCK_ONLY */
5921
        }
5922
    #endif /* !WC_ECC_NONBLOCK */
5923
5924
        if (err == MP_OKAY) {
5925
            key->type = ECC_PRIVATEKEY;
5926
        }
5927
    }
5928
    else
5929
#endif /* WOLFSSL_SP_384 */
5930
#ifdef WOLFSSL_SP_521
5931
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5932
    #ifndef WC_ECC_NONBLOCK
5933
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5934
    #else
5935
        if (key->nb_ctx) {
5936
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5937
                                         &key->pubkey, key->heap);
5938
        }
5939
        else {
5940
        #ifdef WC_ECC_NONBLOCK_ONLY
5941
            do { /* perform blocking call to non-blocking function */
5942
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
5943
                                             &key->pubkey, key->heap);
5944
            } while (err == FP_WOULDBLOCK);
5945
        #else
5946
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5947
        #endif /* WC_ECC_NONBLOCK_ONLY */
5948
        }
5949
    #endif /* !WC_ECC_NONBLOCK */
5950
5951
        if (err == MP_OKAY) {
5952
            key->type = ECC_PRIVATEKEY;
5953
        }
5954
    }
5955
    else
5956
#endif /* WOLFSSL_SP_521 */
5957
#endif /* WOLFSSL_HAVE_SP_ECC */
5958
5959
0
   { /* software key gen */
5960
#if defined(WOLFSSL_SP_MATH)
5961
        err = WC_KEY_SIZE_E;
5962
#else
5963
0
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5964
5965
        /* setup the key variables */
5966
0
#ifndef ALT_ECC_SIZE
5967
0
        err = mp_init(key->k);
5968
#else
5969
        err = 0;
5970
        key->k = (mp_int*)key->ka;
5971
        alt_fp_init(key->k);
5972
#endif
5973
5974
        /* load curve info */
5975
0
        if (err == MP_OKAY) {
5976
0
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5977
0
            if (err != MP_OKAY) {
5978
0
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5979
0
            }
5980
0
        }
5981
5982
0
        if (err == MP_OKAY) {
5983
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5984
0
            if (err != MP_OKAY) {
5985
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5986
0
            }
5987
0
        }
5988
5989
        /* generate k */
5990
0
        if (err == MP_OKAY) {
5991
0
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5992
0
            if (err != MP_OKAY) {
5993
0
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5994
0
            }
5995
0
        }
5996
5997
        /* generate public key from k */
5998
0
        if (err == MP_OKAY) {
5999
0
            err = ecc_make_pub_ex(key, curve, NULL, rng);
6000
0
            if (err != MP_OKAY) {
6001
0
                WOLFSSL_MSG("ecc_make_pub_ex failed");
6002
0
            }
6003
0
        }
6004
6005
0
        if (err == MP_OKAY
6006
        #ifdef WOLFSSL_ASYNC_CRYPT
6007
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
6008
        #endif
6009
0
        ) {
6010
0
            key->type = ECC_PRIVATEKEY;
6011
0
        }
6012
0
        else {
6013
            /* cleanup these on failure case only */
6014
0
            mp_forcezero(key->k);
6015
0
        }
6016
6017
        /* cleanup allocations */
6018
0
        wc_ecc_curve_free(curve);
6019
0
        FREE_CURVE_SPECS();
6020
0
#endif /* WOLFSSL_SP_MATH */
6021
0
    }
6022
6023
#ifdef HAVE_WOLF_BIGINT
6024
    if (err == MP_OKAY)
6025
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6026
    if (err == MP_OKAY)
6027
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6028
    if (err == MP_OKAY)
6029
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6030
    if (err == MP_OKAY)
6031
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6032
#endif
6033
6034
#ifdef WOLFSSL_ECC_BLIND_K
6035
    if (err == MP_OKAY)
6036
        err = ecc_blind_k_rng(key, rng);
6037
#endif
6038
6039
0
#endif /* HAVE_ECC_MAKE_PUB */
6040
6041
0
    return err;
6042
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6043
0
}
6044
6045
6046
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6047
                        int flags)
6048
0
{
6049
0
    int err;
6050
6051
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6052
6053
0
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6054
6055
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6056
    !defined(WOLFSSL_KCAPI_ECC)
6057
    if (err == MP_OKAY) {
6058
        err = _ecc_validate_public_key(key, 0, 0);
6059
    }
6060
    if (err == MP_OKAY
6061
#if defined(WOLF_CRYPTO_CB)
6062
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6063
        && key->devId == INVALID_DEVID
6064
#endif
6065
        ) {
6066
        err = _ecc_pairwise_consistency_test(key, rng);
6067
    }
6068
#endif
6069
6070
0
    RESTORE_VECTOR_REGISTERS();
6071
6072
0
    return err;
6073
0
}
6074
6075
WOLFSSL_ABI
6076
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6077
0
{
6078
0
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6079
0
}
6080
6081
#ifdef ECC_DUMP_OID
6082
/* Optional dump of encoded OID for adding new curves */
6083
static int mOidDumpDone;
6084
static void wc_ecc_dump_oids(void)
6085
{
6086
    int x;
6087
6088
    if (mOidDumpDone) {
6089
        return;
6090
    }
6091
6092
    /* find matching OID sum (based on encoded value) */
6093
    for (x = 0; ecc_sets[x].size != 0; x++) {
6094
        int i;
6095
        byte* oid;
6096
        word32 oidSz, sum = 0;
6097
6098
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6099
6100
    #ifdef HAVE_OID_ENCODING
6101
        byte oidEnc[ECC_MAX_OID_LEN];
6102
6103
        oid = oidEnc;
6104
        oidSz = ECC_MAX_OID_LEN;
6105
6106
        printf("OID: ");
6107
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6108
            printf("%d.", ecc_sets[x].oid[i]);
6109
        }
6110
        printf("\n");
6111
6112
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6113
    #else
6114
        oid = (byte*)ecc_sets[x].oid;
6115
        oidSz = ecc_sets[x].oidSz;
6116
    #endif
6117
6118
        printf("OID Encoded: ");
6119
        for (i = 0; i < (int)oidSz; i++) {
6120
            printf("0x%02X,", oid[i]);
6121
        }
6122
        printf("\n");
6123
6124
        for (i = 0; i < (int)oidSz; i++) {
6125
            sum += oid[i];
6126
        }
6127
        printf("Sum: %u\n", sum);
6128
6129
        /* validate sum */
6130
        if (ecc_sets[x].oidSum != sum) {
6131
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6132
        }
6133
    }
6134
    mOidDumpDone = 1;
6135
}
6136
#endif /* ECC_DUMP_OID */
6137
6138
6139
WOLFSSL_ABI
6140
ecc_key* wc_ecc_key_new(void* heap)
6141
0
{
6142
0
    int devId = INVALID_DEVID;
6143
0
    ecc_key* key;
6144
6145
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6146
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6147
    devId = WOLFSSL_CAAM_DEVID;
6148
#endif
6149
0
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6150
0
    if (key) {
6151
0
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6152
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6153
0
            key = NULL;
6154
0
        }
6155
0
    }
6156
6157
0
    return key;
6158
0
}
6159
6160
6161
WOLFSSL_ABI
6162
void wc_ecc_key_free(ecc_key* key)
6163
0
{
6164
0
    if (key) {
6165
0
        void* heap = key->heap;
6166
6167
0
        wc_ecc_free(key);
6168
0
        ForceZero(key, sizeof(ecc_key));
6169
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6170
0
        (void)heap;
6171
0
    }
6172
0
}
6173
6174
6175
/**
6176
 Make a new ECC key
6177
 rng          An active RNG state
6178
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6179
 key          [out] Destination of the newly created key
6180
 return       MP_OKAY if successful,
6181
 upon error all allocated memory will be freed
6182
 */
6183
WOLFSSL_ABI
6184
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6185
0
{
6186
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6187
0
}
6188
6189
/* Setup dynamic pointers if using normal math for proper freeing */
6190
WOLFSSL_ABI
6191
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6192
0
{
6193
0
    int ret      = 0;
6194
6195
0
    if (key == NULL) {
6196
0
        return BAD_FUNC_ARG;
6197
0
    }
6198
6199
#ifdef ECC_DUMP_OID
6200
    wc_ecc_dump_oids();
6201
#endif
6202
6203
0
    XMEMSET(key, 0, sizeof(ecc_key));
6204
0
    key->state = ECC_STATE_NONE;
6205
6206
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6207
    key->devId = devId;
6208
#else
6209
0
    (void)devId;
6210
0
#endif
6211
6212
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6213
    key->slot = ATECC_INVALID_SLOT;
6214
#elif defined(WOLFSSL_KCAPI_ECC)
6215
    key->handle = NULL;
6216
#else
6217
#ifdef ALT_ECC_SIZE
6218
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6219
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6220
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6221
    alt_fp_init(key->pubkey.x);
6222
    alt_fp_init(key->pubkey.y);
6223
    alt_fp_init(key->pubkey.z);
6224
    key->k = (mp_int*)key->ka;
6225
    alt_fp_init(key->k);
6226
#ifdef WOLFSSL_ECC_BLIND_K
6227
    key->kb = (mp_int*)key->kba;
6228
    key->ku = (mp_int*)key->kia;
6229
    alt_fp_init(key->kb);
6230
    alt_fp_init(key->ku);
6231
#endif
6232
#else
6233
0
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6234
0
#ifndef WOLFSSL_ECC_BLIND_K
6235
0
                                                                      NULL, NULL
6236
#else
6237
                                                                key->kb, key->ku
6238
#endif
6239
0
                        );
6240
0
    if (ret != MP_OKAY) {
6241
0
        return MEMORY_E;
6242
0
    }
6243
0
#endif /* ALT_ECC_SIZE */
6244
#ifdef WOLFSSL_ECC_BLIND_K
6245
    mp_forcezero(key->kb);
6246
#endif
6247
0
#endif /* WOLFSSL_ATECC508A */
6248
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6249
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6250
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6251
     defined(WOLFSSL_NO_MALLOC)
6252
    ret = mp_init(key->sign_k);
6253
    if (ret != MP_OKAY) {
6254
        return MEMORY_E;
6255
    }
6256
#endif
6257
6258
#ifdef WOLFSSL_HEAP_TEST
6259
    (void)heap;
6260
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6261
#else
6262
0
    key->heap = heap;
6263
0
#endif
6264
6265
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6266
    #ifdef WOLF_CRYPTO_CB
6267
    /* prefer crypto callback */
6268
    if (key->devId != INVALID_DEVID)
6269
    #endif
6270
    {
6271
        /* handle as async */
6272
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6273
                                                        key->heap, devId);
6274
    }
6275
    if (ret != 0)
6276
        return ret;
6277
#endif
6278
6279
#if defined(WOLFSSL_DSP)
6280
    key->handle = -1;
6281
#endif
6282
6283
#ifdef WOLFSSL_SE050
6284
    key->keyId = 0;
6285
    key->keyIdSet = 0;
6286
#endif
6287
6288
#ifdef WOLFSSL_CHECK_MEM_ZERO
6289
    mp_memzero_add("ECC k", key->k);
6290
#ifdef WOLFSSL_ECC_BLIND_K
6291
    mp_memzero_add("ECC kb", key->kb);
6292
    mp_memzero_add("ECC ku", key->ku);
6293
#endif
6294
#endif
6295
6296
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6297
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6298
6299
    if (wc_InitXsecure(&(key->xSec))) {
6300
        WOLFSSL_MSG("Can't initialize Xsecure");
6301
        return WC_HW_E;
6302
    }
6303
#endif
6304
6305
0
    return ret;
6306
0
}
6307
6308
WOLFSSL_ABI
6309
int wc_ecc_init(ecc_key* key)
6310
0
{
6311
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6312
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6313
#else
6314
0
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6315
0
#endif
6316
0
}
6317
6318
#ifdef WOLF_PRIVATE_KEY_ID
6319
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6320
                   int devId)
6321
{
6322
    int ret = 0;
6323
#ifdef WOLFSSL_SE050
6324
    /* SE050 TLS users store a word32 at id, need to cast back */
6325
    word32* keyPtr = NULL;
6326
#endif
6327
6328
    if (key == NULL)
6329
        ret = BAD_FUNC_ARG;
6330
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6331
        ret = BUFFER_E;
6332
    if (ret == 0)
6333
        ret = wc_ecc_init_ex(key, heap, devId);
6334
    if (ret == 0 && id != NULL && len != 0) {
6335
        XMEMCPY(key->id, id, (size_t)len);
6336
        key->idLen = len;
6337
    #ifdef WOLFSSL_SE050
6338
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6339
        if (len == (int)sizeof(word32)) {
6340
            keyPtr = (word32*)key->id;
6341
            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
6342
        }
6343
    #endif
6344
    }
6345
6346
    return ret;
6347
}
6348
6349
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6350
{
6351
    int ret = 0;
6352
    int labelLen = 0;
6353
6354
    if (key == NULL || label == NULL)
6355
        ret = BAD_FUNC_ARG;
6356
    if (ret == 0) {
6357
        labelLen = (int)XSTRLEN(label);
6358
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6359
            ret = BUFFER_E;
6360
    }
6361
    if (ret == 0)
6362
        ret = wc_ecc_init_ex(key, heap, devId);
6363
    if (ret == 0) {
6364
        XMEMCPY(key->label, label, (size_t)labelLen);
6365
        key->labelLen = labelLen;
6366
    }
6367
6368
    return ret;
6369
}
6370
#endif /* WOLF_PRIVATE_KEY_ID */
6371
6372
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6373
0
{
6374
0
    if (key == NULL) {
6375
0
        return BAD_FUNC_ARG;
6376
0
    }
6377
0
    key->flags |= flags;
6378
0
    return 0;
6379
0
}
6380
6381
6382
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6383
0
{
6384
0
    int err = MP_OKAY;
6385
0
    int orderBits;
6386
0
    DECLARE_CURVE_SPECS(1);
6387
6388
0
    ALLOC_CURVE_SPECS(1, err);
6389
0
    if (err == MP_OKAY) {
6390
0
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6391
0
    }
6392
6393
0
    if (err != 0) {
6394
0
       FREE_CURVE_SPECS();
6395
0
       return err;
6396
0
    }
6397
0
    orderBits = mp_count_bits(curve->order);
6398
6399
0
    wc_ecc_curve_free(curve);
6400
0
    FREE_CURVE_SPECS();
6401
0
    return orderBits;
6402
0
}
6403
6404
#ifdef HAVE_ECC_SIGN
6405
6406
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6407
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6408
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6409
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6410
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6411
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6412
    ecc_key* key)
6413
{
6414
    int err;
6415
#ifdef PLUTON_CRYPTO_ECC
6416
    if (key->devId != INVALID_DEVID) /* use hardware */
6417
#endif
6418
    {
6419
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6420
        !defined(WOLFSSL_ATECC608A)
6421
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6422
        word32 raw_sig_size = *outlen;
6423
        word32 msgLenInBytes = inlen;
6424
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6425
    #endif
6426
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6427
#ifdef WOLFSSL_SMALL_STACK
6428
        byte* K = NULL;
6429
        byte* incopy = NULL;
6430
#else
6431
        byte K[MAX_ECC_BYTES] = {0};
6432
        byte incopy[MAX_ECC_BYTES] = {0};
6433
#endif
6434
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6435
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6436
        word32 Ksize;
6437
#endif
6438
#endif
6439
        word32 keysize = (word32)key->dp->size;
6440
    #ifdef PLUTON_CRYPTO_ECC
6441
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6442
    #endif
6443
6444
    #ifndef WOLFSSL_KCAPI_ECC
6445
        /* Check args */
6446
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6447
            return ECC_BAD_ARG_E;
6448
        }
6449
    #endif
6450
6451
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6452
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6453
        err = atmel_ecc_sign(key->slot, in, out);
6454
        if (err != 0) {
6455
           return err;
6456
        }
6457
    #elif defined(PLUTON_CRYPTO_ECC)
6458
        {
6459
            /* if the input is larger than curve order, we must truncate */
6460
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6461
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6462
            }
6463
6464
            /* perform ECC sign */
6465
            word32 raw_sig_size = *outlen;
6466
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6467
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6468
               return BAD_COND_E;
6469
            }
6470
        }
6471
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6472
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6473
        if (err != 0) {
6474
               return WC_HW_E;
6475
        }
6476
    #elif defined(WOLFSSL_CRYPTOCELL)
6477
        /* truncate if hash is longer than key size */
6478
        if (msgLenInBytes > keysize) {
6479
            msgLenInBytes = keysize;
6480
        }
6481
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6482
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6483
            (void)cc310_hashModeECC(keysize);
6484
            /* Ignoring returned value */
6485
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6486
6487
        }
6488
6489
        /* create signature from an input buffer using a private key*/
6490
        err = CRYS_ECDSA_Sign(&wc_rndState,
6491
                               wc_rndGenVectFunc,
6492
                               &sigCtxTemp,
6493
                               &key->ctx.privKey,
6494
                               hash_mode,
6495
                               (byte*)in,
6496
                               msgLenInBytes,
6497
                               out,
6498
                               (uint32_t*)&raw_sig_size);
6499
6500
        if (err != SA_SILIB_RET_OK){
6501
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6502
            return err;
6503
        }
6504
    #elif defined(WOLFSSL_KCAPI_ECC)
6505
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6506
        if (err != MP_OKAY) {
6507
            return err;
6508
        }
6509
        (void)rng;
6510
    #elif defined(WOLFSSL_SE050)
6511
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6512
        if (err != MP_OKAY) {
6513
            return err;
6514
        }
6515
        (void)rng;
6516
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6517
6518
#ifdef WOLFSSL_SMALL_STACK
6519
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6520
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6521
        if (K == NULL || incopy == NULL) {
6522
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6523
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6524
            return MEMORY_E;
6525
        }
6526
#else
6527
        if (inlen > sizeof(incopy))
6528
            return ECC_BAD_ARG_E;
6529
#endif
6530
6531
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6532
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6533
        err = deterministic_sign_helper(in, inlen, key);
6534
        if (err)
6535
            return err;
6536
        Ksize = mp_unsigned_bin_size(key->sign_k);
6537
        if (Ksize > keysize) {
6538
            err = BUFFER_E;
6539
            goto error_out;
6540
        }
6541
        err = mp_to_unsigned_bin(key->sign_k, K);
6542
        if (err)
6543
            goto error_out;
6544
        mp_reverse(K, Ksize);
6545
#else
6546
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6547
        if (err)
6548
            goto error_out;
6549
        /* Make sure that K is max. 521 bits */
6550
        if (keysize == 66)
6551
            K[65] &= 0x1;
6552
#endif
6553
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6554
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6555
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6556
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6557
6558
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6559
6560
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6561
                                           xil_curve_type[key->dp->id],
6562
                                           XIL_CAST_U64(incopy), keysize,
6563
                                           XIL_CAST_U64(key->privKey),
6564
                                           XIL_CAST_U64(K),
6565
                                           XIL_CAST_U64(out));
6566
        if (err) {
6567
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6568
            err = WC_HW_E;
6569
        }
6570
6571
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6572
        mp_reverse(&out[0], keysize);
6573
        mp_reverse(&out[keysize], keysize);
6574
6575
error_out:
6576
        ForceZero(K, MAX_ECC_BYTES);
6577
#ifdef WOLFSSL_SMALL_STACK
6578
        XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6579
        XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6580
#endif
6581
        if (err) {
6582
            ForceZero(out, keysize * 2);
6583
            return err;
6584
        }
6585
    #endif /* HW-specific #if-#elif chain */
6586
6587
    #ifndef WOLFSSL_SE050
6588
        /* Load R and S, SE050 does this in port layer */
6589
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6590
        if (err != MP_OKAY) {
6591
            return err;
6592
        }
6593
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6594
        if (err != MP_OKAY) {
6595
            return err;
6596
        }
6597
    #endif
6598
6599
        /* Check for zeros */
6600
        if (mp_iszero(r) || mp_iszero(s)) {
6601
            return MP_ZERO_E;
6602
        }
6603
    }
6604
#ifdef PLUTON_CRYPTO_ECC
6605
    else {
6606
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6607
    }
6608
#endif
6609
    (void)rng;
6610
6611
    return err;
6612
}
6613
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6614
6615
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6616
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6617
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6618
{
6619
    int err;
6620
    mp_int *r = NULL, *s = NULL;
6621
6622
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6623
                                                                rng == NULL) {
6624
        return ECC_BAD_ARG_E;
6625
    }
6626
6627
    err = wc_ecc_alloc_async(key);
6628
    if (err != 0) {
6629
        return err;
6630
    }
6631
    r = key->r;
6632
    s = key->s;
6633
6634
    switch (key->state) {
6635
        case ECC_STATE_NONE:
6636
        case ECC_STATE_SIGN_DO:
6637
            key->state = ECC_STATE_SIGN_DO;
6638
6639
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6640
                break;
6641
            }
6642
6643
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6644
            if (err < 0) {
6645
                break;
6646
            }
6647
6648
            FALL_THROUGH;
6649
6650
        case ECC_STATE_SIGN_ENCODE:
6651
            key->state = ECC_STATE_SIGN_ENCODE;
6652
6653
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6654
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6655
                    DECLARE_CURVE_SPECS(1);
6656
                    ALLOC_CURVE_SPECS(1, err);
6657
                    if (err != MP_OKAY) {
6658
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6659
                        break;
6660
                    }
6661
6662
                    /* get curve order */
6663
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6664
                #endif
6665
6666
                #ifdef HAVE_CAVIUM_V
6667
                    /* Nitrox requires r and s in sep buffer, so split it */
6668
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6669
                #endif
6670
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6671
                    /* only do this if not software, since it overwrites result */
6672
                    wc_bigint_to_mp(&r->raw, r);
6673
                    wc_bigint_to_mp(&s->raw, s);
6674
6675
                /* if using a curve with cofactor != 1 then reduce by mod order */
6676
                #ifdef HAVE_ECC_CDH
6677
                    /* if r is not less than order than reduce */
6678
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6679
                        err = mp_mod(r, curve->order, r);
6680
                    }
6681
                    wc_ecc_curve_free(curve);
6682
                    FREE_CURVE_SPECS();
6683
                #endif
6684
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6685
            }
6686
6687
            /* encoded with DSA header */
6688
            if (err == 0) {
6689
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6690
            }
6691
6692
            /* done with R/S */
6693
            mp_clear(r);
6694
            mp_clear(s);
6695
            break;
6696
6697
        default:
6698
            err = BAD_STATE_E;
6699
            break;
6700
    }
6701
6702
    /* if async pending then return and skip done cleanup below */
6703
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6704
        key->state++;
6705
        return err;
6706
    }
6707
6708
    /* cleanup */
6709
    wc_ecc_free_async(key);
6710
    key->state = ECC_STATE_NONE;
6711
6712
    return err;
6713
}
6714
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6715
6716
/**
6717
 Sign a message digest
6718
 in        The message digest to sign
6719
 inlen     The length of the digest
6720
 out       [out] The destination for the signature
6721
 outlen    [in/out] The max size and resulting size of the signature
6722
 key       A private ECC key
6723
 return    MP_OKAY if successful
6724
 */
6725
WOLFSSL_ABI
6726
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6727
                     WC_RNG* rng, ecc_key* key)
6728
0
{
6729
0
    int err;
6730
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6731
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6732
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6733
0
#endif
6734
#ifdef NO_ASN
6735
    word32 keySz;
6736
#endif
6737
6738
0
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6739
0
        return ECC_BAD_ARG_E;
6740
0
    }
6741
6742
#ifdef WOLF_CRYPTO_CB
6743
    #ifndef WOLF_CRYPTO_CB_FIND
6744
    if (key->devId != INVALID_DEVID)
6745
    #endif
6746
    {
6747
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
6748
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6749
            return err;
6750
        /* fall-through when unavailable */
6751
    }
6752
#endif
6753
6754
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6755
    (void)rng;
6756
    (void)inlen;
6757
    (void)s;
6758
    (void)r;
6759
    (void)err;
6760
    return NO_VALID_DEVID;
6761
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6762
0
    if (rng == NULL) {
6763
0
        WOLFSSL_MSG("ECC sign RNG missing");
6764
0
        return ECC_BAD_ARG_E;
6765
0
    }
6766
6767
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6768
    /* handle async cases */
6769
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
6770
#else
6771
6772
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6773
    #ifdef MP_INT_SIZE_CHECK_NULL
6774
    if (r == NULL)
6775
        return MEMORY_E;
6776
    #endif
6777
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6778
    #ifdef MP_INT_SIZE_CHECK_NULL
6779
    if (s == NULL) {
6780
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6781
        return MEMORY_E;
6782
    }
6783
    #endif
6784
6785
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6786
0
    if (err != 0) {
6787
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6788
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6789
0
        return err;
6790
0
    }
6791
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6792
0
    if (err != 0) {
6793
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6794
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6795
0
        return err;
6796
0
    }
6797
6798
/* hardware crypto */
6799
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6800
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6801
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6802
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6803
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
6804
#else
6805
0
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6806
0
#endif
6807
0
    if (err < 0) {
6808
0
        mp_clear(r);
6809
0
        mp_clear(s);
6810
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6811
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6812
0
        return err;
6813
0
    }
6814
6815
0
#ifndef NO_ASN
6816
    /* encoded with DSA header */
6817
0
    err = StoreECC_DSA_Sig(out, outlen, r, s);
6818
#else
6819
    /* No support for DSA ASN.1 header.
6820
     * Signature will be r+s directly. */
6821
    keySz = 0;
6822
    if (key->dp != NULL) {
6823
        keySz = (word32)key->dp->size;
6824
    }
6825
    if (keySz <= 0) {
6826
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
6827
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
6828
    }
6829
    *outlen = keySz * 2;
6830
6831
    /* Export signature into r,s */
6832
    mp_to_unsigned_bin_len(r, out, keySz);
6833
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
6834
#endif /* !NO_ASN */
6835
6836
    /* cleanup */
6837
0
    mp_clear(r);
6838
0
    mp_clear(s);
6839
6840
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6841
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6842
0
#endif /* WOLFSSL_ASYNC_CRYPT */
6843
0
    return err;
6844
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6845
0
}
6846
6847
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6848
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6849
/* returns MP_OKAY on success */
6850
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
6851
{
6852
    int err = MP_OKAY;
6853
    DECLARE_CURVE_SPECS(1);
6854
    ALLOC_CURVE_SPECS(1, err);
6855
6856
    /* get curve order */
6857
    if (err == MP_OKAY) {
6858
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6859
    }
6860
6861
    if (err == MP_OKAY) {
6862
    #ifndef WOLFSSL_NO_MALLOC
6863
        /* if key->sign_k is NULL then create a buffer for the mp_int
6864
         * if not NULL then assume the user correctly set deterministic flag and
6865
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
6866
        if (key->sign_k == NULL) {
6867
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6868
                                                            DYNAMIC_TYPE_ECC);
6869
            if (key->sign_k != NULL) {
6870
                err = mp_init(key->sign_k);
6871
                if (err != MP_OKAY) {
6872
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6873
                    key->sign_k = NULL;
6874
                }
6875
            }
6876
        }
6877
        if (key->sign_k != NULL) {
6878
            if (wc_ecc_gen_deterministic_k(in, inlen,
6879
                        key->hashType, ecc_get_k(key), key->sign_k,
6880
                        curve->order, key->heap) != 0) {
6881
                mp_free(key->sign_k);
6882
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6883
                key->sign_k = NULL;
6884
                err = ECC_PRIV_KEY_E;
6885
            }
6886
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6887
            else {
6888
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
6889
            }
6890
        #endif
6891
        }
6892
        else {
6893
            err = MEMORY_E;
6894
        }
6895
    #else
6896
        key->sign_k_set = 0;
6897
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
6898
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
6899
            err = ECC_PRIV_KEY_E;
6900
        }
6901
        else {
6902
            key->sign_k_set = 1;
6903
        }
6904
    #endif
6905
    }
6906
6907
    wc_ecc_curve_free(curve);
6908
    FREE_CURVE_SPECS();
6909
    return err;
6910
}
6911
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
6912
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
6913
6914
#if defined(WOLFSSL_STM32_PKA)
6915
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6916
                     ecc_key* key, mp_int *r, mp_int *s)
6917
{
6918
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6919
}
6920
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6921
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
6922
#ifndef WOLFSSL_SP_MATH
6923
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
6924
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
6925
                            mp_int* s)
6926
0
{
6927
0
    int err = MP_OKAY;
6928
0
    int loop_check = 0;
6929
0
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6930
6931
0
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6932
#ifdef MP_INT_SIZE_CHECK_NULL
6933
    if (b == NULL)
6934
        err = MEMORY_E;
6935
#endif
6936
6937
0
    if (err == MP_OKAY) {
6938
0
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6939
0
    }
6940
6941
#ifdef WOLFSSL_CUSTOM_CURVES
6942
    /* if custom curve, apply params to pubkey */
6943
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6944
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6945
    }
6946
#endif
6947
6948
0
    if (err == MP_OKAY) {
6949
        /* Generate blinding value - non-zero value. */
6950
0
        do {
6951
0
            if (++loop_check > 64) {
6952
0
                 err = RNG_FAILURE_E;
6953
0
                 break;
6954
0
            }
6955
6956
0
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6957
0
        }
6958
0
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6959
0
        loop_check = 0;
6960
0
    }
6961
#ifdef WOLFSSL_CHECK_MEM_ZERO
6962
    if (err == MP_OKAY) {
6963
        mp_memzero_add("ecc_sign_hash_sw b", b);
6964
    }
6965
#endif
6966
6967
0
    for (; err == MP_OKAY;) {
6968
0
        if (++loop_check > 64) {
6969
0
             err = RNG_FAILURE_E;
6970
0
             break;
6971
0
        }
6972
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6973
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6974
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6975
#ifndef WOLFSSL_NO_MALLOC
6976
        if (key->sign_k != NULL)
6977
#else
6978
        if (key->sign_k_set)
6979
#endif
6980
        {
6981
            if (loop_check > 1) {
6982
               err = RNG_FAILURE_E;
6983
               break;
6984
            }
6985
6986
            /* use provided sign_k */
6987
            err = mp_copy(key->sign_k, pubkey->k);
6988
            if (err != MP_OKAY) break;
6989
6990
            /* free sign_k, so only used once */
6991
            mp_forcezero(key->sign_k);
6992
#ifndef WOLFSSL_NO_MALLOC
6993
            mp_free(key->sign_k);
6994
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6995
            key->sign_k = NULL;
6996
#else
6997
            key->sign_k_set = 0;
6998
#endif
6999
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
7000
            loop_check = 64;
7001
    #endif
7002
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7003
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7004
            if (key->deterministic == 1) {
7005
                /* sign_k generated earlier in function for SP calls.
7006
                 * Only go through the loop once and fail if error */
7007
                loop_check = 64;
7008
            }
7009
    #endif
7010
7011
            /* compute public key based on provided "k" */
7012
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
7013
        }
7014
        else
7015
#endif
7016
0
        {
7017
0
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
7018
0
                    WC_ECC_FLAG_NONE);
7019
0
        }
7020
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7021
        if (err == MP_OKAY) {
7022
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7023
        }
7024
    #endif
7025
    #ifdef WOLFSSL_ASYNC_CRYPT
7026
        /* for async do blocking wait here */
7027
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7028
    #endif
7029
0
        if (err != MP_OKAY) break;
7030
7031
        /* find r = x1 mod n */
7032
0
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7033
0
        if (err != MP_OKAY) break;
7034
7035
0
        if (mp_iszero(r) == MP_NO) {
7036
0
            mp_int* kp = ecc_get_k(pubkey);
7037
0
            mp_int* ep = kp;
7038
0
            mp_int* x  = ecc_get_k(key);
7039
7040
            /* Blind after getting. */
7041
0
            ecc_blind_k(key, b);
7042
7043
            /* find s = (e + xr)/k
7044
                      = b.(e/k.b + x.r/k.b) */
7045
7046
            /* k' = k.b */
7047
0
            err = mp_mulmod(kp, b, curve->order, kp);
7048
0
            if (err != MP_OKAY) break;
7049
7050
            /* k' = 1/k.b
7051
                  = 1/k' */
7052
0
            err = mp_invmod(kp, curve->order, kp);
7053
0
            if (err != MP_OKAY) break;
7054
7055
            /* s = x.r */
7056
0
            err = mp_mulmod(x, r, curve->order, s);
7057
0
            if (err != MP_OKAY) break;
7058
7059
            /* s = x.r/k.b
7060
                 = k'.s */
7061
0
            err = mp_mulmod(kp, s, curve->order, s);
7062
0
            if (err != MP_OKAY) break;
7063
7064
            /* e' = e/k.b
7065
                  = e.k' */
7066
0
            err = mp_mulmod(kp, e, curve->order, ep);
7067
0
            if (err != MP_OKAY) break;
7068
7069
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7070
                 = e' + s */
7071
0
            err = mp_addmod_ct(ep, s, curve->order, s);
7072
0
            if (err != MP_OKAY) break;
7073
7074
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7075
                 = b.s */
7076
0
            err = mp_mulmod(s, b, curve->order, s);
7077
0
            if (err != MP_OKAY) break;
7078
7079
0
            if (mp_iszero(s) == MP_NO) {
7080
                /* sign successful */
7081
0
                break;
7082
0
            }
7083
0
         }
7084
0
     #ifndef ALT_ECC_SIZE
7085
0
         mp_clear(pubkey->pubkey.x);
7086
0
         mp_clear(pubkey->pubkey.y);
7087
0
         mp_clear(pubkey->pubkey.z);
7088
0
     #endif
7089
0
         mp_forcezero(pubkey->k);
7090
0
    }
7091
0
    mp_forcezero(b);
7092
0
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7093
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7094
    mp_memzero_check(b);
7095
#endif
7096
7097
0
    return err;
7098
0
}
7099
#endif
7100
7101
#ifdef WOLFSSL_HAVE_SP_ECC
7102
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7103
    ecc_key* key, mp_int *r, mp_int *s)
7104
{
7105
    if (key->idx != ECC_CUSTOM_IDX) {
7106
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7107
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7108
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7109
        mp_int* sign_k = key->sign_k;
7110
    #else
7111
        mp_int* sign_k = NULL;
7112
    #endif
7113
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7114
        /* perform blocking call to non-blocking function */
7115
        ecc_nb_ctx_t nb_ctx;
7116
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7117
    #endif
7118
    #ifndef WOLFSSL_SP_NO_256
7119
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7120
        #ifdef WC_ECC_NONBLOCK
7121
            #ifdef WC_ECC_NONBLOCK_ONLY
7122
            int err;
7123
            #endif
7124
            if (key->nb_ctx) {
7125
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7126
                    ecc_get_k(key), r, s, sign_k, key->heap);
7127
            }
7128
            #ifdef WC_ECC_NONBLOCK_ONLY
7129
            do { /* perform blocking call to non-blocking function */
7130
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7131
                    ecc_get_k(key), r, s, sign_k, key->heap);
7132
            } while (err == FP_WOULDBLOCK);
7133
            return err;
7134
            #endif
7135
        #endif /* WC_ECC_NONBLOCK */
7136
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7137
            {
7138
                int ret;
7139
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7140
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7141
                                      sign_k, key->heap);
7142
                RESTORE_VECTOR_REGISTERS();
7143
                return ret;
7144
            }
7145
        #endif
7146
        }
7147
    #endif
7148
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7149
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7150
            int ret;
7151
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
7152
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7153
                                      sign_k, key->heap);
7154
            RESTORE_VECTOR_REGISTERS();
7155
            return ret;
7156
        }
7157
    #endif
7158
    #ifdef WOLFSSL_SP_384
7159
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7160
        #ifdef WC_ECC_NONBLOCK
7161
            #ifdef WC_ECC_NONBLOCK_ONLY
7162
            int err;
7163
            #endif
7164
            if (key->nb_ctx) {
7165
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7166
                    ecc_get_k(key), r, s, sign_k, key->heap);
7167
            }
7168
            #ifdef WC_ECC_NONBLOCK_ONLY
7169
            do { /* perform blocking call to non-blocking function */
7170
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7171
                    ecc_get_k(key), r, s, sign_k, key->heap);
7172
            } while (err == FP_WOULDBLOCK);
7173
            return err;
7174
            #endif
7175
        #endif /* WC_ECC_NONBLOCK */
7176
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7177
            {
7178
                int ret;
7179
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7180
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7181
                                      sign_k, key->heap);
7182
                RESTORE_VECTOR_REGISTERS();
7183
                return ret;
7184
            }
7185
        #endif
7186
        }
7187
    #endif
7188
    #ifdef WOLFSSL_SP_521
7189
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7190
        #ifdef WC_ECC_NONBLOCK
7191
            #ifdef WC_ECC_NONBLOCK_ONLY
7192
            int err;
7193
            #endif
7194
            if (key->nb_ctx) {
7195
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7196
                    ecc_get_k(key), r, s, sign_k, key->heap);
7197
            }
7198
            #ifdef WC_ECC_NONBLOCK_ONLY
7199
            do { /* perform blocking call to non-blocking function */
7200
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7201
                    ecc_get_k(key), r, s, sign_k, key->heap);
7202
            } while (err == FP_WOULDBLOCK);
7203
            return err;
7204
            #endif
7205
        #endif /* WC_ECC_NONBLOCK */
7206
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7207
            {
7208
                int ret;
7209
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7210
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7211
                                      sign_k, key->heap);
7212
                RESTORE_VECTOR_REGISTERS();
7213
                return ret;
7214
            }
7215
        #endif
7216
        }
7217
    #endif
7218
        (void)sign_k;
7219
    }
7220
7221
    /* SP doesn't support curve. */
7222
    return WC_KEY_SIZE_E;
7223
}
7224
#endif
7225
7226
/**
7227
  Sign a message digest
7228
  in        The message digest to sign
7229
  inlen     The length of the digest
7230
  key       A private ECC key
7231
  r         [out] The destination for r component of the signature
7232
  s         [out] The destination for s component of the signature
7233
  return    MP_OKAY if successful
7234
*/
7235
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7236
                     ecc_key* key, mp_int *r, mp_int *s)
7237
0
{
7238
0
   int    err = 0;
7239
0
#if !defined(WOLFSSL_SP_MATH)
7240
0
   mp_int* e;
7241
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7242
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7243
0
#endif
7244
7245
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7246
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7247
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7248
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7249
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7250
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7251
#else
7252
0
   DECLARE_CURVE_SPECS(1);
7253
0
#endif
7254
0
#endif /* !WOLFSSL_SP_MATH */
7255
7256
0
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7257
0
       return ECC_BAD_ARG_E;
7258
0
   }
7259
7260
   /* is this a private key? */
7261
0
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7262
0
      return ECC_BAD_ARG_E;
7263
0
   }
7264
7265
   /* is the IDX valid ?  */
7266
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7267
0
      return ECC_BAD_ARG_E;
7268
0
   }
7269
7270
#if defined(WOLFSSL_SP_MATH)
7271
    if (key->idx == ECC_CUSTOM_IDX || (1
7272
    #ifndef WOLFSSL_SP_NO_256
7273
         && ecc_sets[key->idx].id != ECC_SECP256R1
7274
    #endif
7275
    #ifdef WOLFSSL_SP_SM2
7276
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7277
    #endif
7278
    #ifdef WOLFSSL_SP_384
7279
         && ecc_sets[key->idx].id != ECC_SECP384R1
7280
    #endif
7281
    #ifdef WOLFSSL_SP_521
7282
         && ecc_sets[key->idx].id != ECC_SECP521R1
7283
    #endif
7284
        )) {
7285
        return WC_KEY_SIZE_E;
7286
    }
7287
#endif
7288
7289
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7290
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7291
    /* generate deterministic 'k' value to be used either with SP or normal */
7292
    if (key->deterministic == 1) {
7293
        if (deterministic_sign_helper(in, inlen, key)) {
7294
            WOLFSSL_MSG("Error generating deterministic k to sign");
7295
            return ECC_PRIV_KEY_E;
7296
        }
7297
    }
7298
#endif
7299
7300
7301
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7302
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7303
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7304
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7305
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7306
            sw->eccSign.in = in;
7307
            sw->eccSign.inSz = inlen;
7308
            sw->eccSign.rng = rng;
7309
            sw->eccSign.key = key;
7310
            sw->eccSign.r = r;
7311
            sw->eccSign.s = s;
7312
            return WC_PENDING_E;
7313
        }
7314
    }
7315
#endif
7316
7317
#if defined(WOLFSSL_HAVE_SP_ECC)
7318
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7319
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7320
       return err;
7321
   }
7322
#else
7323
0
   (void)inlen;
7324
0
#endif
7325
7326
0
#if !defined(WOLFSSL_SP_MATH)
7327
7328
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7329
   err = wc_ecc_alloc_mpint(key, &key->e);
7330
   if (err != 0) {
7331
      return err;
7332
   }
7333
   e = key->e;
7334
#else
7335
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7336
#ifdef MP_INT_SIZE_CHECK_NULL
7337
   if (e_lcl == NULL) {
7338
      return MEMORY_E;
7339
   }
7340
#endif
7341
0
   e = e_lcl;
7342
0
#endif
7343
7344
   /* get the hash and load it as a bignum into 'e' */
7345
   /* init the bignums */
7346
0
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7347
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7348
0
      return err;
7349
0
   }
7350
7351
   /* load curve info */
7352
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7353
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7354
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7355
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7356
    if (err == MP_OKAY)
7357
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7358
#else
7359
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7360
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7361
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7362
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7363
        if (err == MP_OKAY)
7364
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7365
    }
7366
    else
7367
    #endif
7368
0
    {
7369
0
        ALLOC_CURVE_SPECS(1, err);
7370
0
        if (err == MP_OKAY)
7371
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7372
0
    }
7373
0
#endif
7374
7375
   /* load digest into e */
7376
0
   if (err == MP_OKAY) {
7377
       /* we may need to truncate if hash is longer than key size */
7378
0
       word32 orderBits = (word32)mp_count_bits(curve->order);
7379
7380
       /* truncate down to byte size, may be all that's needed */
7381
0
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7382
0
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7383
0
       err = mp_read_unsigned_bin(e, in, inlen);
7384
7385
       /* may still need bit truncation too */
7386
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7387
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7388
0
   }
7389
7390
   /* make up a key and export the public copy */
7391
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7392
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7393
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7394
   #ifdef HAVE_CAVIUM_V
7395
       if (NitroxEccIsCurveSupported(key))
7396
   #endif
7397
       {
7398
           word32 keySz = key->dp->size;
7399
           mp_int* k;
7400
       #ifdef HAVE_CAVIUM_V
7401
           err = wc_ecc_alloc_mpint(key, &key->signK);
7402
           if (err != 0)
7403
              return err;
7404
           k = key->signK;
7405
       #else
7406
           mp_int k_lcl;
7407
           k = &k_lcl;
7408
       #endif
7409
7410
           err = mp_init(k);
7411
7412
            /* make sure r and s are allocated */
7413
       #ifdef HAVE_CAVIUM_V
7414
           /* Nitrox V needs single buffer for R and S */
7415
           if (err == MP_OKAY)
7416
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7417
           /* Nitrox V only needs Prime and Order */
7418
           if (err == MP_OKAY)
7419
               err = wc_ecc_curve_load(key->dp, &curve,
7420
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7421
       #else
7422
           if (err == MP_OKAY)
7423
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7424
           if (err == MP_OKAY)
7425
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7426
       #endif
7427
           if (err == MP_OKAY)
7428
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7429
7430
           /* load e and k */
7431
           if (err == MP_OKAY)
7432
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7433
           if (err == MP_OKAY)
7434
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7435
                  keySz);
7436
           if (err == MP_OKAY)
7437
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7438
           if (err == MP_OKAY)
7439
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7440
7441
       #ifdef HAVE_CAVIUM_V
7442
           if (err == MP_OKAY)
7443
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7444
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7445
                  &curve->order->raw);
7446
       #else
7447
           if (err == MP_OKAY)
7448
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7449
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7450
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7451
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7452
       #endif
7453
7454
       #ifndef HAVE_CAVIUM_V
7455
           mp_clear(e);
7456
           mp_clear(k);
7457
       #endif
7458
           wc_ecc_curve_free(curve);
7459
           FREE_CURVE_SPECS();
7460
7461
           return err;
7462
       }
7463
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7464
   }
7465
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7466
7467
0
   if (err == MP_OKAY) {
7468
   #ifdef WOLFSSL_SMALL_STACK
7469
       ecc_key* pubkey;
7470
   #else
7471
0
       ecc_key  pubkey[1];
7472
0
   #endif
7473
7474
   #ifdef WOLFSSL_SMALL_STACK
7475
       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
7476
       if (pubkey == NULL)
7477
           err = MEMORY_E;
7478
       else
7479
   #endif
7480
0
       {
7481
       /* don't use async for key, since we don't support async return here */
7482
0
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7483
0
           if (err == MP_OKAY) {
7484
0
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7485
0
              wc_ecc_free(pubkey);
7486
           #ifdef WOLFSSL_SMALL_STACK
7487
              XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7488
           #endif
7489
0
           }
7490
0
       }
7491
0
   }
7492
7493
0
   mp_clear(e);
7494
0
   wc_ecc_curve_free(curve);
7495
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7496
0
   FREE_CURVE_SPECS();
7497
0
#endif /* !WOLFSSL_SP_MATH */
7498
7499
0
   return err;
7500
0
}
7501
7502
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7503
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7504
/* helper function to do HMAC operations
7505
 * returns 0 on success and updates "out" buffer
7506
 */
7507
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7508
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7509
        byte* out, enum wc_HashType hashType, void* heap)
7510
{
7511
    Hmac hmac;
7512
    int  ret, init;
7513
7514
    ret = init = wc_HmacInit(&hmac, heap, INVALID_DEVID);
7515
    if (ret == 0)
7516
        ret = wc_HmacSetKey(&hmac, (int)hashType, K, KSz);
7517
7518
    if (ret == 0)
7519
        ret = wc_HmacUpdate(&hmac, V, VSz);
7520
7521
    if (ret == 0 && oct != NULL)
7522
        ret = wc_HmacUpdate(&hmac, oct, 1);
7523
7524
    if (ret == 0)
7525
        ret = wc_HmacUpdate(&hmac, x, xSz);
7526
7527
    if (ret == 0)
7528
        ret = wc_HmacUpdate(&hmac, h1, h1Sz);
7529
7530
    if (ret == 0)
7531
        ret = wc_HmacFinal(&hmac, out);
7532
7533
    if (init == 0)
7534
        wc_HmacFree(&hmac);
7535
7536
    return ret;
7537
}
7538
7539
7540
/* Generates a deterministic key based of the message using RFC6979
7541
 * @param  [in]   hash     Hash value to sign
7542
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7543
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7544
 *                WC_HASH_TYPE_SHA256
7545
 * @param  [in]   priv     Current ECC private key set
7546
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7547
 * @param  [in]   order    ECC order parameter to use with generation
7548
 * @return  0 on success.
7549
 */
7550
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7551
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7552
        void* heap)
7553
{
7554
    int ret = 0;
7555
#ifndef WOLFSSL_SMALL_STACK
7556
    byte h1[MAX_ECC_BYTES];
7557
    byte V[WC_MAX_DIGEST_SIZE];
7558
    byte K[WC_MAX_DIGEST_SIZE];
7559
    byte x[MAX_ECC_BYTES];
7560
    mp_int z1[1];
7561
#else
7562
    byte *h1 = NULL;
7563
    byte *V  = NULL;
7564
    byte *K  = NULL;
7565
    byte *x  = NULL;
7566
    mp_int *z1 = NULL;
7567
#endif
7568
    word32 xSz, VSz, KSz, h1len, qLen;
7569
    byte intOct;
7570
    int qbits = 0;
7571
7572
    if (hash == NULL || k == NULL || order == NULL) {
7573
        return BAD_FUNC_ARG;
7574
    }
7575
7576
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7577
        WOLFSSL_MSG("hash size was too large!");
7578
        return BAD_FUNC_ARG;
7579
    }
7580
7581
    /* if none is provided then detect has type based on hash size */
7582
    if (hashType == WC_HASH_TYPE_NONE) {
7583
        if (hashSz == 64) {
7584
            hashType = WC_HASH_TYPE_SHA512;
7585
        }
7586
        else if (hashSz == 48) {
7587
            hashType = WC_HASH_TYPE_SHA384;
7588
        }
7589
        else if (hashSz == 32) {
7590
            hashType = WC_HASH_TYPE_SHA256;
7591
        }
7592
        else {
7593
            return BAD_FUNC_ARG;
7594
        }
7595
    }
7596
7597
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
7598
        WOLFSSL_MSG("private key larger than max expected!");
7599
        return BAD_FUNC_ARG;
7600
    }
7601
7602
#ifdef WOLFSSL_SMALL_STACK
7603
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
7604
    if (h1 == NULL) {
7605
        ret = MEMORY_E;
7606
    }
7607
7608
    if (ret == 0) {
7609
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7610
        if (V == NULL)
7611
            ret = MEMORY_E;
7612
    }
7613
7614
    if (ret == 0) {
7615
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7616
        if (K == NULL)
7617
            ret = MEMORY_E;
7618
    }
7619
7620
    if (ret == 0) {
7621
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7622
        if (x == NULL)
7623
            ret = MEMORY_E;
7624
    }
7625
7626
    if (ret == 0) {
7627
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
7628
        if (z1 == NULL)
7629
            ret = MEMORY_E;
7630
    }
7631
7632
    /* bail out if any error has been hit at this point */
7633
    if (ret != 0) {
7634
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7635
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7636
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7637
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7638
        return ret;
7639
    }
7640
#endif
7641
7642
    VSz = KSz = hashSz;
7643
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
7644
7645
    /* 3.2 b. Set V = 0x01 0x01 ... */
7646
    XMEMSET(V, 0x01, VSz);
7647
7648
    /* 3.2 c. Set K = 0x00 0x00 ... */
7649
    XMEMSET(K, 0x00, KSz);
7650
7651
    if (ret == 0) {
7652
        ret = mp_init(z1); /* always init z1 and free z1 */
7653
    }
7654
    if (ret == 0) {
7655
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
7656
    }
7657
    if (ret == 0) {
7658
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7659
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
7660
    #endif
7661
        qbits = mp_count_bits(order);
7662
        if (qbits < 0)
7663
            ret = MP_VAL;
7664
    }
7665
7666
    if (ret == 0) {
7667
         /* hash truncate if too long */
7668
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
7669
            /* calculate truncated hash size using bits rounded up byte */
7670
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
7671
        }
7672
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
7673
    }
7674
7675
    /* bits2octets on h1 */
7676
    if (ret == 0) {
7677
        XMEMSET(h1, 0, MAX_ECC_BYTES);
7678
7679
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7680
        /* mod reduce by order using conditional subtract
7681
         * RFC6979 lists a variant that uses the hash directly instead of
7682
         * doing bits2octets(H(m)), when variant macro is used avoid this
7683
         * bits2octets operation */
7684
        if (mp_cmp(z1, order) == MP_GT) {
7685
            int z1Sz;
7686
7687
            mp_sub(z1, order, z1);
7688
            z1Sz = mp_unsigned_bin_size(z1);
7689
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
7690
                ret = BUFFER_E;
7691
            }
7692
            else {
7693
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7694
            }
7695
        }
7696
        else
7697
    #endif
7698
        {
7699
            /* use original hash and keep leading 0's */
7700
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7701
        }
7702
    }
7703
    mp_free(z1);
7704
7705
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
7706
    if (ret == 0) {
7707
        intOct = 0x00;
7708
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
7709
                hashType, heap);
7710
    }
7711
7712
    /* 3.2 step e. V = HMAC_K(V) */
7713
    if (ret == 0) {
7714
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7715
                heap);
7716
    }
7717
7718
7719
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
7720
    if (ret == 0) {
7721
        intOct = 0x01;
7722
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
7723
                heap);
7724
    }
7725
7726
    /* 3.2 step g. V = HMAC_K(V) */
7727
    if (ret == 0) {
7728
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7729
                heap);
7730
    }
7731
7732
    /* 3.2 step h. loop through the next steps until a valid value is found */
7733
    if (ret == 0 ) {
7734
        int err;
7735
7736
        intOct = 0x00;
7737
        do {
7738
            xSz = 0; /* used as tLen */
7739
            err = 0; /* start as good until generated k is tested */
7740
7741
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
7742
            while (xSz < qLen) {
7743
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7744
                        hashType, heap);
7745
                if (ret == 0) {
7746
                    int sz;
7747
7748
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
7749
                    XMEMCPY(x + xSz, V, (size_t)sz);
7750
                    xSz += (word32)sz;
7751
                }
7752
                else {
7753
                    break; /* error case */
7754
                }
7755
            }
7756
7757
            if (ret == 0) {
7758
                mp_clear(k); /* 3.2 step h.1 clear T */
7759
                ret = mp_read_unsigned_bin(k, x, xSz);
7760
            }
7761
7762
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
7763
                /* handle odd case where shift of 'k' is needed with RFC 6979
7764
                 *  k = bits2int(T) in section 3.2 h.3 */
7765
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
7766
            }
7767
7768
            /* 3.2 step h.3 the key should be smaller than the order of base
7769
             * point */
7770
            if (ret == 0) {
7771
                if (mp_cmp(k, order) != MP_LT) {
7772
                    err = MP_VAL;
7773
                } else if (mp_iszero(k) == MP_YES) {
7774
                    /* no 0 key's */
7775
                    err = MP_ZERO_E;
7776
                }
7777
            }
7778
7779
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
7780
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
7781
            if (ret == 0 && err != 0) {
7782
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
7783
                    hashType, heap);
7784
                if (ret == 0) {
7785
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7786
                    hashType, heap);
7787
                }
7788
            }
7789
        } while (ret == 0 && err != 0);
7790
    }
7791
7792
    ForceZero(x, MAX_ECC_BYTES);
7793
#ifdef WOLFSSL_SMALL_STACK
7794
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
7795
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7796
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7797
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7798
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7799
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
7800
    wc_MemZero_Check(x, MAX_ECC_BYTES);
7801
#endif
7802
7803
    return ret;
7804
}
7805
7806
7807
/* Sets the deterministic flag for 'k' generation with sign.
7808
 * returns 0 on success
7809
 */
7810
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
7811
                                enum wc_HashType hashType)
7812
{
7813
    if (key == NULL) {
7814
        return BAD_FUNC_ARG;
7815
    }
7816
7817
    key->deterministic = flag ? 1 : 0;
7818
    key->hashType = hashType;
7819
    return 0;
7820
}
7821
7822
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
7823
{
7824
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
7825
}
7826
7827
#endif /* end sign_ex and deterministic sign */
7828
7829
7830
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
7831
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
7832
{
7833
    int ret = MP_OKAY;
7834
    DECLARE_CURVE_SPECS(1);
7835
7836
    if (k == NULL || klen == 0 || key == NULL) {
7837
        return BAD_FUNC_ARG;
7838
    }
7839
7840
    ALLOC_CURVE_SPECS(1, ret);
7841
    if (ret == MP_OKAY) {
7842
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7843
    }
7844
7845
    if (ret != 0) {
7846
        FREE_CURVE_SPECS();
7847
        return ret;
7848
    }
7849
7850
#ifndef WOLFSSL_NO_MALLOC
7851
    if (key->sign_k == NULL) {
7852
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7853
                                                            DYNAMIC_TYPE_ECC);
7854
        if (key->sign_k) {
7855
            ret = mp_init(key->sign_k);
7856
        }
7857
        else {
7858
            ret = MEMORY_E;
7859
        }
7860
    }
7861
#endif
7862
7863
    if (ret == 0) {
7864
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7865
    }
7866
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7867
        ret = MP_VAL;
7868
    }
7869
#ifdef WOLFSSL_NO_MALLOC
7870
    if (ret == 0) {
7871
        key->sign_k_set = 1;
7872
    }
7873
#endif
7874
7875
    wc_ecc_curve_free(curve);
7876
    FREE_CURVE_SPECS();
7877
    return ret;
7878
}
7879
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
7880
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
7881
7882
#endif /* !HAVE_ECC_SIGN */
7883
7884
#ifdef WOLFSSL_CUSTOM_CURVES
7885
void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
7886
{
7887
#ifndef WOLFSSL_ECC_CURVE_STATIC
7888
    if (curve->prime != NULL)
7889
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7890
    if (curve->Af != NULL)
7891
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7892
    if (curve->Bf != NULL)
7893
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7894
    if (curve->order != NULL)
7895
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7896
    if (curve->Gx != NULL)
7897
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7898
    if (curve->Gy != NULL)
7899
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7900
#endif
7901
7902
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7903
7904
    (void)heap;
7905
}
7906
#endif /* WOLFSSL_CUSTOM_CURVES */
7907
7908
/**
7909
  Free an ECC key from memory
7910
  key   The key you wish to free
7911
*/
7912
WOLFSSL_ABI
7913
int wc_ecc_free(ecc_key* key)
7914
0
{
7915
0
    if (key == NULL) {
7916
0
        return 0;
7917
0
    }
7918
7919
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7920
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7921
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7922
#ifndef WOLFSSL_NO_MALLOC
7923
    if (key->sign_k != NULL)
7924
#endif
7925
    {
7926
        mp_forcezero(key->sign_k);
7927
        mp_free(key->sign_k);
7928
#ifndef WOLFSSL_NO_MALLOC
7929
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7930
#endif
7931
    }
7932
#endif
7933
7934
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7935
    #ifdef WC_ASYNC_ENABLE_ECC
7936
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
7937
    #endif
7938
    wc_ecc_free_async(key);
7939
#endif
7940
7941
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
7942
    /* free secure memory */
7943
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
7944
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
7945
       caamFreePart(key->partNum);
7946
    }
7947
#endif
7948
7949
#ifdef WOLFSSL_SE050
7950
#ifdef WOLFSSL_SE050_AUTO_ERASE
7951
    wc_se050_erase_object(key->keyId);
7952
#endif
7953
    se050_ecc_free_key(key);
7954
#endif
7955
7956
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7957
    atmel_ecc_free(key->slot);
7958
    key->slot = ATECC_INVALID_SLOT;
7959
#endif /* WOLFSSL_ATECC508A */
7960
7961
#ifdef WOLFSSL_KCAPI_ECC
7962
    KcapiEcc_Free(key);
7963
#endif
7964
7965
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7966
    key->privKey = NULL;
7967
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
7968
    ForceZero(&key->xSec, sizeof(key->xSec));
7969
#endif
7970
7971
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
7972
    wc_MAXQ10XX_EccFree(key);
7973
#endif
7974
7975
0
    mp_clear(key->pubkey.x);
7976
0
    mp_clear(key->pubkey.y);
7977
0
    mp_clear(key->pubkey.z);
7978
7979
#ifdef ALT_ECC_SIZE
7980
    if (key->k)
7981
#endif
7982
0
        mp_forcezero(key->k);
7983
#ifdef WOLFSSL_ECC_BLIND_K
7984
#ifdef ALT_ECC_SIZE
7985
    if (key->kb)
7986
#endif
7987
        mp_forcezero(key->kb);
7988
#ifdef ALT_ECC_SIZE
7989
    if (key->ku)
7990
#endif
7991
        mp_forcezero(key->ku);
7992
#endif
7993
7994
#ifdef WOLFSSL_CUSTOM_CURVES
7995
    if (key->deallocSet && key->dp != NULL)
7996
        wc_ecc_free_curve(key->dp, key->heap);
7997
#endif
7998
7999
#ifdef WOLFSSL_CHECK_MEM_ZERO
8000
    wc_MemZero_Check(key, sizeof(ecc_key));
8001
#endif
8002
8003
0
    return 0;
8004
0
}
8005
8006
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
8007
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
8008
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
8009
      defined(WOLFSSL_IMXRT1170_CAAM))
8010
8011
/* Handles add failure cases:
8012
 *
8013
 * Before add:
8014
 *   Case 1: A is infinity
8015
 *        -> Copy B into result.
8016
 *   Case 2: B is infinity
8017
 *        -> Copy A into result.
8018
 *   Case 3: x and z are the same in A and B (same x value in affine)
8019
 *     Case 3a: y values the same - same point
8020
 *           -> Double instead of add.
8021
 *     Case 3b: y values different - negative of the other when points on curve
8022
 *           -> Need to set result to infinity.
8023
 *
8024
 * After add:
8025
 *   Case 1: A and B are the same point (maybe different z)
8026
 *           (Result was: x == y == z == 0)
8027
 *        -> Need to double instead.
8028
 *
8029
 *   Case 2: A + B = <infinity> = 0.
8030
 *           (Result was: z == 0, x and/or y not 0)
8031
 *        -> Need to set result to infinity.
8032
 */
8033
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8034
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8035
0
{
8036
0
    int err;
8037
8038
0
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8039
        /* A is infinity. */
8040
0
        err = wc_ecc_copy_point(B, R);
8041
0
    }
8042
0
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8043
        /* B is infinity. */
8044
0
        err = wc_ecc_copy_point(A, R);
8045
0
    }
8046
0
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8047
        /* x ordinattes the same. */
8048
0
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8049
            /* A = B */
8050
0
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8051
0
        }
8052
0
        else {
8053
            /* A = -B */
8054
0
            err = mp_set(R->x, 0);
8055
0
            if (err == MP_OKAY)
8056
0
                err = mp_set(R->y, 0);
8057
0
            if (err == MP_OKAY)
8058
0
                err = mp_set(R->z, 1);
8059
0
            if ((err == MP_OKAY) && (infinity != NULL))
8060
0
                *infinity = 1;
8061
0
        }
8062
0
    }
8063
0
    else {
8064
0
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8065
0
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8066
            /* When all zero then should have done a double */
8067
0
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8068
0
                if (mp_iszero(B->z)) {
8069
0
                    err = wc_ecc_copy_point(B, R);
8070
0
                    if (err == MP_OKAY) {
8071
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8072
0
                    }
8073
0
                    if (err == MP_OKAY) {
8074
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8075
0
                    }
8076
0
                }
8077
0
                else {
8078
0
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8079
0
                }
8080
0
            }
8081
            /* When only Z zero then result is infinity */
8082
0
            else {
8083
0
                err = mp_set(R->x, 0);
8084
0
                if (err == MP_OKAY)
8085
0
                    err = mp_set(R->y, 0);
8086
0
                if (err == MP_OKAY)
8087
0
                    err = mp_set(R->z, 1);
8088
0
                if ((err == MP_OKAY) && (infinity != NULL))
8089
0
                    *infinity = 1;
8090
0
            }
8091
0
        }
8092
0
    }
8093
8094
0
    return err;
8095
0
}
8096
8097
/* Handles when P is the infinity point.
8098
 *
8099
 * Double infinity -> infinity.
8100
 * Otherwise do normal double - which can't lead to infinity as odd order.
8101
 */
8102
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8103
                                  mp_int* modulus, mp_digit mp)
8104
0
{
8105
0
    int err;
8106
8107
0
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8108
        /* P is infinity. */
8109
0
        err = wc_ecc_copy_point(P, R);
8110
0
    }
8111
0
    else {
8112
0
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8113
0
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8114
0
           err = mp_set(R->x, 0);
8115
0
           if (err == MP_OKAY)
8116
0
               err = mp_set(R->y, 0);
8117
0
           if (err == MP_OKAY)
8118
0
               err = mp_set(R->z, 1);
8119
0
        }
8120
0
    }
8121
8122
0
    return err;
8123
0
}
8124
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8125
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8126
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8127
            (WOLFSSL_IMXRT1170_CAAM))
8128
        */
8129
8130
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8131
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \
8132
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8133
#ifdef ECC_SHAMIR
8134
8135
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8136
    ecc_point* Bm, mp_int* modulus, void* heap)
8137
0
{
8138
0
    int err = MP_OKAY;
8139
0
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8140
8141
0
    (void)heap;
8142
8143
0
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8144
#ifdef MP_INT_SIZE_CHECK_NULL
8145
    if (mu == NULL)
8146
       err = MEMORY_E;
8147
#endif
8148
0
    if (err == MP_OKAY) {
8149
0
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8150
0
    }
8151
0
    if (err == MP_OKAY) {
8152
0
        err = mp_montgomery_calc_normalization(mu, modulus);
8153
8154
0
        if (err == MP_OKAY) {
8155
            /* copy ones ... */
8156
0
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8157
0
        }
8158
8159
0
        if (err == MP_OKAY)
8160
0
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8161
0
        if (err == MP_OKAY)
8162
0
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8163
8164
0
        if (err == MP_OKAY)
8165
0
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8166
0
        if (err == MP_OKAY)
8167
0
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8168
0
        if (err == MP_OKAY)
8169
0
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8170
8171
        /* done with mu */
8172
0
        mp_clear(mu);
8173
0
    }
8174
8175
0
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8176
8177
0
    return err;
8178
0
}
8179
8180
/** Computes kA*A + kB*B = C using Shamir's Trick
8181
  A        First point to multiply
8182
  kA       What to multiple A by
8183
  B        Second point to multiply
8184
  kB       What to multiple B by
8185
  C        [out] Destination point (can overlap with A or B)
8186
  a        ECC curve parameter a
8187
  modulus  Modulus for curve
8188
  return MP_OKAY on success
8189
*/
8190
#ifdef FP_ECC
8191
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8192
                             ecc_point* B, mp_int* kB,
8193
                             ecc_point* C, mp_int* a, mp_int* modulus,
8194
                             void* heap)
8195
#else
8196
int ecc_mul2add(ecc_point* A, mp_int* kA,
8197
                    ecc_point* B, mp_int* kB,
8198
                    ecc_point* C, mp_int* a, mp_int* modulus,
8199
                    void* heap)
8200
#endif
8201
0
{
8202
#ifdef WOLFSSL_SMALL_STACK_CACHE
8203
  ecc_key        *key = NULL;
8204
#endif
8205
#ifdef WOLFSSL_SMALL_STACK
8206
  ecc_point**    precomp = NULL;
8207
#else
8208
0
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8209
  #ifdef WOLFSSL_NO_MALLOC
8210
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8211
  #endif
8212
0
#endif
8213
0
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8214
#ifdef WOLFSSL_NO_MALLOC
8215
  unsigned char tA[ECC_BUFSIZE];
8216
  unsigned char tB[ECC_BUFSIZE];
8217
#else
8218
0
  unsigned char* tA = NULL;
8219
0
  unsigned char* tB = NULL;
8220
0
#endif
8221
0
  int            err = MP_OKAY, first, x, y;
8222
0
  mp_digit       mp = 0;
8223
8224
  /* argchks */
8225
0
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8226
0
                                                         modulus == NULL) {
8227
0
     return ECC_BAD_ARG_E;
8228
0
  }
8229
8230
0
#ifndef WOLFSSL_NO_MALLOC
8231
  /* allocate memory */
8232
0
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8233
0
  if (tA == NULL) {
8234
0
     return MP_MEM;
8235
0
  }
8236
0
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8237
0
  if (tB == NULL) {
8238
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8239
0
     return MP_MEM;
8240
0
  }
8241
0
#endif
8242
8243
#ifdef WOLFSSL_SMALL_STACK_CACHE
8244
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8245
  if (key == NULL) {
8246
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8247
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8248
     return MP_MEM;
8249
  }
8250
#endif
8251
#ifdef WOLFSSL_SMALL_STACK
8252
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8253
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8254
  if (precomp == NULL) {
8255
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8256
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8257
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8258
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8259
  #endif
8260
     return MP_MEM;
8261
  }
8262
#endif
8263
#ifdef WOLFSSL_SMALL_STACK_CACHE
8264
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8265
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8266
#ifdef ALT_ECC_SIZE
8267
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8268
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8269
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8270
#endif
8271
8272
  if (key->t1 == NULL || key->t2 == NULL
8273
#ifdef ALT_ECC_SIZE
8274
     || key->x == NULL || key->y == NULL || key->z == NULL
8275
#endif
8276
  ) {
8277
#ifdef ALT_ECC_SIZE
8278
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8279
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8280
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8281
#endif
8282
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8283
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8284
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8285
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8286
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8287
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8288
      return MEMORY_E;
8289
  }
8290
  C->key = key;
8291
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8292
8293
  /* init variables */
8294
0
  XMEMSET(tA, 0, ECC_BUFSIZE);
8295
0
  XMEMSET(tB, 0, ECC_BUFSIZE);
8296
0
#ifndef WOLFSSL_SMALL_STACK
8297
0
  XMEMSET(precomp, 0, sizeof(precomp));
8298
#else
8299
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8300
#endif
8301
#ifdef WOLFSSL_CHECK_MEM_ZERO
8302
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8303
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8304
#endif
8305
8306
  /* get sizes */
8307
0
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8308
0
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8309
0
  len  = MAX(lenA, lenB);
8310
8311
  /* sanity check */
8312
0
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8313
0
    err = BAD_FUNC_ARG;
8314
0
  }
8315
8316
0
  if (err == MP_OKAY) {
8317
    /* extract and justify kA */
8318
0
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8319
8320
    /* extract and justify kB */
8321
0
    if (err == MP_OKAY)
8322
0
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8323
8324
    /* allocate the table */
8325
0
    if (err == MP_OKAY) {
8326
0
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8327
        #ifdef WOLFSSL_NO_MALLOC
8328
            precomp[x] = &lcl_precomp[x];
8329
        #endif
8330
0
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8331
0
            if (err != MP_OKAY)
8332
0
                break;
8333
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8334
            precomp[x]->key = key;
8335
        #endif
8336
0
        }
8337
0
    }
8338
0
  }
8339
8340
0
  if (err == MP_OKAY)
8341
    /* init montgomery reduction */
8342
0
    err = mp_montgomery_setup(modulus, &mp);
8343
8344
0
  if (err == MP_OKAY) {
8345
0
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8346
0
  }
8347
8348
0
  if (err == MP_OKAY) {
8349
    /* precomp [i,0](A + B) table */
8350
0
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8351
0
  }
8352
0
  if (err == MP_OKAY) {
8353
0
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8354
0
                                                          a, modulus, mp, NULL);
8355
0
  }
8356
8357
0
  if (err == MP_OKAY) {
8358
    /* precomp [0,i](A + B) table */
8359
0
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8360
0
  }
8361
0
  if (err == MP_OKAY) {
8362
0
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8363
0
                                                             modulus, mp, NULL);
8364
0
  }
8365
8366
0
  if (err == MP_OKAY) {
8367
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8368
0
    for (x = 1; x < 4; x++) {
8369
0
      for (y = 1; y < 4; y++) {
8370
0
        if (err == MP_OKAY) {
8371
0
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8372
0
                                                  precomp[x+(y<<2)], a, modulus,
8373
0
                                                  mp, NULL);
8374
0
        }
8375
0
      }
8376
0
    }
8377
0
  }
8378
8379
0
  if (err == MP_OKAY) {
8380
0
    nibble  = 3;
8381
0
    first   = 1;
8382
0
    bitbufA = tA[0];
8383
0
    bitbufB = tB[0];
8384
8385
    /* for every byte of the multiplicands */
8386
0
    for (x = 0; x < (int)len || nibble != 3; ) {
8387
        /* grab a nibble */
8388
0
        if (++nibble == 4) {
8389
0
            if (x == (int)len) break;
8390
0
            bitbufA = tA[x];
8391
0
            bitbufB = tB[x];
8392
0
            nibble  = 0;
8393
0
            x++;
8394
0
        }
8395
8396
        /* extract two bits from both, shift/update */
8397
0
        nA = (bitbufA >> 6) & 0x03;
8398
0
        nB = (bitbufB >> 6) & 0x03;
8399
0
        bitbufA = (bitbufA << 2) & 0xFF;
8400
0
        bitbufB = (bitbufB << 2) & 0xFF;
8401
8402
        /* if both zero, if first, continue */
8403
0
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8404
0
            continue;
8405
0
        }
8406
8407
        /* double twice, only if this isn't the first */
8408
0
        if (first == 0) {
8409
            /* double twice */
8410
0
            if (err == MP_OKAY)
8411
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8412
0
            if (err == MP_OKAY)
8413
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8414
0
            else
8415
0
                break;
8416
0
        }
8417
8418
        /* if not both zero */
8419
0
        if ((nA != 0) || (nB != 0)) {
8420
0
            unsigned int i = nA + (nB<<2);
8421
0
            if (first == 1) {
8422
                /* if first, copy from table */
8423
0
                first = 0;
8424
0
                if (err == MP_OKAY)
8425
0
                    err = mp_copy(precomp[i]->x, C->x);
8426
8427
0
                if (err == MP_OKAY)
8428
0
                    err = mp_copy(precomp[i]->y, C->y);
8429
8430
0
                if (err == MP_OKAY)
8431
0
                    err = mp_copy(precomp[i]->z, C->z);
8432
0
                else
8433
0
                    break;
8434
0
            } else {
8435
                /* if not first, add from table */
8436
0
                if (err == MP_OKAY)
8437
0
                    err = ecc_projective_add_point_safe(C, precomp[i],
8438
0
                                                        C, a, modulus, mp,
8439
0
                                                        &first);
8440
0
                if (err != MP_OKAY)
8441
0
                    break;
8442
0
            }
8443
0
        }
8444
0
    }
8445
0
  }
8446
8447
  /* reduce to affine */
8448
0
  if (err == MP_OKAY)
8449
0
    err = ecc_map(C, modulus, mp);
8450
8451
  /* clean up */
8452
0
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8453
0
     wc_ecc_del_point_ex(precomp[x], heap);
8454
0
  }
8455
8456
0
  ForceZero(tA, ECC_BUFSIZE);
8457
0
  ForceZero(tB, ECC_BUFSIZE);
8458
#ifdef WOLFSSL_SMALL_STACK_CACHE
8459
#ifdef ALT_ECC_SIZE
8460
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8461
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8462
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8463
#endif
8464
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8465
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8466
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8467
  C->key = NULL;
8468
#endif
8469
#ifdef WOLFSSL_SMALL_STACK
8470
  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8471
#endif
8472
0
#ifndef WOLFSSL_NO_MALLOC
8473
0
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8474
0
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8475
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8476
  wc_MemZero_Check(tB, ECC_BUFSIZE);
8477
  wc_MemZero_Check(tA, ECC_BUFSIZE);
8478
#endif
8479
0
  return err;
8480
0
}
8481
8482
#endif /* ECC_SHAMIR */
8483
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
8484
        * !WOLFSSL_CRYPTOCEL */
8485
8486
8487
#ifdef HAVE_ECC_VERIFY
8488
/* verify
8489
 *
8490
 * w  = s^-1 mod n
8491
 * u1 = xw
8492
 * u2 = rw
8493
 * X = u1*G + u2*Q
8494
 * v = X_x1 mod n
8495
 * accept if v == r
8496
 */
8497
8498
/**
8499
 Verify an ECC signature
8500
 sig         The signature to verify
8501
 siglen      The length of the signature (octets)
8502
 hash        The hash (message digest) that was signed
8503
 hashlen     The length of the hash (octets)
8504
 res         Result of signature, 1==valid, 0==invalid
8505
 key         The corresponding public ECC key
8506
 return      MP_OKAY if successful (even if the signature is not valid)
8507
             Caller should check the *res value to determine if the signature
8508
             is valid or invalid. Other negative values are returned on error.
8509
 */
8510
WOLFSSL_ABI
8511
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
8512
                       word32 hashlen, int* res, ecc_key* key)
8513
0
{
8514
0
    int err;
8515
8516
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8517
    mp_int *r = NULL, *s = NULL;
8518
#else
8519
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8520
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8521
0
#endif
8522
#ifdef WOLFSSL_ASYNC_CRYPT
8523
    int isPrivateKeyOnly = 0;
8524
#endif
8525
#ifdef NO_ASN
8526
    word32 keySz;
8527
#endif
8528
8529
0
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8530
0
        return ECC_BAD_ARG_E;
8531
0
    }
8532
8533
#ifdef WOLF_CRYPTO_CB
8534
    #ifndef WOLF_CRYPTO_CB_FIND
8535
    if (key->devId != INVALID_DEVID)
8536
    #endif
8537
    {
8538
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
8539
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8540
            return err;
8541
        /* fall-through when unavailable */
8542
    }
8543
#endif
8544
8545
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
8546
    (void)siglen;
8547
    (void)hashlen;
8548
    (void)s;
8549
    (void)r;
8550
    (void)err;
8551
    return NO_VALID_DEVID;
8552
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
8553
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8554
    err = wc_ecc_alloc_async(key);
8555
    if (err != 0)
8556
        return err;
8557
    r = key->r;
8558
    s = key->s;
8559
#else
8560
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8561
0
        DYNAMIC_TYPE_ECC);
8562
    #ifdef MP_INT_SIZE_CHECK_NULL
8563
    if (r == NULL)
8564
        return MEMORY_E;
8565
    #endif
8566
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8567
0
        DYNAMIC_TYPE_ECC);
8568
    #ifdef MP_INT_SIZE_CHECK_NULL
8569
    if (s == NULL) {
8570
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8571
        return MEMORY_E;
8572
    }
8573
    #endif
8574
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8575
0
    if (err != 0) {
8576
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8577
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8578
0
        return err;
8579
0
    }
8580
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8581
0
    if (err != 0) {
8582
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8583
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8584
0
        return err;
8585
0
    }
8586
0
#endif /* WOLFSSL_ASYNC_CRYPT */
8587
8588
0
    switch (key->state) {
8589
0
        case ECC_STATE_NONE:
8590
0
        case ECC_STATE_VERIFY_DECODE:
8591
0
            key->state = ECC_STATE_VERIFY_DECODE;
8592
8593
            /* default to invalid signature */
8594
0
            *res = 0;
8595
8596
0
    #ifndef NO_ASN
8597
            /* Decode ASN.1 ECDSA signature. */
8598
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8599
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
8600
             * If either of those don't allocate correctly, none of
8601
             * the rest of this function will execute, and everything
8602
             * gets cleaned up at the end. */
8603
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
8604
        #else
8605
            /* r and s are initialized. */
8606
0
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8607
0
        #endif
8608
0
            if (err < 0) {
8609
0
                break;
8610
0
            }
8611
    #else
8612
            /* No support for DSA ASN.1 header.
8613
             * Signature must be r+s directly. */
8614
            keySz = 0;
8615
            if (key->dp != NULL) {
8616
                keySz = (word32)key->dp->size;
8617
            }
8618
            if (siglen != keySz * 2) {
8619
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
8620
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
8621
            }
8622
8623
            /* Import signature into r,s */
8624
            mp_init(r);
8625
            mp_init(s);
8626
            mp_read_unsigned_bin(r, sig, keySz);
8627
            mp_read_unsigned_bin(s, sig + keySz, keySz);
8628
    #endif /* !NO_ASN */
8629
0
            FALL_THROUGH;
8630
8631
0
        case ECC_STATE_VERIFY_DO:
8632
0
            key->state = ECC_STATE_VERIFY_DO;
8633
        #ifdef WOLFSSL_ASYNC_CRYPT
8634
            if (key->type == ECC_PRIVATEKEY_ONLY) {
8635
                isPrivateKeyOnly = 1;
8636
            }
8637
        #endif
8638
0
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8639
8640
0
        #ifndef WOLFSSL_ASYNC_CRYPT
8641
            /* done with R/S */
8642
0
            mp_clear(r);
8643
0
            mp_clear(s);
8644
0
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8645
0
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8646
        #ifdef MP_INT_SIZE_CHECK_NULL
8647
            r = NULL;
8648
            s = NULL;
8649
        #endif
8650
0
        #endif
8651
8652
0
            if (err < 0) {
8653
0
                break;
8654
0
            }
8655
0
            FALL_THROUGH;
8656
8657
0
        case ECC_STATE_VERIFY_RES:
8658
0
            key->state = ECC_STATE_VERIFY_RES;
8659
0
            err = 0;
8660
0
            break;
8661
8662
0
        default:
8663
0
            err = BAD_STATE_E;
8664
0
    }
8665
8666
#ifdef WOLFSSL_ASYNC_CRYPT
8667
    /* if async pending then return and skip done cleanup below */
8668
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8669
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
8670
            key->state++;
8671
        return err;
8672
    }
8673
#endif
8674
8675
    /* cleanup */
8676
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8677
    wc_ecc_free_async(key);
8678
#else
8679
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8680
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8681
0
#endif
8682
8683
    /* make sure required variables are reset */
8684
0
    wc_ecc_reset(key);
8685
0
    return err;
8686
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8687
0
}
8688
8689
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
8690
8691
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
8692
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8693
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
8694
0
{
8695
0
    int err = MP_OKAY;
8696
0
    DECLARE_CURVE_SPECS(1);
8697
8698
0
    ALLOC_CURVE_SPECS(1, err);
8699
0
    if (err == MP_OKAY) {
8700
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8701
0
    }
8702
0
    if (err != 0) {
8703
0
        FREE_CURVE_SPECS();
8704
0
        return err;
8705
0
    }
8706
8707
0
    if (mp_iszero(r) || mp_iszero(s)) {
8708
0
        err = MP_ZERO_E;
8709
0
    }
8710
0
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8711
0
        err = MP_VAL;
8712
0
    }
8713
0
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8714
0
        err = MP_VAL;
8715
0
    }
8716
8717
0
    wc_ecc_curve_free(curve);
8718
0
    FREE_CURVE_SPECS();
8719
0
    return err;
8720
0
}
8721
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
8722
8723
#ifdef HAVE_ECC_VERIFY_HELPER
8724
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
8725
    word32 hashlen, int* res, ecc_key* key)
8726
0
{
8727
0
    (void)r;
8728
0
    (void)s;
8729
0
    (void)hash;
8730
0
    (void)hashlen;
8731
0
    (void)res;
8732
0
    (void)key;
8733
8734
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
8735
  if (key->handle != -1) {
8736
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
8737
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8738
  }
8739
  if (wolfSSL_GetHandleCbSet() == 1) {
8740
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
8741
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8742
  }
8743
#endif
8744
8745
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
8746
    if (key->idx == ECC_CUSTOM_IDX || (1
8747
    #ifndef WOLFSSL_SP_NO_256
8748
         && ecc_sets[key->idx].id != ECC_SECP256R1
8749
    #endif
8750
    #ifdef WOLFSSL_SP_SM2
8751
         && ecc_sets[key->idx].id != ECC_SM2P256V1
8752
    #endif
8753
    #ifdef WOLFSSL_SP_384
8754
         && ecc_sets[key->idx].id != ECC_SECP384R1
8755
    #endif
8756
    #ifdef WOLFSSL_SP_521
8757
         && ecc_sets[key->idx].id != ECC_SECP521R1
8758
    #endif
8759
        )) {
8760
        return WC_KEY_SIZE_E;
8761
    }
8762
#endif
8763
8764
#if defined(WOLFSSL_HAVE_SP_ECC)
8765
    if (key->idx != ECC_CUSTOM_IDX) {
8766
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
8767
        /* perform blocking call to non-blocking function */
8768
        ecc_nb_ctx_t nb_ctx;
8769
        int err;
8770
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
8771
        err = NOT_COMPILED_IN; /* set default error */
8772
    #endif
8773
    #ifndef WOLFSSL_SP_NO_256
8774
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
8775
        #ifdef WC_ECC_NONBLOCK
8776
            if (key->nb_ctx) {
8777
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8778
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8779
                    key->heap);
8780
            }
8781
            #ifdef WC_ECC_NONBLOCK_ONLY
8782
            do { /* perform blocking call to non-blocking function */
8783
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
8784
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8785
                    key->heap);
8786
            } while (err == FP_WOULDBLOCK);
8787
            return err;
8788
            #endif
8789
        #endif /* WC_ECC_NONBLOCK */
8790
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8791
            {
8792
                int ret;
8793
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8794
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
8795
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8796
                RESTORE_VECTOR_REGISTERS();
8797
                return ret;
8798
            }
8799
        #endif
8800
        }
8801
    #endif
8802
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
8803
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
8804
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
8805
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
8806
                key->pubkey.y, key->pubkey.z, r, s, res,
8807
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
8808
                                          key->fpIdx, key->fpBuild, key->heap),
8809
                key->heap);
8810
            #endif
8811
            #if !defined(FP_ECC_CONTROL)
8812
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
8813
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8814
            #endif
8815
        }
8816
    #endif
8817
    #ifdef WOLFSSL_SP_384
8818
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
8819
        #ifdef WC_ECC_NONBLOCK
8820
            if (key->nb_ctx) {
8821
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8822
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8823
                    key->heap);
8824
            }
8825
            #ifdef WC_ECC_NONBLOCK_ONLY
8826
            do { /* perform blocking call to non-blocking function */
8827
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
8828
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8829
                    key->heap);
8830
            } while (err == FP_WOULDBLOCK);
8831
            return err;
8832
            #endif
8833
        #endif /* WC_ECC_NONBLOCK */
8834
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8835
            {
8836
                int ret;
8837
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8838
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
8839
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8840
                RESTORE_VECTOR_REGISTERS();
8841
                return ret;
8842
            }
8843
        #endif
8844
        }
8845
    #endif
8846
    #ifdef WOLFSSL_SP_521
8847
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
8848
        #ifdef WC_ECC_NONBLOCK
8849
            if (key->nb_ctx) {
8850
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8851
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8852
                    key->heap);
8853
            }
8854
            #ifdef WC_ECC_NONBLOCK_ONLY
8855
            do { /* perform blocking call to non-blocking function */
8856
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
8857
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8858
                    key->heap);
8859
            } while (err == FP_WOULDBLOCK);
8860
            return err;
8861
            #endif
8862
        #endif /* WC_ECC_NONBLOCK */
8863
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8864
            {
8865
                int ret;
8866
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8867
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
8868
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8869
                RESTORE_VECTOR_REGISTERS();
8870
                return ret;
8871
            }
8872
        #endif
8873
        }
8874
    #endif
8875
    }
8876
#endif
8877
8878
0
    return NOT_COMPILED_IN;
8879
0
}
8880
8881
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
8882
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
8883
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
8884
0
{
8885
0
   int        err;
8886
0
   ecc_point* mG = NULL;
8887
0
   ecc_point* mQ = NULL;
8888
#ifdef WOLFSSL_NO_MALLOC
8889
   ecc_point  lcl_mG;
8890
   ecc_point  lcl_mQ;
8891
#endif
8892
0
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8893
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8894
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8895
0
#endif
8896
0
   mp_int*    e;
8897
0
   mp_int*    v = NULL;      /* Will be w. */
8898
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
8899
   mp_int     u1tmp[1];
8900
   mp_int     u2tmp[1];
8901
#endif
8902
0
   mp_int*    u1 = NULL;     /* Will be e. */
8903
0
   mp_int*    u2 = NULL;     /* Will be w. */
8904
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
8905
   err = wc_ecc_alloc_mpint(key, &key->e);
8906
   if (err != 0) {
8907
      return err;
8908
   }
8909
   e = key->e;
8910
8911
   err = mp_init(e);
8912
#else
8913
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8914
#ifdef MP_INT_SIZE_CHECK_NULL
8915
   if (e_lcl == NULL) {
8916
       return MEMORY_E;
8917
   }
8918
#endif
8919
0
   e = e_lcl;
8920
8921
0
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8922
0
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8923
0
   if (err != MP_OKAY) {
8924
#ifdef WOLFSSL_SMALL_STACK
8925
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8926
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8927
   #endif
8928
#endif
8929
0
      return MEMORY_E;
8930
0
   }
8931
8932
   /* read hash */
8933
0
   if (err == MP_OKAY) {
8934
       /* we may need to truncate if hash is longer than key size */
8935
0
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
8936
8937
       /* truncate down to byte size, may be all that's needed */
8938
0
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8939
0
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8940
0
       err = mp_read_unsigned_bin(e, hash, hashlen);
8941
8942
       /* may still need bit truncation too */
8943
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8944
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8945
0
   }
8946
8947
   /* check for async hardware acceleration */
8948
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8949
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8950
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8951
   #ifdef HAVE_CAVIUM_V
8952
      if (NitroxEccIsCurveSupported(key))
8953
   #endif
8954
      {
8955
          word32 keySz = (word32)key->dp->size;
8956
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8957
          if (err == MP_OKAY)
8958
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
8959
          if (err == MP_OKAY)
8960
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
8961
          if (err == MP_OKAY)
8962
          #ifdef HAVE_CAVIUM_V
8963
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
8964
                    &key->pubkey.y->raw, &r->raw, &s->raw,
8965
                    &curve->prime->raw, &curve->order->raw, res);
8966
          #else
8967
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
8968
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
8969
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
8970
                    &curve->Gx->raw, &curve->Gy->raw, res);
8971
          #endif
8972
8973
      #ifndef HAVE_CAVIUM_V
8974
          mp_clear(e);
8975
      #endif
8976
8977
          return err;
8978
      }
8979
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8980
   }
8981
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8982
8983
0
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8984
#ifdef MP_INT_SIZE_CHECK_NULL
8985
   if (w == NULL) {
8986
       err = MEMORY_E;
8987
   }
8988
#endif
8989
8990
0
   if (err == MP_OKAY) {
8991
#ifdef WOLFSSL_CHECK_VER_FAULTS
8992
    #ifndef WOLFSSL_NO_MALLOC
8993
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8994
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8995
       if (u1 == NULL || u2 == NULL)
8996
            err = MEMORY_E;
8997
    #else
8998
        u1 = u1tmp;
8999
        u2 = u2tmp;
9000
    #endif
9001
#else
9002
0
       u1 = e;
9003
0
       u2 = w;
9004
0
#endif
9005
0
       v = w;
9006
0
   }
9007
0
   if (err == MP_OKAY) {
9008
0
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9009
0
   }
9010
#ifdef WOLFSSL_CHECK_VER_FAULTS
9011
   if (err == MP_OKAY) {
9012
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9013
   }
9014
   if (err == MP_OKAY) {
9015
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9016
   }
9017
#endif
9018
9019
   /* allocate points */
9020
0
   if (err == MP_OKAY) {
9021
   #ifdef WOLFSSL_NO_MALLOC
9022
       mG = &lcl_mG;
9023
   #endif
9024
0
       err = wc_ecc_new_point_ex(&mG, key->heap);
9025
0
   }
9026
0
   if (err == MP_OKAY) {
9027
   #ifdef WOLFSSL_NO_MALLOC
9028
       mQ = &lcl_mQ;
9029
   #endif
9030
0
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9031
0
   }
9032
9033
   /*  w  = s^-1 mod n */
9034
0
   if (err == MP_OKAY)
9035
0
       err = mp_invmod(s, curve->order, w);
9036
9037
   /* u1 = ew */
9038
0
   if (err == MP_OKAY)
9039
0
       err = mp_mulmod(e, w, curve->order, u1);
9040
9041
#ifdef WOLFSSL_CHECK_VER_FAULTS
9042
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9043
        err = BAD_STATE_E;
9044
    }
9045
#endif
9046
9047
   /* u2 = rw */
9048
0
   if (err == MP_OKAY)
9049
0
       err = mp_mulmod(r, w, curve->order, u2);
9050
9051
#ifdef WOLFSSL_CHECK_VER_FAULTS
9052
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9053
        err = BAD_STATE_E;
9054
    }
9055
#endif
9056
9057
   /* find mG and mQ */
9058
0
   if (err == MP_OKAY)
9059
0
       err = mp_copy(curve->Gx, mG->x);
9060
0
   if (err == MP_OKAY)
9061
0
       err = mp_copy(curve->Gy, mG->y);
9062
0
   if (err == MP_OKAY)
9063
0
       err = mp_set(mG->z, 1);
9064
9065
0
   if (err == MP_OKAY)
9066
0
       err = mp_copy(key->pubkey.x, mQ->x);
9067
0
   if (err == MP_OKAY)
9068
0
       err = mp_copy(key->pubkey.y, mQ->y);
9069
0
   if (err == MP_OKAY)
9070
0
       err = mp_copy(key->pubkey.z, mQ->z);
9071
9072
#if defined(FREESCALE_LTC_ECC)
9073
   /* use PKHA to compute u1*mG + u2*mQ */
9074
   if (err == MP_OKAY)
9075
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9076
   if (err == MP_OKAY)
9077
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9078
   if (err == MP_OKAY)
9079
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9080
#else
9081
#ifndef ECC_SHAMIR
9082
    if (err == MP_OKAY)
9083
    {
9084
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9085
        ecc_point mG1, mQ1;
9086
        wc_ecc_copy_point(mQ, &mQ1);
9087
        wc_ecc_copy_point(mG, &mG1);
9088
     #endif
9089
9090
        mp_digit mp = 0;
9091
9092
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9093
            /* compute u1*mG + u2*mQ = mG */
9094
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9095
                                                                     key->heap);
9096
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9097
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9098
                err = BAD_STATE_E;
9099
            }
9100
9101
            /* store new value for comparing with after add operation */
9102
           wc_ecc_copy_point(mG, &mG1);
9103
        #endif
9104
            if (err == MP_OKAY) {
9105
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9106
                                                                     key->heap);
9107
            }
9108
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9109
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9110
                err = BAD_STATE_E;
9111
            }
9112
        #endif
9113
9114
            /* find the montgomery mp */
9115
            if (err == MP_OKAY)
9116
                err = mp_montgomery_setup(curve->prime, &mp);
9117
9118
            /* add them */
9119
            if (err == MP_OKAY)
9120
                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
9121
                                                        curve->prime, mp, NULL);
9122
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9123
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9124
                err = BAD_STATE_E;
9125
            }
9126
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9127
                err = BAD_STATE_E;
9128
            }
9129
        #endif
9130
        }
9131
        else {
9132
            /* compute 0*mG + u2*mQ = mG */
9133
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9134
                                                                     key->heap);
9135
            /* find the montgomery mp */
9136
            if (err == MP_OKAY)
9137
                err = mp_montgomery_setup(curve->prime, &mp);
9138
        }
9139
9140
        /* reduce */
9141
        if (err == MP_OKAY)
9142
            err = ecc_map(mG, curve->prime, mp);
9143
    }
9144
#else
9145
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9146
0
    if (err == MP_OKAY) {
9147
0
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9148
0
                                                                     key->heap);
9149
0
    }
9150
0
#endif /* ECC_SHAMIR */
9151
0
#endif /* FREESCALE_LTC_ECC */
9152
9153
   /* v = X_x1 mod n */
9154
0
   if (err == MP_OKAY)
9155
0
       err = mp_mod(mG->x, curve->order, v);
9156
9157
   /* does v == r */
9158
0
   if (err == MP_OKAY) {
9159
0
       if (mp_cmp(v, r) == MP_EQ)
9160
0
           *res = 1;
9161
#ifdef WOLFSSL_CHECK_VER_FAULTS
9162
       /* redundant comparison as sanity check that first one happened */
9163
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9164
           *res = 0;
9165
#endif
9166
0
   }
9167
9168
   /* cleanup */
9169
0
   wc_ecc_del_point_ex(mG, key->heap);
9170
0
   wc_ecc_del_point_ex(mQ, key->heap);
9171
9172
0
   mp_clear(e);
9173
0
   mp_clear(w);
9174
0
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9175
#ifdef WOLFSSL_CHECK_VER_FAULTS
9176
   mp_clear(u1);
9177
   mp_clear(u2);
9178
#ifndef WOLFSSL_NO_MALLOC
9179
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9180
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9181
#endif
9182
#endif
9183
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9184
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9185
0
#endif
9186
9187
0
   return err;
9188
0
}
9189
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9190
#endif /* HAVE_ECC_VERIFY_HELPER */
9191
9192
/**
9193
   Verify an ECC signature
9194
   r           The signature R component to verify
9195
   s           The signature S component to verify
9196
   hash        The hash (message digest) that was signed
9197
   hashlen     The length of the hash (octets)
9198
   res         Result of signature, 1==valid, 0==invalid
9199
   key         The corresponding public ECC key
9200
   return      MP_OKAY if successful (even if the signature is not valid)
9201
               Caller should check the *res value to determine if the signature
9202
               is valid or invalid. Other negative values are returned on error.
9203
*/
9204
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9205
                    word32 hashlen, int* res, ecc_key* key)
9206
0
{
9207
#if defined(WOLFSSL_STM32_PKA)
9208
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9209
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9210
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9211
#else
9212
0
   int           err;
9213
0
   word32        keySz = 0;
9214
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9215
   byte sigRS[ATECC_KEY_SIZE*2];
9216
#elif defined(WOLFSSL_CRYPTOCELL)
9217
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9218
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9219
   word32 msgLenInBytes = hashlen;
9220
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9221
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9222
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9223
#elif defined(WOLFSSL_KCAPI_ECC)
9224
   byte sigRS[MAX_ECC_BYTES*2];
9225
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9226
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9227
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9228
#elif defined(WOLFSSL_SE050)
9229
#else
9230
0
   int curveLoaded = 0;
9231
0
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9232
0
#endif
9233
9234
0
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9235
0
       return ECC_BAD_ARG_E;
9236
9237
   /* default to invalid signature */
9238
0
   *res = 0;
9239
9240
   /* is the IDX valid ?  */
9241
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9242
0
      return ECC_BAD_ARG_E;
9243
0
   }
9244
9245
0
   err = wc_ecc_check_r_s_range(key, r, s);
9246
0
   if (err != MP_OKAY) {
9247
0
      return err;
9248
0
   }
9249
9250
0
   keySz = (word32)key->dp->size;
9251
9252
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9253
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9254
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9255
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9256
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9257
            sw->eccVerify.r = r;
9258
            sw->eccVerify.s = s;
9259
            sw->eccVerify.hash = hash;
9260
            sw->eccVerify.hashlen = hashlen;
9261
            sw->eccVerify.stat = res;
9262
            sw->eccVerify.key = key;
9263
            return WC_PENDING_E;
9264
        }
9265
    }
9266
#endif
9267
9268
#ifndef HAVE_ECC_VERIFY_HELPER
9269
9270
#ifndef WOLFSSL_SE050
9271
    /* Extract R and S with front zero padding (if required),
9272
     * SE050 does this in port layer  */
9273
    XMEMSET(sigRS, 0, sizeof(sigRS));
9274
    err = mp_to_unsigned_bin(r, sigRS +
9275
                                (keySz - mp_unsigned_bin_size(r)));
9276
    if (err != MP_OKAY) {
9277
        return err;
9278
    }
9279
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9280
                                (keySz - mp_unsigned_bin_size(s)));
9281
    if (err != MP_OKAY) {
9282
        return err;
9283
    }
9284
#endif /* WOLFSSL_SE050 */
9285
9286
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9287
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9288
    if (err != 0) {
9289
       return err;
9290
    }
9291
    (void)hashlen;
9292
#elif defined(WOLFSSL_CRYPTOCELL)
9293
9294
   /* truncate if hash is longer than key size */
9295
   if (msgLenInBytes > keySz) {
9296
       msgLenInBytes = keySz;
9297
   }
9298
   hash_mode = cc310_hashModeECC(msgLenInBytes);
9299
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
9300
       /* hash_mode = */ cc310_hashModeECC(keySz);
9301
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
9302
   }
9303
9304
   /* verify the signature using the public key */
9305
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
9306
                           &key->ctx.pubKey,
9307
                           hash_mode,
9308
                           &sigRS[0],
9309
                           keySz*2,
9310
                           (byte*)hash,
9311
                           msgLenInBytes);
9312
9313
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
9314
       /* signature verification reported invalid signature. */
9315
       *res = 0; /* Redundant, added for code clarity */
9316
       err = MP_OKAY;
9317
   }
9318
   else if (err != SA_SILIB_RET_OK) {
9319
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
9320
       return err;
9321
   }
9322
   else {
9323
       /* valid signature. */
9324
       *res = 1;
9325
       err = MP_OKAY;
9326
   }
9327
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9328
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
9329
                                hash, hashlen,
9330
                                res, key);
9331
#elif defined(WOLFSSL_KCAPI_ECC)
9332
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
9333
    if (err == 0) {
9334
        *res = 1;
9335
    }
9336
#elif defined(WOLFSSL_SE050)
9337
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9338
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9339
    if (hashlen > sizeof(hashcopy))
9340
        return ECC_BAD_ARG_E;
9341
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
9342
    mp_reverse(sigRS, keySz);
9343
    mp_reverse(sigRS + keySz, keySz);
9344
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
9345
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
9346
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
9347
9348
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
9349
                                     xil_curve_type[key->dp->id],
9350
                                     XIL_CAST_U64(hashcopy), keySz,
9351
                                     XIL_CAST_U64(key->keyRaw),
9352
                                     XIL_CAST_U64(sigRS));
9353
9354
    if (err != XST_SUCCESS) {
9355
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
9356
        err = WC_HW_E;
9357
    } else {
9358
        *res = 1;
9359
    }
9360
#endif
9361
9362
#else
9363
  /* checking if private key with no public part */
9364
0
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9365
0
      WOLFSSL_MSG("Verify called with private key, generating public part");
9366
0
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9367
0
      if (err != MP_OKAY) {
9368
0
          return err;
9369
0
      }
9370
0
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9371
0
      if (err != MP_OKAY) {
9372
0
          FREE_CURVE_SPECS();
9373
0
          return err;
9374
0
      }
9375
0
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9376
0
      if (err != MP_OKAY) {
9377
0
           WOLFSSL_MSG("Unable to extract public key");
9378
0
           wc_ecc_curve_free(curve);
9379
0
           FREE_CURVE_SPECS();
9380
0
           return err;
9381
0
      }
9382
0
      curveLoaded = 1;
9383
0
  }
9384
9385
0
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9386
0
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
9387
0
      if (curveLoaded) {
9388
0
           wc_ecc_curve_free(curve);
9389
0
           FREE_CURVE_SPECS();
9390
0
      }
9391
0
      return err;
9392
0
  }
9393
9394
0
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9395
0
   if (!curveLoaded) {
9396
0
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9397
0
       if (err != 0) {
9398
0
          return err;
9399
0
       }
9400
       /* read in the specs for this curve */
9401
0
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9402
0
       if (err != 0) {
9403
0
          FREE_CURVE_SPECS();
9404
0
          return err;
9405
0
       }
9406
0
   }
9407
9408
0
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9409
0
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9410
9411
0
   (void)curveLoaded;
9412
0
   wc_ecc_curve_free(curve);
9413
0
   FREE_CURVE_SPECS();
9414
0
#endif /* HAVE_ECC_VERIFY_HELPER */
9415
9416
0
   (void)keySz;
9417
0
   (void)hashlen;
9418
9419
0
   return err;
9420
0
#endif /* WOLFSSL_STM32_PKA */
9421
0
}
9422
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
9423
#endif /* HAVE_ECC_VERIFY */
9424
9425
#ifdef HAVE_ECC_KEY_IMPORT
9426
/* import point from der
9427
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
9428
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
9429
                               const int curve_idx, ecc_point* point,
9430
                               int shortKeySize)
9431
0
{
9432
0
    int err = 0;
9433
#ifdef HAVE_COMP_KEY
9434
    int compressed = 0;
9435
#endif
9436
0
    int keysize;
9437
0
    byte pointType;
9438
9439
0
#ifndef HAVE_COMP_KEY
9440
0
    (void)shortKeySize;
9441
0
#endif
9442
9443
0
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9444
0
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9445
0
        return ECC_BAD_ARG_E;
9446
9447
    /* must be odd */
9448
0
    if ((inLen & 1) == 0) {
9449
0
        return ECC_BAD_ARG_E;
9450
0
    }
9451
9452
    /* clear if previously allocated */
9453
0
    mp_clear(point->x);
9454
0
    mp_clear(point->y);
9455
0
    mp_clear(point->z);
9456
9457
    /* init point */
9458
#ifdef ALT_ECC_SIZE
9459
    point->x = (mp_int*)&point->xyz[0];
9460
    point->y = (mp_int*)&point->xyz[1];
9461
    point->z = (mp_int*)&point->xyz[2];
9462
    alt_fp_init(point->x);
9463
    alt_fp_init(point->y);
9464
    alt_fp_init(point->z);
9465
#else
9466
0
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9467
0
#endif
9468
0
    if (err != MP_OKAY)
9469
0
        return MEMORY_E;
9470
9471
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9472
9473
    /* check for point type (4, 2, or 3) */
9474
0
    pointType = in[0];
9475
0
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9476
0
                                         pointType != ECC_POINT_COMP_ODD) {
9477
0
        err = ASN_PARSE_E;
9478
0
    }
9479
9480
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9481
#ifdef HAVE_COMP_KEY
9482
        compressed = 1;
9483
#else
9484
0
        err = NOT_COMPILED_IN;
9485
0
#endif
9486
0
    }
9487
9488
    /* adjust to skip first byte */
9489
0
    inLen -= 1;
9490
0
    in += 1;
9491
9492
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9493
     * is true */
9494
#ifdef HAVE_COMP_KEY
9495
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9496
#else
9497
0
    keysize = (int)(inLen>>1);
9498
0
#endif
9499
9500
    /* read data */
9501
0
    if (err == MP_OKAY)
9502
0
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9503
9504
#ifdef HAVE_COMP_KEY
9505
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9506
    #if defined(WOLFSSL_HAVE_SP_ECC)
9507
        #ifndef WOLFSSL_SP_NO_256
9508
        if (curve_idx != ECC_CUSTOM_IDX &&
9509
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
9510
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
9511
        }
9512
        else
9513
        #endif
9514
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9515
        if (curve_idx != ECC_CUSTOM_IDX &&
9516
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
9517
            sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
9518
        }
9519
        else
9520
        #endif
9521
        #ifdef WOLFSSL_SP_384
9522
        if (curve_idx != ECC_CUSTOM_IDX &&
9523
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
9524
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
9525
        }
9526
        else
9527
        #endif
9528
        #ifdef WOLFSSL_SP_521
9529
        if (curve_idx != ECC_CUSTOM_IDX &&
9530
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
9531
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
9532
        }
9533
        else
9534
        #endif
9535
    #endif
9536
    #if !defined(WOLFSSL_SP_MATH)
9537
        {
9538
            int did_init = 0;
9539
        #ifdef WOLFSSL_SMALL_STACK
9540
            mp_int* t1 = NULL;
9541
            mp_int* t2 = NULL;
9542
        #else
9543
            mp_int t1[1], t2[1];
9544
        #endif
9545
            DECLARE_CURVE_SPECS(3);
9546
9547
            ALLOC_CURVE_SPECS(3, err);
9548
9549
        #ifdef WOLFSSL_SMALL_STACK
9550
            if (err == MP_OKAY) {
9551
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9552
                                      DYNAMIC_TYPE_BIGINT);
9553
                if (t1 == NULL) {
9554
                    err = MEMORY_E;
9555
                }
9556
            }
9557
            if (err == MP_OKAY) {
9558
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9559
                                      DYNAMIC_TYPE_BIGINT);
9560
                if (t2 == NULL) {
9561
                    err = MEMORY_E;
9562
                }
9563
            }
9564
        #endif
9565
9566
            if (err == MP_OKAY) {
9567
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9568
                    err = MEMORY_E;
9569
                else
9570
                    did_init = 1;
9571
            }
9572
9573
            /* load curve info */
9574
            if (err == MP_OKAY)
9575
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9576
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9577
                        ECC_CURVE_FIELD_BF));
9578
9579
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
9580
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
9581
            /* validate prime is prime for custom curves */
9582
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
9583
                int isPrime = MP_NO;
9584
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
9585
                if (err == MP_OKAY && isPrime == MP_NO)
9586
                    err = MP_VAL;
9587
            }
9588
        #endif
9589
9590
            /* compute x^3 */
9591
            if (err == MP_OKAY)
9592
                err = mp_sqr(point->x, t1);
9593
            if (err == MP_OKAY)
9594
                err = mp_mulmod(t1, point->x, curve->prime, t1);
9595
9596
            /* compute x^3 + a*x */
9597
            if (err == MP_OKAY)
9598
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
9599
            if (err == MP_OKAY)
9600
                err = mp_add(t1, t2, t1);
9601
9602
            /* compute x^3 + a*x + b */
9603
            if (err == MP_OKAY)
9604
                err = mp_add(t1, curve->Bf, t1);
9605
9606
            /* compute sqrt(x^3 + a*x + b) */
9607
            if (err == MP_OKAY)
9608
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
9609
9610
            /* adjust y */
9611
            if (err == MP_OKAY) {
9612
                if ((mp_isodd(t2) == MP_YES &&
9613
                                            pointType == ECC_POINT_COMP_ODD) ||
9614
                    (mp_isodd(t2) == MP_NO &&
9615
                                            pointType == ECC_POINT_COMP_EVEN)) {
9616
                    err = mp_mod(t2, curve->prime, point->y);
9617
                }
9618
                else {
9619
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
9620
                }
9621
            }
9622
9623
            if (did_init) {
9624
                mp_clear(t2);
9625
                mp_clear(t1);
9626
            }
9627
9628
        #ifdef WOLFSSL_SMALL_STACK
9629
            XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
9630
            XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
9631
        #endif
9632
9633
            wc_ecc_curve_free(curve);
9634
            FREE_CURVE_SPECS();
9635
        }
9636
    #else
9637
        {
9638
            err = WC_KEY_SIZE_E;
9639
        }
9640
    #endif
9641
    }
9642
#endif
9643
9644
0
    if (err == MP_OKAY) {
9645
#ifdef HAVE_COMP_KEY
9646
        if (compressed == 0)
9647
#endif
9648
0
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9649
0
    }
9650
0
    if (err == MP_OKAY)
9651
0
        err = mp_set(point->z, 1);
9652
9653
0
    if (err != MP_OKAY) {
9654
0
        mp_clear(point->x);
9655
0
        mp_clear(point->y);
9656
0
        mp_clear(point->z);
9657
0
    }
9658
9659
0
    RESTORE_VECTOR_REGISTERS();
9660
9661
0
    return err;
9662
0
}
9663
9664
/* function for backwards compatibility with previous implementations */
9665
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
9666
                            ecc_point* point)
9667
0
{
9668
0
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9669
0
}
9670
#endif /* HAVE_ECC_KEY_IMPORT */
9671
9672
#ifdef HAVE_ECC_KEY_EXPORT
9673
/* export point to der */
9674
9675
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
9676
                               word32* outLen, int compressed)
9677
0
{
9678
0
    if (compressed == 0)
9679
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
9680
#ifdef HAVE_COMP_KEY
9681
    else
9682
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
9683
#else
9684
0
    return NOT_COMPILED_IN;
9685
0
#endif
9686
0
}
9687
9688
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
9689
                            word32* outLen)
9690
0
{
9691
0
    int    ret = MP_OKAY;
9692
0
    word32 numlen;
9693
#ifdef WOLFSSL_SMALL_STACK
9694
    byte*  buf;
9695
#else
9696
0
    byte   buf[ECC_BUFSIZE];
9697
0
#endif
9698
9699
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9700
0
        return ECC_BAD_ARG_E;
9701
9702
0
    numlen = (word32)ecc_sets[curve_idx].size;
9703
9704
    /* return length needed only */
9705
0
    if (point != NULL && out == NULL && outLen != NULL) {
9706
0
        *outLen = 1 + 2*numlen;
9707
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9708
0
    }
9709
9710
0
    if (point == NULL || out == NULL || outLen == NULL)
9711
0
        return ECC_BAD_ARG_E;
9712
9713
0
    if (*outLen < (1 + 2*numlen)) {
9714
0
        *outLen = 1 + 2*numlen;
9715
0
        return BUFFER_E;
9716
0
    }
9717
9718
    /* Sanity check the ordinates' sizes. */
9719
0
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9720
0
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9721
0
        return ECC_BAD_ARG_E;
9722
0
    }
9723
9724
    /* store byte point type */
9725
0
    out[0] = ECC_POINT_UNCOMP;
9726
9727
#ifdef WOLFSSL_SMALL_STACK
9728
    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9729
    if (buf == NULL)
9730
        return MEMORY_E;
9731
#endif
9732
9733
    /* pad and store x */
9734
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9735
0
    ret = mp_to_unsigned_bin(point->x, buf +
9736
0
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9737
0
    if (ret != MP_OKAY)
9738
0
        goto done;
9739
0
    XMEMCPY(out+1, buf, numlen);
9740
9741
    /* pad and store y */
9742
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9743
0
    ret = mp_to_unsigned_bin(point->y, buf +
9744
0
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9745
0
    if (ret != MP_OKAY)
9746
0
        goto done;
9747
0
    XMEMCPY(out+1+numlen, buf, numlen);
9748
9749
0
    *outLen = 1 + 2*numlen;
9750
9751
0
done:
9752
#ifdef WOLFSSL_SMALL_STACK
9753
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9754
#endif
9755
9756
0
    return ret;
9757
0
}
9758
9759
9760
/* export point to der */
9761
#ifdef HAVE_COMP_KEY
9762
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
9763
                                       byte* out, word32* outLen)
9764
{
9765
    int    ret = MP_OKAY;
9766
    word32 numlen;
9767
    word32 output_len;
9768
#ifdef WOLFSSL_SMALL_STACK
9769
    byte*  buf;
9770
#else
9771
    byte   buf[ECC_BUFSIZE];
9772
#endif
9773
9774
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9775
        return ECC_BAD_ARG_E;
9776
9777
    numlen = (word32)ecc_sets[curve_idx].size;
9778
    output_len = 1 + numlen; /* y point type + x */
9779
9780
    /* return length needed only */
9781
    if (point != NULL && out == NULL && outLen != NULL) {
9782
        *outLen = output_len;
9783
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9784
    }
9785
9786
    if (point == NULL || out == NULL || outLen == NULL)
9787
        return ECC_BAD_ARG_E;
9788
9789
9790
    if (*outLen < output_len) {
9791
        *outLen = output_len;
9792
        return BUFFER_E;
9793
    }
9794
9795
    /* Sanity check the ordinate's size. */
9796
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
9797
        return ECC_BAD_ARG_E;
9798
    }
9799
9800
    /* store byte point type */
9801
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
9802
                                            ECC_POINT_COMP_EVEN;
9803
9804
#ifdef WOLFSSL_SMALL_STACK
9805
    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9806
    if (buf == NULL)
9807
        return MEMORY_E;
9808
#endif
9809
9810
    /* pad and store x */
9811
    XMEMSET(buf, 0, ECC_BUFSIZE);
9812
    ret = mp_to_unsigned_bin(point->x, buf +
9813
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
9814
    if (ret != MP_OKAY)
9815
        goto done;
9816
    XMEMCPY(out+1, buf, numlen);
9817
9818
    *outLen = output_len;
9819
9820
done:
9821
#ifdef WOLFSSL_SMALL_STACK
9822
    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9823
#endif
9824
9825
    return ret;
9826
}
9827
#endif /* HAVE_COMP_KEY */
9828
9829
/* export public ECC key in ANSI X9.63 format */
9830
WOLFSSL_ABI
9831
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
9832
0
{
9833
0
   int    ret = MP_OKAY;
9834
0
   word32 numlen;
9835
#ifdef WOLFSSL_SMALL_STACK
9836
   byte*  buf;
9837
#else
9838
0
   byte   buf[ECC_BUFSIZE];
9839
0
#endif
9840
0
   word32 pubxlen, pubylen;
9841
9842
   /* return length needed only */
9843
0
   if (key != NULL && out == NULL && outLen != NULL) {
9844
      /* if key hasn't been setup assume max bytes for size estimation */
9845
0
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9846
0
      *outLen = 1 + 2 * numlen;
9847
0
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9848
0
   }
9849
9850
0
   if (key == NULL || out == NULL || outLen == NULL)
9851
0
      return ECC_BAD_ARG_E;
9852
9853
0
   if (key->type == ECC_PRIVATEKEY_ONLY)
9854
0
       return ECC_PRIVATEONLY_E;
9855
9856
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
9857
    /* check if public key in secure memory */
9858
    if (key->securePubKey > 0) {
9859
        int keySz = wc_ecc_size(key);
9860
9861
        /* store byte point type */
9862
        out[0] = ECC_POINT_UNCOMP;
9863
9864
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
9865
            return WC_HW_E;
9866
9867
        *outLen = 1 + 2*keySz;
9868
        return MP_OKAY;
9869
    }
9870
#endif
9871
9872
0
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9873
0
       return ECC_BAD_ARG_E;
9874
0
   }
9875
9876
0
   numlen = (word32)key->dp->size;
9877
9878
    /* verify room in out buffer */
9879
0
   if (*outLen < (1 + 2*numlen)) {
9880
0
      *outLen = 1 + 2*numlen;
9881
0
      return BUFFER_E;
9882
0
   }
9883
9884
   /* verify public key length is less than key size */
9885
0
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9886
0
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9887
0
   if ((pubxlen > numlen) || (pubylen > numlen)) {
9888
0
      WOLFSSL_MSG("Public key x/y invalid!");
9889
0
      return BUFFER_E;
9890
0
   }
9891
9892
   /* store byte point type */
9893
0
   out[0] = ECC_POINT_UNCOMP;
9894
9895
#ifdef WOLFSSL_SMALL_STACK
9896
   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9897
   if (buf == NULL)
9898
      return MEMORY_E;
9899
#endif
9900
9901
   /* pad and store x */
9902
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
9903
0
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9904
0
   if (ret != MP_OKAY)
9905
0
      goto done;
9906
0
   XMEMCPY(out+1, buf, numlen);
9907
9908
   /* pad and store y */
9909
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
9910
0
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9911
0
   if (ret != MP_OKAY)
9912
0
      goto done;
9913
0
   XMEMCPY(out+1+numlen, buf, numlen);
9914
9915
0
   *outLen = 1 + 2*numlen;
9916
9917
0
done:
9918
#ifdef WOLFSSL_SMALL_STACK
9919
   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9920
#endif
9921
9922
0
   return ret;
9923
0
}
9924
9925
9926
/* export public ECC key in ANSI X9.63 format, extended with
9927
 * compression option */
9928
WOLFSSL_ABI
9929
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
9930
                          int compressed)
9931
0
{
9932
0
    if (compressed == 0)
9933
0
        return wc_ecc_export_x963(key, out, outLen);
9934
#ifdef HAVE_COMP_KEY
9935
    else
9936
        return wc_ecc_export_x963_compressed(key, out, outLen);
9937
#else
9938
0
    return NOT_COMPILED_IN;
9939
0
#endif
9940
0
}
9941
#endif /* HAVE_ECC_KEY_EXPORT */
9942
9943
9944
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
9945
9946
/* is ecc point on curve described by dp ? */
9947
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
9948
0
{
9949
0
#if !defined(WOLFSSL_SP_MATH)
9950
0
   int err;
9951
#ifdef WOLFSSL_SMALL_STACK
9952
   mp_int* t1;
9953
   mp_int* t2;
9954
#else
9955
0
   mp_int  t1[1], t2[1];
9956
0
#endif
9957
9958
#ifdef WOLFSSL_SMALL_STACK
9959
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9960
   if (t1 == NULL)
9961
       return MEMORY_E;
9962
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9963
   if (t2 == NULL) {
9964
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9965
       return MEMORY_E;
9966
   }
9967
#endif
9968
9969
0
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
9970
   #ifdef WOLFSSL_SMALL_STACK
9971
      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
9972
      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9973
   #endif
9974
0
      return err;
9975
0
   }
9976
9977
0
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9978
9979
   /* compute y^2 */
9980
0
   if (err == MP_OKAY)
9981
0
       err = mp_sqr(ecp->y, t1);
9982
9983
   /* compute x^3 */
9984
0
   if (err == MP_OKAY)
9985
0
       err = mp_sqr(ecp->x, t2);
9986
0
   if (err == MP_OKAY)
9987
0
       err = mp_mod(t2, prime, t2);
9988
0
   if (err == MP_OKAY)
9989
0
       err = mp_mul(ecp->x, t2, t2);
9990
9991
   /* compute y^2 - x^3 */
9992
0
   if (err == MP_OKAY)
9993
0
       err = mp_submod(t1, t2, prime, t1);
9994
9995
   /* Determine if curve "a" should be used in calc */
9996
#ifdef WOLFSSL_CUSTOM_CURVES
9997
   if (err == MP_OKAY) {
9998
      /* Use a and prime to determine if a == 3 */
9999
      err = mp_set(t2, 0);
10000
      if (err == MP_OKAY)
10001
          err = mp_submod(prime, a, prime, t2);
10002
   }
10003
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
10004
      /* compute y^2 - x^3 + a*x */
10005
      if (err == MP_OKAY)
10006
          err = mp_mulmod(t2, ecp->x, prime, t2);
10007
      if (err == MP_OKAY)
10008
          err = mp_addmod(t1, t2, prime, t1);
10009
   }
10010
   else
10011
#endif /* WOLFSSL_CUSTOM_CURVES */
10012
0
   {
10013
      /* assumes "a" == 3 */
10014
0
      (void)a;
10015
10016
      /* compute y^2 - x^3 + 3x */
10017
0
      if (err == MP_OKAY)
10018
0
          err = mp_add(t1, ecp->x, t1);
10019
0
      if (err == MP_OKAY)
10020
0
          err = mp_add(t1, ecp->x, t1);
10021
0
      if (err == MP_OKAY)
10022
0
          err = mp_add(t1, ecp->x, t1);
10023
0
      if (err == MP_OKAY)
10024
0
          err = mp_mod(t1, prime, t1);
10025
0
  }
10026
10027
   /* adjust range (0, prime) */
10028
0
   while (err == MP_OKAY && mp_isneg(t1)) {
10029
0
      err = mp_add(t1, prime, t1);
10030
0
   }
10031
0
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
10032
0
      err = mp_sub(t1, prime, t1);
10033
0
   }
10034
10035
   /* compare to b */
10036
0
   if (err == MP_OKAY) {
10037
0
       if (mp_cmp(t1, b) != MP_EQ) {
10038
0
          err = IS_POINT_E;
10039
0
       } else {
10040
0
          err = MP_OKAY;
10041
0
       }
10042
0
   }
10043
10044
0
   mp_clear(t1);
10045
0
   mp_clear(t2);
10046
10047
0
   RESTORE_VECTOR_REGISTERS();
10048
10049
#ifdef WOLFSSL_SMALL_STACK
10050
   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
10051
   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
10052
#endif
10053
10054
0
   return err;
10055
#else
10056
   (void)a;
10057
   (void)b;
10058
10059
#ifdef WOLFSSL_HAVE_SP_ECC
10060
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10061
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10062
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10063
   }
10064
#endif
10065
#ifndef WOLFSSL_SP_NO_256
10066
   if (mp_count_bits(prime) == 256) {
10067
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10068
   }
10069
#endif
10070
#ifdef WOLFSSL_SP_384
10071
   if (mp_count_bits(prime) == 384) {
10072
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10073
   }
10074
#endif
10075
#ifdef WOLFSSL_SP_521
10076
   if (mp_count_bits(prime) == 521) {
10077
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10078
   }
10079
#endif
10080
#else
10081
   (void)ecp;
10082
   (void)prime;
10083
#endif
10084
   return WC_KEY_SIZE_E;
10085
#endif
10086
0
}
10087
10088
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10089
0
{
10090
0
    int err = MP_OKAY;
10091
10092
    /* Validate parameters. */
10093
0
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10094
0
        err = BAD_FUNC_ARG;
10095
0
    }
10096
10097
0
    if (err == MP_OKAY) {
10098
        /* x must be in the range [0, p-1] */
10099
0
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10100
0
            err = ECC_OUT_OF_RANGE_E;
10101
0
        }
10102
0
    }
10103
10104
0
    if (err == MP_OKAY) {
10105
        /* y must be in the range [0, p-1] */
10106
0
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10107
0
            err = ECC_OUT_OF_RANGE_E;
10108
0
        }
10109
0
    }
10110
10111
0
    if (err == MP_OKAY) {
10112
        /* z must be one, that is point must be in affine form. */
10113
0
        if (!mp_isone(ecp->z)) {
10114
0
            err = ECC_BAD_ARG_E;
10115
0
        }
10116
0
    }
10117
10118
0
    if (err == MP_OKAY) {
10119
        /* Check x and y are valid for curve equation. */
10120
0
        err = _ecc_is_point(ecp, a, b, prime);
10121
0
    }
10122
10123
0
    return err;
10124
0
}
10125
10126
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10127
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10128
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10129
/* validate privkey * generator == pubkey, 0 on success */
10130
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10131
{
10132
    int        err;
10133
    ecc_point* base = NULL;
10134
    ecc_point* res  = NULL;
10135
#ifdef WOLFSSL_NO_MALLOC
10136
    ecc_point lcl_base;
10137
    ecc_point lcl_res;
10138
#endif
10139
    DECLARE_CURVE_SPECS(3);
10140
10141
    if (key == NULL)
10142
        return BAD_FUNC_ARG;
10143
10144
    ALLOC_CURVE_SPECS(3, err);
10145
    if (err != MP_OKAY) {
10146
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10147
        return err;
10148
    }
10149
10150
#ifdef WOLFSSL_NO_MALLOC
10151
    res = &lcl_res;
10152
#endif
10153
    err = wc_ecc_new_point_ex(&res, key->heap);
10154
10155
#ifdef WOLFSSL_HAVE_SP_ECC
10156
#ifndef WOLFSSL_SP_NO_256
10157
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10158
        if (err == MP_OKAY) {
10159
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10160
        }
10161
    }
10162
    else
10163
#endif
10164
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10165
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10166
        if (err == MP_OKAY) {
10167
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10168
        }
10169
    }
10170
    else
10171
#endif
10172
#ifdef WOLFSSL_SP_384
10173
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10174
        if (err == MP_OKAY) {
10175
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10176
        }
10177
    }
10178
    else
10179
#endif
10180
#ifdef WOLFSSL_SP_521
10181
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10182
        if (err == MP_OKAY) {
10183
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10184
        }
10185
    }
10186
    else
10187
#endif
10188
#endif
10189
    {
10190
        if (err == MP_OKAY) {
10191
        #ifdef WOLFSSL_NO_MALLOC
10192
            base = &lcl_base;
10193
        #endif
10194
            err = wc_ecc_new_point_ex(&base, key->heap);
10195
        }
10196
10197
        if (err == MP_OKAY) {
10198
            /* load curve info */
10199
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10200
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10201
        }
10202
10203
        /* set up base generator */
10204
        if (err == MP_OKAY)
10205
            err = mp_copy(curve->Gx, base->x);
10206
        if (err == MP_OKAY)
10207
            err = mp_copy(curve->Gy, base->y);
10208
        if (err == MP_OKAY)
10209
            err = mp_set(base->z, 1);
10210
10211
#ifdef WOLFSSL_KCAPI_ECC
10212
        if (err == MP_OKAY) {
10213
            word32 pubkey_sz = (word32)key->dp->size*2;
10214
            if (key->handle == NULL) {
10215
                /* if handle loaded, then pubkey_raw already populated */
10216
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10217
            }
10218
            if (err == 0) {
10219
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10220
                                           pubkey_sz/2);
10221
            }
10222
            if (err == MP_OKAY) {
10223
                err = mp_read_unsigned_bin(res->y,
10224
                                           key->pubkey_raw + pubkey_sz/2,
10225
                                           pubkey_sz/2);
10226
            }
10227
            if (err == MP_OKAY) {
10228
                err = mp_set(res->z, 1);
10229
            }
10230
        }
10231
        (void)a;
10232
        (void)prime;
10233
#else
10234
#ifdef ECC_TIMING_RESISTANT
10235
        if (err == MP_OKAY)
10236
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10237
                                          curve->order, key->rng, 1, key->heap);
10238
#else
10239
        if (err == MP_OKAY)
10240
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10241
                                              curve->order, NULL, 1, key->heap);
10242
#endif
10243
#endif /* WOLFSSL_KCAPI_ECC */
10244
    }
10245
10246
    if (err == MP_OKAY) {
10247
        /* compare result to public key */
10248
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10249
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10250
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10251
            /* didn't match */
10252
            err = ECC_PRIV_KEY_E;
10253
        }
10254
    }
10255
10256
    wc_ecc_curve_free(curve);
10257
    wc_ecc_del_point_ex(res, key->heap);
10258
    wc_ecc_del_point_ex(base, key->heap);
10259
    FREE_CURVE_SPECS();
10260
10261
    return err;
10262
}
10263
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10264
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10265
10266
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10267
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10268
10269
/* check privkey generator helper, creates prime needed */
10270
static int ecc_check_privkey_gen_helper(ecc_key* key)
10271
{
10272
    int    err;
10273
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
10274
    DECLARE_CURVE_SPECS(2);
10275
#endif
10276
10277
    if (key == NULL)
10278
        return BAD_FUNC_ARG;
10279
10280
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10281
    /* Hardware based private key, so this operation is not supported */
10282
    err = MP_OKAY; /* just report success */
10283
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10284
    /* Hardware based private key, so this operation is not supported */
10285
    err = MP_OKAY; /* just report success */
10286
#elif defined(WOLFSSL_KCAPI_ECC)
10287
    /* Hardware based private key, so this operation is not supported */
10288
    err = MP_OKAY; /* just report success */
10289
#else
10290
    ALLOC_CURVE_SPECS(2, err);
10291
10292
    /* load curve info */
10293
    if (err == MP_OKAY)
10294
        err = wc_ecc_curve_load(key->dp, &curve,
10295
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10296
10297
    if (err == MP_OKAY)
10298
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10299
10300
    wc_ecc_curve_free(curve);
10301
    FREE_CURVE_SPECS();
10302
10303
#endif /* WOLFSSL_ATECC508A */
10304
10305
    return err;
10306
}
10307
10308
/* Performs a Pairwise Consistency Test on an ECC key pair. */
10309
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10310
{
10311
    int err = 0;
10312
    word32 flags = key->flags;
10313
10314
    /* If flags not set default to cofactor and dec/sign */
10315
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10316
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10317
    }
10318
10319
    if (flags & WC_ECC_FLAG_COFACTOR) {
10320
        err = ecc_check_privkey_gen_helper(key);
10321
    }
10322
10323
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10324
#ifndef WOLFSSL_SMALL_STACK
10325
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10326
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10327
#else
10328
        byte* sig;
10329
#endif
10330
        byte* digest;
10331
        word32 sigLen, digestLen;
10332
        int dynRng = 0, res = 0;
10333
10334
        sigLen = (word32)wc_ecc_sig_size(key);
10335
        digestLen = WC_SHA256_DIGEST_SIZE;
10336
#ifdef WOLFSSL_SMALL_STACK
10337
        sig = (byte*)XMALLOC(sigLen + digestLen, key->heap, DYNAMIC_TYPE_ECC);
10338
        if (sig == NULL)
10339
            return MEMORY_E;
10340
#endif
10341
        digest = sig + sigLen;
10342
10343
        if (rng == NULL) {
10344
            dynRng = 1;
10345
            rng = wc_rng_new(NULL, 0, key->heap);
10346
            if (rng == NULL) {
10347
#ifdef WOLFSSL_SMALL_STACK
10348
                XFREE(sig, key->heap, DYNAMIC_TYPE_ECC);
10349
#endif
10350
                return MEMORY_E;
10351
            }
10352
        }
10353
10354
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10355
10356
        if (!err)
10357
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10358
                    rng, key);
10359
        if (!err)
10360
            err = wc_ecc_verify_hash(sig, sigLen,
10361
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10362
10363
        if (res == 0)
10364
            err = ECC_PCT_E;
10365
10366
        if (dynRng) {
10367
            wc_rng_free(rng);
10368
        }
10369
        ForceZero(sig, sigLen + digestLen);
10370
#ifdef WOLFSSL_SMALL_STACK
10371
        XFREE(sig, key->heap, DYNAMIC_TYPE_ECC);
10372
#endif
10373
    }
10374
    (void)rng;
10375
10376
    if (err != 0)
10377
        err = ECC_PCT_E;
10378
10379
    return err;
10380
}
10381
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10382
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10383
10384
#ifndef WOLFSSL_SP_MATH
10385
/* validate order * pubkey = point at infinity, 0 on success */
10386
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10387
        mp_int* prime, mp_int* order)
10388
0
{
10389
0
    ecc_point* inf = NULL;
10390
#ifdef WOLFSSL_NO_MALLOC
10391
    ecc_point  lcl_inf;
10392
#endif
10393
0
    int err;
10394
10395
0
    if (key == NULL)
10396
0
        return BAD_FUNC_ARG;
10397
0
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10398
0
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10399
0
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10400
0
       return IS_POINT_E;
10401
0
   }
10402
10403
#ifdef WOLFSSL_NO_MALLOC
10404
    inf = &lcl_inf;
10405
#endif
10406
0
    err = wc_ecc_new_point_ex(&inf, key->heap);
10407
0
    if (err == MP_OKAY) {
10408
#ifdef WOLFSSL_HAVE_SP_ECC
10409
#ifndef WOLFSSL_SP_NO_256
10410
        if (key->idx != ECC_CUSTOM_IDX &&
10411
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
10412
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
10413
        }
10414
        else
10415
#endif
10416
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10417
        if (key->idx != ECC_CUSTOM_IDX &&
10418
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
10419
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
10420
        }
10421
        else
10422
#endif
10423
#ifdef WOLFSSL_SP_384
10424
        if (key->idx != ECC_CUSTOM_IDX &&
10425
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
10426
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
10427
        }
10428
        else
10429
#endif
10430
#ifdef WOLFSSL_SP_521
10431
        if (key->idx != ECC_CUSTOM_IDX &&
10432
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
10433
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
10434
        }
10435
        else
10436
#endif
10437
#endif
10438
0
#if !defined(WOLFSSL_SP_MATH)
10439
0
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10440
0
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10441
0
            err = ECC_INF_E;
10442
#else
10443
        {
10444
            (void)a;
10445
            (void)prime;
10446
10447
            err = WC_KEY_SIZE_E;
10448
        }
10449
#endif
10450
0
    }
10451
10452
0
    wc_ecc_del_point_ex(inf, key->heap);
10453
10454
0
    return err;
10455
0
}
10456
#endif /* !WOLFSSL_SP_MATH */
10457
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10458
10459
10460
#ifdef OPENSSL_EXTRA
10461
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
10462
{
10463
    int err = MP_OKAY;
10464
    DECLARE_CURVE_SPECS(2);
10465
10466
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
10467
        return BAD_FUNC_ARG;
10468
10469
    ALLOC_CURVE_SPECS(2, err);
10470
10471
    if (err == MP_OKAY)
10472
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10473
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
10474
    if (err == MP_OKAY)
10475
        err = mp_copy(curve->Gx, ecp->x);
10476
    if (err == MP_OKAY)
10477
        err = mp_copy(curve->Gy, ecp->y);
10478
    if (err == MP_OKAY)
10479
        err = mp_set(ecp->z, 1);
10480
10481
    wc_ecc_curve_free(curve);
10482
    FREE_CURVE_SPECS();
10483
10484
    return err;
10485
}
10486
#endif /* OPENSSL_EXTRA */
10487
10488
10489
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
10490
 * ECC Full Public Key Validation Routine. If the parameter
10491
 * partial is set, then it follows section 5.6.2.3.4, the ECC
10492
 * Partial Public Key Validation Routine.
10493
 * If the parameter priv is set, add in a few extra
10494
 * checks on the bounds of the private key. */
10495
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
10496
0
{
10497
0
    int err = MP_OKAY;
10498
0
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10499
0
    mp_int* b = NULL;
10500
    #ifdef USE_ECC_B_PARAM
10501
        DECLARE_CURVE_SPECS(4);
10502
    #else
10503
0
        #ifndef WOLFSSL_SMALL_STACK
10504
0
            mp_int b_lcl;
10505
0
        #endif
10506
0
        DECLARE_CURVE_SPECS(3);
10507
0
    #endif /* USE_ECC_B_PARAM */
10508
0
#endif
10509
10510
0
    ASSERT_SAVED_VECTOR_REGISTERS();
10511
10512
0
    if (key == NULL)
10513
0
        return BAD_FUNC_ARG;
10514
10515
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
10516
    /* consider key check success on HW crypto
10517
     * ex: ATECC508/608A, CryptoCell and Silabs
10518
     *
10519
     * consider key check success on most Crypt Cb only builds
10520
     */
10521
    err = MP_OKAY;
10522
10523
#else
10524
10525
#ifdef WOLFSSL_HAVE_SP_ECC
10526
#ifndef WOLFSSL_SP_NO_256
10527
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10528
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10529
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10530
    }
10531
#endif
10532
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10533
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10534
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10535
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10536
    }
10537
#endif
10538
#ifdef WOLFSSL_SP_384
10539
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10540
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10541
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10542
    }
10543
#endif
10544
#ifdef WOLFSSL_SP_521
10545
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10546
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10547
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10548
    }
10549
#endif
10550
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
10551
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
10552
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
10553
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10554
    }
10555
#endif
10556
#endif
10557
10558
0
#ifndef WOLFSSL_SP_MATH
10559
    #ifdef USE_ECC_B_PARAM
10560
        ALLOC_CURVE_SPECS(4, err);
10561
    #else
10562
0
        ALLOC_CURVE_SPECS(3, err);
10563
0
        #ifndef WOLFSSL_SMALL_STACK
10564
0
            b = &b_lcl;
10565
        #else
10566
            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10567
            if (b == NULL) {
10568
                FREE_CURVE_SPECS();
10569
                return MEMORY_E;
10570
            }
10571
        #endif
10572
0
        XMEMSET(b, 0, sizeof(mp_int));
10573
0
    #endif
10574
10575
    #ifdef WOLFSSL_CAAM
10576
    /* keys can be black encrypted ones which can not be checked like plain text
10577
     * keys */
10578
    if (key->blackKey > 0) {
10579
        /* encrypted key was used */
10580
        #ifdef WOLFSSL_SMALL_STACK
10581
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
10582
        #endif
10583
        FREE_CURVE_SPECS();
10584
        return 0;
10585
    }
10586
    #endif
10587
10588
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
10589
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
10590
    /* pubkey point cannot be at infinity */
10591
0
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10592
    #ifdef WOLFSSL_SMALL_STACK
10593
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
10594
    #endif
10595
0
        FREE_CURVE_SPECS();
10596
0
        return ECC_INF_E;
10597
0
    }
10598
10599
    /* load curve info */
10600
0
    if (err == MP_OKAY)
10601
0
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10602
0
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10603
#ifdef USE_ECC_B_PARAM
10604
            | ECC_CURVE_FIELD_BF
10605
#endif
10606
0
    ));
10607
10608
0
#ifndef USE_ECC_B_PARAM
10609
    /* load curve b parameter */
10610
0
    if (err == MP_OKAY)
10611
0
        err = mp_init(b);
10612
0
    if (err == MP_OKAY)
10613
0
        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
10614
#else
10615
    if (err == MP_OKAY)
10616
        b = curve->Bf;
10617
#endif
10618
10619
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
10620
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
10621
    /* Qx must be in the range [0, p-1] */
10622
0
    if (err == MP_OKAY) {
10623
0
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10624
0
                mp_isneg(key->pubkey.x)) {
10625
0
            err = ECC_OUT_OF_RANGE_E;
10626
0
        }
10627
0
    }
10628
10629
    /* Qy must be in the range [0, p-1] */
10630
0
    if (err == MP_OKAY) {
10631
0
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10632
0
                mp_isneg(key->pubkey.y)) {
10633
0
            err = ECC_OUT_OF_RANGE_E;
10634
0
        }
10635
0
    }
10636
10637
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
10638
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
10639
    /* make sure point is actually on curve */
10640
0
    if (err == MP_OKAY)
10641
0
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10642
10643
0
    if (!partial) {
10644
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10645
        /* pubkey * order must be at infinity */
10646
0
        if (err == MP_OKAY)
10647
0
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10648
0
                    curve->prime, curve->order);
10649
0
    }
10650
10651
0
    if (priv) {
10652
        /* SP 800-56Ar3, section 5.6.2.1.2 */
10653
        /* private keys must be in the range [1, n-1] */
10654
0
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10655
0
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10656
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10657
        #ifdef WOLFSSL_KCAPI_ECC
10658
            && key->handle == NULL
10659
        #endif
10660
0
        ) {
10661
0
            err = ECC_PRIV_KEY_E;
10662
0
        }
10663
10664
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
10665
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
10666
        /* private * base generator must equal pubkey */
10667
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
10668
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10669
    #endif
10670
0
    }
10671
10672
0
    wc_ecc_curve_free(curve);
10673
10674
0
#ifndef USE_ECC_B_PARAM
10675
0
    mp_clear(b);
10676
    #ifdef WOLFSSL_SMALL_STACK
10677
        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
10678
    #endif
10679
0
#endif
10680
10681
0
    FREE_CURVE_SPECS();
10682
10683
#else
10684
    /* The single precision math curve is not available */
10685
    err = WC_KEY_SIZE_E;
10686
#endif /* !WOLFSSL_SP_MATH */
10687
0
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10688
10689
0
    (void)partial;
10690
0
    (void)priv;
10691
0
    return err;
10692
0
}
10693
10694
10695
/* perform sanity checks on ecc key validity, 0 on success */
10696
WOLFSSL_ABI
10697
int wc_ecc_check_key(ecc_key* key)
10698
0
{
10699
0
    int ret;
10700
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10701
0
    ret = _ecc_validate_public_key(key, 0, 1);
10702
0
    RESTORE_VECTOR_REGISTERS();
10703
0
    return ret;
10704
0
}
10705
10706
10707
#ifdef HAVE_ECC_KEY_IMPORT
10708
/* import public ECC key in ANSI X9.63 format */
10709
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
10710
                          int curve_id)
10711
0
{
10712
0
    int err = MP_OKAY;
10713
#ifdef HAVE_COMP_KEY
10714
    int compressed = 0;
10715
#endif
10716
0
    int keysize = 0;
10717
0
    byte pointType;
10718
#ifdef WOLFSSL_CRYPTOCELL
10719
    const CRYS_ECPKI_Domain_t* pDomain;
10720
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10721
#endif
10722
0
    if (in == NULL || key == NULL)
10723
0
        return BAD_FUNC_ARG;
10724
10725
    /* must be odd */
10726
0
    if ((inLen & 1) == 0) {
10727
0
        return ECC_BAD_ARG_E;
10728
0
    }
10729
10730
    /* make sure required variables are reset */
10731
0
    wc_ecc_reset(key);
10732
10733
    /* init key */
10734
    #ifdef ALT_ECC_SIZE
10735
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10736
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10737
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10738
        alt_fp_init(key->pubkey.x);
10739
        alt_fp_init(key->pubkey.y);
10740
        alt_fp_init(key->pubkey.z);
10741
        key->k = (mp_int*)key->ka;
10742
        alt_fp_init(key->k);
10743
    #ifdef WOLFSSL_ECC_BLIND_K
10744
        key->kb = (mp_int*)key->kba;
10745
        key->ku = (mp_int*)key->kua;
10746
        alt_fp_init(key->kb);
10747
        alt_fp_init(key->ku);
10748
    #endif
10749
    #else
10750
0
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10751
0
    #ifndef WOLFSSL_ECC_BLIND_K
10752
0
                                                                      NULL, NULL
10753
    #else
10754
                                                                key->kb, key->ku
10755
    #endif
10756
0
                            );
10757
0
    #endif
10758
0
    if (err != MP_OKAY)
10759
0
        return MEMORY_E;
10760
#ifdef WOLFSSL_ECC_BLIND_K
10761
    mp_forcezero(key->kb);
10762
#endif
10763
10764
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10765
10766
    /* check for point type (4, 2, or 3) */
10767
0
    pointType = in[0];
10768
0
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10769
0
                                         pointType != ECC_POINT_COMP_ODD) {
10770
0
        err = ASN_PARSE_E;
10771
0
    }
10772
10773
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10774
    #ifdef HAVE_COMP_KEY
10775
        compressed = 1;
10776
    #else
10777
0
        err = NOT_COMPILED_IN;
10778
0
    #endif
10779
0
    }
10780
10781
    /* adjust to skip first byte */
10782
0
    inLen -= 1;
10783
0
    in += 1;
10784
10785
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10786
    /* For SECP256R1 only save raw public key for hardware */
10787
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
10788
    #ifdef HAVE_COMP_KEY
10789
        if (!compressed)
10790
    #endif
10791
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10792
    }
10793
#elif defined(WOLFSSL_KCAPI_ECC)
10794
    XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10795
#endif
10796
10797
0
    if (err == MP_OKAY) {
10798
    #ifdef HAVE_COMP_KEY
10799
        /* adjust inLen if compressed */
10800
        if (compressed)
10801
            inLen = inLen*2 + 1;  /* used uncompressed len */
10802
    #endif
10803
10804
        /* determine key size */
10805
0
        keysize = (int)(inLen>>1);
10806
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
10807
         *       on created keys or signatures */
10808
0
        err = wc_ecc_set_curve(key, keysize, curve_id);
10809
0
        key->type = ECC_PUBLICKEY;
10810
0
    }
10811
10812
    /* read data */
10813
0
    if (err == MP_OKAY)
10814
0
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10815
10816
#ifdef HAVE_COMP_KEY
10817
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10818
#if !defined(WOLFSSL_SP_MATH)
10819
    #ifdef WOLFSSL_SMALL_STACK
10820
        mp_int* t1 = NULL;
10821
        mp_int* t2 = NULL;
10822
    #else
10823
        mp_int t1[1], t2[1];
10824
    #endif
10825
        int did_init = 0;
10826
10827
        DECLARE_CURVE_SPECS(3);
10828
        ALLOC_CURVE_SPECS(3, err);
10829
10830
        #ifdef WOLFSSL_SMALL_STACK
10831
        if (err == MP_OKAY) {
10832
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10833
            if (t1 == NULL) {
10834
                err = MEMORY_E;
10835
            }
10836
        }
10837
        if (err == MP_OKAY) {
10838
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10839
            if (t2 == NULL) {
10840
                err = MEMORY_E;
10841
            }
10842
        }
10843
        #endif
10844
        if (err == MP_OKAY) {
10845
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10846
                err = MEMORY_E;
10847
            else
10848
                did_init = 1;
10849
        }
10850
10851
        /* load curve info */
10852
        if (err == MP_OKAY)
10853
            err = wc_ecc_curve_load(key->dp, &curve,
10854
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10855
                 ECC_CURVE_FIELD_BF));
10856
10857
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
10858
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10859
        /* validate prime is prime for custom curves */
10860
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
10861
            int isPrime = MP_NO;
10862
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10863
            if (err == MP_OKAY && isPrime == MP_NO)
10864
                err = MP_VAL;
10865
        }
10866
    #endif
10867
10868
        /* compute x^3 */
10869
        if (err == MP_OKAY)
10870
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10871
        if (err == MP_OKAY)
10872
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10873
10874
        /* compute x^3 + a*x */
10875
        if (err == MP_OKAY)
10876
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10877
        if (err == MP_OKAY)
10878
            err = mp_add(t1, t2, t1);
10879
10880
        /* compute x^3 + a*x + b */
10881
        if (err == MP_OKAY)
10882
            err = mp_add(t1, curve->Bf, t1);
10883
10884
        /* compute sqrt(x^3 + a*x + b) */
10885
        if (err == MP_OKAY)
10886
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10887
10888
        /* adjust y */
10889
        if (err == MP_OKAY) {
10890
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10891
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10892
                err = mp_mod(t2, curve->prime, t2);
10893
            }
10894
            else {
10895
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10896
            }
10897
            if (err == MP_OKAY)
10898
                err = mp_copy(t2, key->pubkey.y);
10899
        }
10900
10901
        if (did_init) {
10902
            mp_clear(t2);
10903
            mp_clear(t1);
10904
        }
10905
    #ifdef WOLFSSL_SMALL_STACK
10906
        XFREE(t1, NULL, DYNAMIC_TYPE_BIGINT);
10907
        XFREE(t2, NULL, DYNAMIC_TYPE_BIGINT);
10908
    #endif
10909
10910
        wc_ecc_curve_free(curve);
10911
        FREE_CURVE_SPECS();
10912
#else
10913
    #ifndef WOLFSSL_SP_NO_256
10914
        if (key->dp->id == ECC_SECP256R1) {
10915
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
10916
                key->pubkey.y);
10917
        }
10918
        else
10919
    #endif
10920
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10921
        if (key->dp->id == ECC_SM2P256V1) {
10922
            sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
10923
        }
10924
        else
10925
    #endif
10926
    #ifdef WOLFSSL_SP_384
10927
        if (key->dp->id == ECC_SECP384R1) {
10928
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
10929
                key->pubkey.y);
10930
        }
10931
        else
10932
    #endif
10933
    #ifdef WOLFSSL_SP_521
10934
        if (key->dp->id == ECC_SECP521R1) {
10935
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
10936
                key->pubkey.y);
10937
        }
10938
        else
10939
    #endif
10940
        {
10941
            err = WC_KEY_SIZE_E;
10942
        }
10943
#endif
10944
    }
10945
#endif /* HAVE_COMP_KEY */
10946
10947
0
    if (err == MP_OKAY) {
10948
    #ifdef HAVE_COMP_KEY
10949
        if (compressed == 0)
10950
    #endif
10951
0
        {
10952
0
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10953
0
                (word32)keysize);
10954
0
        }
10955
0
    }
10956
0
    if (err == MP_OKAY)
10957
0
        err = mp_set(key->pubkey.z, 1);
10958
10959
#ifdef WOLFSSL_CRYPTOCELL
10960
    if (err == MP_OKAY) {
10961
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
10962
10963
        /* create public key from external key buffer */
10964
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
10965
                                               (byte*)in-1, /* re-adjust */
10966
                                               inLen+1,     /* original input */
10967
                                               &key->ctx.pubKey,
10968
                                               &tempBuff);
10969
10970
        if (err != SA_SILIB_RET_OK){
10971
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
10972
        }
10973
    }
10974
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10975
    if (err == MP_OKAY)
10976
        err = silabs_ecc_import(key, keysize, 1, 0);
10977
#elif defined(WOLFSSL_SE050)
10978
    if (err == MP_OKAY) {
10979
        /* reset key ID, in case used before */
10980
        key->keyId = 0;
10981
        key->keyIdSet = 0;
10982
    }
10983
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10984
    #ifndef HAVE_COMP_KEY
10985
    if (err == MP_OKAY) {
10986
    #else
10987
    if (err == MP_OKAY && !compressed) {
10988
    #endif
10989
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
10990
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
10991
    }
10992
#endif
10993
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10994
    if (err == MP_OKAY)
10995
        err = wc_ecc_check_key(key);
10996
#endif
10997
10998
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
10999
    if (err == MP_OKAY) {
11000
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
11001
    }
11002
#endif
11003
11004
0
    if (err != MP_OKAY) {
11005
0
        mp_clear(key->pubkey.x);
11006
0
        mp_clear(key->pubkey.y);
11007
0
        mp_clear(key->pubkey.z);
11008
0
        mp_clear(key->k);
11009
0
    }
11010
11011
0
    RESTORE_VECTOR_REGISTERS();
11012
11013
0
    return err;
11014
0
}
11015
11016
WOLFSSL_ABI
11017
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
11018
0
{
11019
0
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
11020
0
}
11021
#endif /* HAVE_ECC_KEY_IMPORT */
11022
11023
#ifdef HAVE_ECC_KEY_EXPORT
11024
11025
/* export ecc key to component form, d is optional if only exporting public
11026
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
11027
 * return MP_OKAY on success */
11028
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
11029
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
11030
0
{
11031
0
    int err = 0;
11032
0
    word32 keySz;
11033
11034
0
    if (key == NULL) {
11035
0
        return BAD_FUNC_ARG;
11036
0
    }
11037
11038
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
11039
0
        return ECC_BAD_ARG_E;
11040
0
    }
11041
0
    keySz = (word32)key->dp->size;
11042
11043
    /* private key, d */
11044
0
    if (d != NULL) {
11045
0
        if (dLen == NULL ||
11046
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
11047
0
            return BAD_FUNC_ARG;
11048
11049
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11050
        /* Hardware cannot export private portion */
11051
        return NOT_COMPILED_IN;
11052
    #else
11053
    #if defined(WOLFSSL_SECO_CAAM)
11054
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
11055
            /* Hardware cannot export private portion */
11056
            WOLFSSL_MSG("Can not export private key from HSM");
11057
            return NOT_COMPILED_IN;
11058
        }
11059
    #endif
11060
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11061
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11062
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11063
                *dLen = keySz + WC_CAAM_MAC_SZ;
11064
                return BUFFER_E;
11065
            }
11066
11067
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
11068
                encType);
11069
            *dLen = keySz + WC_CAAM_MAC_SZ;
11070
        }
11071
        else if (encType == WC_TYPE_BLACK_KEY &&
11072
                key->blackKey != CAAM_BLACK_KEY_ECB &&
11073
                key->blackKey > 0) {
11074
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11075
                *dLen = keySz + WC_CAAM_MAC_SZ;
11076
                return BUFFER_E;
11077
            }
11078
11079
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11080
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11081
                    return WC_HW_E;
11082
            }
11083
11084
            *dLen = keySz + WC_CAAM_MAC_SZ;
11085
        }
11086
        else
11087
    #endif
11088
0
        {
11089
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11090
0
            if (err != MP_OKAY)
11091
0
                return err;
11092
0
        }
11093
0
    #endif
11094
0
    }
11095
11096
    /* public x component */
11097
0
    if (qx != NULL) {
11098
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11099
0
            return BAD_FUNC_ARG;
11100
11101
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11102
0
        if (err != MP_OKAY)
11103
0
            return err;
11104
0
    }
11105
11106
    /* public y component */
11107
0
    if (qy != NULL) {
11108
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11109
0
            return BAD_FUNC_ARG;
11110
11111
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11112
0
        if (err != MP_OKAY)
11113
0
            return err;
11114
0
    }
11115
11116
0
    return err;
11117
0
}
11118
11119
11120
/* export ecc private key only raw, outLen is in/out size as unsigned bin
11121
   return MP_OKAY on success */
11122
WOLFSSL_ABI
11123
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11124
0
{
11125
0
    if (out == NULL || outLen == NULL) {
11126
0
        return BAD_FUNC_ARG;
11127
0
    }
11128
11129
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11130
    /* check if black key in secure memory */
11131
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11132
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11133
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11134
            WC_TYPE_BLACK_KEY);
11135
    }
11136
#endif
11137
11138
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11139
0
        WC_TYPE_UNSIGNED_BIN);
11140
0
}
11141
11142
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11143
 * return MP_OKAY on success, negative on error */
11144
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11145
                             byte* qy, word32* qyLen)
11146
0
{
11147
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11148
0
        return BAD_FUNC_ARG;
11149
0
    }
11150
11151
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11152
0
        WC_TYPE_UNSIGNED_BIN);
11153
0
}
11154
11155
/* export ecc key to raw elements including public (Qx,Qy) and
11156
 *   private (d) as unsigned bin
11157
 * return MP_OKAY on success, negative on error */
11158
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11159
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11160
0
{
11161
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11162
0
        WC_TYPE_UNSIGNED_BIN);
11163
0
}
11164
11165
#endif /* HAVE_ECC_KEY_EXPORT */
11166
11167
#ifdef HAVE_ECC_KEY_IMPORT
11168
/* import private key, public part optional if (pub) passed as NULL */
11169
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11170
                                 const byte* pub, word32 pubSz, ecc_key* key,
11171
                                 int curve_id)
11172
0
{
11173
0
    int ret;
11174
#ifdef WOLFSSL_CRYPTOCELL
11175
    const CRYS_ECPKI_Domain_t* pDomain;
11176
#endif
11177
0
    if (key == NULL || priv == NULL)
11178
0
        return BAD_FUNC_ARG;
11179
11180
    /* public optional, NULL if only importing private */
11181
0
    if (pub != NULL) {
11182
0
    #ifndef NO_ASN
11183
0
        word32 idx = 0;
11184
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
11185
0
        if (ret < 0)
11186
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11187
0
        key->type = ECC_PRIVATEKEY;
11188
    #else
11189
        (void)pubSz;
11190
        ret = NOT_COMPILED_IN;
11191
    #endif
11192
0
    }
11193
0
    else {
11194
        /* make sure required variables are reset */
11195
0
        wc_ecc_reset(key);
11196
11197
        /* set key size */
11198
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11199
         *       on created keys or signatures */
11200
0
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11201
0
        key->type = ECC_PRIVATEKEY_ONLY;
11202
0
    }
11203
11204
0
    if (ret != 0)
11205
0
        return ret;
11206
11207
#ifdef WOLFSSL_CRYPTOCELL
11208
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11209
    /* import private key - priv checked for NULL at top */
11210
    if (priv[0] != '\0') {
11211
11212
        /* Create private key from external key buffer*/
11213
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11214
                                      priv,
11215
                                      privSz,
11216
                                      &key->ctx.privKey);
11217
11218
        if (ret != SA_SILIB_RET_OK) {
11219
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11220
            return ret;
11221
        }
11222
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
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11231
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11232
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11233
        int part = caamFindUnusedPartition();
11234
        if (part >= 0) {
11235
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11236
            if (vaddr == 0) {
11237
                WOLFSSL_MSG("Unable to get partition");
11238
                return MEMORY_E;
11239
            }
11240
11241
            key->partNum  = part;
11242
            key->blackKey = (word32)vaddr;
11243
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11244
                return WC_HW_E;
11245
11246
            if (pub != NULL) {
11247
                /* +1 to account for x963 compressed bit */
11248
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11249
                    return WC_HW_E;
11250
                key->securePubKey = (word32)vaddr + privSz;
11251
            }
11252
        }
11253
        else {
11254
            WOLFSSL_MSG("Unable to find an unused partition");
11255
            return MEMORY_E;
11256
        }
11257
    #else
11258
        key->blackKey = CAAM_BLACK_KEY_CCM;
11259
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11260
    #ifdef WOLFSSL_ECC_BLIND_K
11261
        if (ret == MP_OKAY) {
11262
            err = ecc_blind_k_rng(key, NULL);
11263
        }
11264
    #endif
11265
    #endif
11266
    }
11267
    else {
11268
        key->blackKey = 0;
11269
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11270
    #ifdef WOLFSSL_ECC_BLIND_K
11271
        if (ret == MP_OKAY) {
11272
            err = ecc_blind_k_rng(key, NULL);
11273
        }
11274
    #endif
11275
11276
        /* If using AES-ECB encrypted black keys check here if key is valid,
11277
         * if not valid than assume is an encrypted key. A public key is needed
11278
         * for testing validity. */
11279
        if (key->devId == WOLFSSL_CAAM_DEVID && (
11280
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11281
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11282
            if ((pub != NULL) && (ret == MP_OKAY) &&
11283
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11284
                key->blackKey = CAAM_BLACK_KEY_ECB;
11285
            }
11286
            else if ((pub == NULL) && (ret == MP_OKAY)) {
11287
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11288
                key->blackKey = CAAM_BLACK_KEY_ECB;
11289
            }
11290
            else {
11291
                WOLFSSL_MSG("Importing key that is not a black key!");
11292
            }
11293
        }
11294
    }
11295
#else
11296
11297
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11298
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11299
#endif
11300
11301
0
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11302
#ifdef HAVE_WOLF_BIGINT
11303
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11304
                                                                 privSz) != 0) {
11305
        mp_clear(key->k);
11306
        ret = ASN_GETINT_E;
11307
    }
11308
#endif /* HAVE_WOLF_BIGINT */
11309
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11310
    if (ret == 0) {
11311
    #ifdef WOLFSSL_SMALL_STACK
11312
        mp_int* order = NULL;
11313
    #else
11314
        mp_int order[1];
11315
    #endif
11316
11317
    #ifdef WOLFSSL_SMALL_STACK
11318
        order = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
11319
        if (order == NULL) {
11320
            ret = MEMORY_E;
11321
        }
11322
    #endif
11323
11324
        if (ret == 0) {
11325
            ret = mp_init(order);
11326
        }
11327
        if (ret == 0) {
11328
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11329
        }
11330
    #ifdef WOLFSSL_SM2
11331
        /* SM2 curve: private key must be less than order-1. */
11332
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11333
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11334
            ret = mp_sub_d(order, 1, order);
11335
        }
11336
    #endif
11337
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11338
            ret = ECC_PRIV_KEY_E;
11339
        }
11340
11341
    #ifdef WOLFSSL_SMALL_STACK
11342
        XFREE(order, key->heap, DYNAMIC_TYPE_ECC);
11343
    #endif
11344
    }
11345
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11346
#ifdef WOLFSSL_ECC_BLIND_K
11347
    if (ret == 0) {
11348
        ret = ecc_blind_k_rng(key, NULL);
11349
    }
11350
#endif
11351
11352
0
#endif /* WOLFSSL_CRYPTOCELL */
11353
11354
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11355
    if ((pub != NULL) && (ret == MP_OKAY))
11356
        /* public key needed to perform key validation */
11357
        ret = _ecc_validate_public_key(key, 1, 1);
11358
11359
#endif
11360
11361
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11362
    RESTORE_VECTOR_REGISTERS();
11363
#endif
11364
11365
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11366
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11367
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11368
    }
11369
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11370
    if (ret == 0) {
11371
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11372
    }
11373
#endif
11374
11375
0
    return ret;
11376
0
}
11377
11378
/* ecc private key import, public key in ANSI X9.63 format, private raw */
11379
WOLFSSL_ABI
11380
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11381
                           word32 pubSz, ecc_key* key)
11382
0
{
11383
0
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11384
0
                                                                ECC_CURVE_DEF);
11385
0
}
11386
#endif /* HAVE_ECC_KEY_IMPORT */
11387
11388
#ifndef NO_ASN
11389
/**
11390
   Convert ECC R,S to signature
11391
   r       R component of signature
11392
   s       S component of signature
11393
   out     DER-encoded ECDSA signature
11394
   outlen  [in/out] output buffer size, output signature size
11395
   return  MP_OKAY on success
11396
*/
11397
WOLFSSL_ABI
11398
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11399
0
{
11400
0
    int err;
11401
#ifdef WOLFSSL_SMALL_STACK
11402
    mp_int* rtmp = NULL;
11403
    mp_int* stmp = NULL;
11404
#else
11405
0
    mp_int  rtmp[1];
11406
0
    mp_int  stmp[1];
11407
0
#endif
11408
11409
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11410
0
        return ECC_BAD_ARG_E;
11411
11412
#ifdef WOLFSSL_SMALL_STACK
11413
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11414
    if (rtmp == NULL)
11415
        return MEMORY_E;
11416
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11417
    if (stmp == NULL) {
11418
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11419
        return MEMORY_E;
11420
    }
11421
#endif
11422
11423
0
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11424
0
    if (err != MP_OKAY) {
11425
    #ifdef WOLFSSL_SMALL_STACK
11426
        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
11427
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11428
    #endif
11429
0
        return err;
11430
0
    }
11431
11432
0
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11433
0
    if (err == MP_OKAY)
11434
0
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11435
11436
0
    if (err == MP_OKAY) {
11437
0
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11438
0
            err = MP_ZERO_E;
11439
0
    }
11440
0
    if (err == MP_OKAY) {
11441
0
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11442
0
            err = MP_READ_E;
11443
0
        }
11444
0
    }
11445
11446
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11447
0
    if (err == MP_OKAY)
11448
0
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11449
11450
0
    mp_clear(rtmp);
11451
0
    mp_clear(stmp);
11452
#ifdef WOLFSSL_SMALL_STACK
11453
    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
11454
    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11455
#endif
11456
11457
0
    return err;
11458
0
}
11459
11460
/**
11461
   Convert ECC R,S raw unsigned bin to signature
11462
   r       R component of signature
11463
   rSz     R size
11464
   s       S component of signature
11465
   sSz     S size
11466
   out     DER-encoded ECDSA signature
11467
   outlen  [in/out] output buffer size, output signature size
11468
   return  MP_OKAY on success
11469
*/
11470
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11471
    byte* out, word32* outlen)
11472
0
{
11473
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11474
0
        return ECC_BAD_ARG_E;
11475
11476
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11477
0
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11478
0
}
11479
11480
/**
11481
   Convert ECC signature to R,S
11482
   sig     DER-encoded ECDSA signature
11483
   sigLen  length of signature in octets
11484
   r       R component of signature
11485
   rLen    [in/out] output "r" buffer size, output "r" size
11486
   s       S component of signature
11487
   sLen    [in/out] output "s" buffer size, output "s" size
11488
   return  MP_OKAY on success, negative on error
11489
*/
11490
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11491
                     byte* s, word32* sLen)
11492
0
{
11493
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11494
0
        return ECC_BAD_ARG_E;
11495
11496
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11497
0
}
11498
#endif /* !NO_ASN */
11499
11500
#ifdef HAVE_ECC_KEY_IMPORT
11501
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
11502
          const char* qy, const char* d, int curve_id, int encType)
11503
0
{
11504
0
    int err = MP_OKAY;
11505
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11506
    !defined(WOLFSSL_ATECC608A)
11507
    const CRYS_ECPKI_Domain_t* pDomain;
11508
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11509
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11510
#endif
11511
11512
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11513
    defined(WOLFSSL_CRYPTOCELL)
11514
    word32 keySz = 0;
11515
#endif
11516
11517
    /* if d is NULL, only import as public key using Qx,Qy */
11518
0
    if (key == NULL || qx == NULL || qy == NULL) {
11519
0
        return BAD_FUNC_ARG;
11520
0
    }
11521
11522
    /* make sure required variables are reset */
11523
0
    wc_ecc_reset(key);
11524
11525
    /* set curve type and index */
11526
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11527
     *       on created keys or signatures */
11528
0
    err = wc_ecc_set_curve(key, 0, curve_id);
11529
0
    if (err != 0) {
11530
0
        return err;
11531
0
    }
11532
11533
    /* init key */
11534
#ifdef ALT_ECC_SIZE
11535
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11536
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11537
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11538
    alt_fp_init(key->pubkey.x);
11539
    alt_fp_init(key->pubkey.y);
11540
    alt_fp_init(key->pubkey.z);
11541
    key->k = (mp_int*)key->ka;
11542
    alt_fp_init(key->k);
11543
#ifdef WOLFSSL_ECC_BLIND_K
11544
    key->kb = (mp_int*)key->kba;
11545
    key->ku = (mp_int*)key->kua;
11546
    alt_fp_init(key->kb);
11547
    alt_fp_init(key->ku);
11548
#endif
11549
#else
11550
0
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11551
0
#ifndef WOLFSSL_ECC_BLIND_K
11552
0
                                                                      NULL, NULL
11553
#else
11554
                                                                key->kb, key->ku
11555
#endif
11556
0
                        );
11557
0
#endif
11558
0
    if (err != MP_OKAY)
11559
0
        return MEMORY_E;
11560
#ifdef WOLFSSL_ECC_BLIND_K
11561
    mp_forcezero(key->kb);
11562
#endif
11563
11564
    /* read Qx */
11565
0
    if (err == MP_OKAY) {
11566
0
        if (encType == WC_TYPE_HEX_STR)
11567
0
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
11568
0
        else
11569
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
11570
0
                (word32)key->dp->size);
11571
11572
0
        if (mp_isneg(key->pubkey.x)) {
11573
0
            WOLFSSL_MSG("Invalid Qx");
11574
0
            err = BAD_FUNC_ARG;
11575
0
        }
11576
0
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11577
0
            err = BAD_FUNC_ARG;
11578
0
        }
11579
0
    }
11580
11581
    /* read Qy */
11582
0
    if (err == MP_OKAY) {
11583
0
        if (encType == WC_TYPE_HEX_STR)
11584
0
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
11585
0
        else
11586
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
11587
0
                (word32)key->dp->size);
11588
11589
0
        if (mp_isneg(key->pubkey.y)) {
11590
0
            WOLFSSL_MSG("Invalid Qy");
11591
0
            err = BAD_FUNC_ARG;
11592
0
        }
11593
0
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11594
0
            err = BAD_FUNC_ARG;
11595
0
        }
11596
0
    }
11597
11598
0
    if (err == MP_OKAY) {
11599
0
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11600
0
            WOLFSSL_MSG("Invalid Qx and Qy");
11601
0
            err = ECC_INF_E;
11602
0
        }
11603
0
    }
11604
11605
0
    if (err == MP_OKAY)
11606
0
        err = mp_set(key->pubkey.z, 1);
11607
11608
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11609
    /* For SECP256R1 only save raw public key for hardware */
11610
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
11611
        keySz = key->dp->size;
11612
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11613
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11614
        if (err == MP_OKAY)
11615
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
11616
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11617
    }
11618
#elif defined(WOLFSSL_CRYPTOCELL)
11619
    if (err == MP_OKAY) {
11620
        keyRaw[0] = ECC_POINT_UNCOMP;
11621
        keySz = (word32)key->dp->size;
11622
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
11623
            WC_TYPE_UNSIGNED_BIN);
11624
        if (err == MP_OKAY) {
11625
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
11626
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11627
        }
11628
11629
        if (err == MP_OKAY) {
11630
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11631
11632
            /* create public key from external key buffer */
11633
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11634
                                                   keyRaw,
11635
                                                   keySz*2 + 1,
11636
                                                   &key->ctx.pubKey,
11637
                                                   &tempBuff);
11638
        }
11639
11640
        if (err != SA_SILIB_RET_OK){
11641
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11642
            return err;
11643
        }
11644
    }
11645
#elif defined(WOLFSSL_KCAPI_ECC)
11646
    if (err == MP_OKAY) {
11647
        word32 keySz = key->dp->size;
11648
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11649
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11650
        if (err == MP_OKAY) {
11651
            err = wc_export_int(key->pubkey.y,
11652
                &key->pubkey_raw[keySz], &keySz, keySz,
11653
                WC_TYPE_UNSIGNED_BIN);
11654
        }
11655
    }
11656
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11657
    if (err == MP_OKAY) {
11658
        const word32 keySize = key->dp->size;
11659
        word32 bufSize = sizeof(key->keyRaw);
11660
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
11661
                            WC_TYPE_UNSIGNED_BIN);
11662
        if (err == MP_OKAY) {
11663
            const word32 offset = bufSize;
11664
            bufSize = sizeof(key->keyRaw) - offset;
11665
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
11666
                                keySize, WC_TYPE_UNSIGNED_BIN);
11667
        }
11668
        if (err == MP_OKAY) {
11669
            mp_reverse(key->keyRaw, keySize);
11670
            mp_reverse(&key->keyRaw[keySize], keySize);
11671
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
11672
                                           keySize * 2);
11673
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
11674
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
11675
                                              xil_curve_type[key->dp->id],
11676
                                              XIL_CAST_U64(key->keyRaw));
11677
            if (err) {
11678
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
11679
                err = WC_HW_E;
11680
            }
11681
#endif
11682
        }
11683
    }
11684
#endif
11685
11686
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11687
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11688
#endif
11689
11690
    /* import private key */
11691
0
    if (err == MP_OKAY) {
11692
0
        if (d != NULL) {
11693
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11694
            /* Hardware doesn't support loading private key */
11695
            err = NOT_COMPILED_IN;
11696
11697
        #elif defined(WOLFSSL_CRYPTOCELL)
11698
            key->type = ECC_PRIVATEKEY;
11699
11700
            if (encType == WC_TYPE_HEX_STR)
11701
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11702
            else
11703
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
11704
                    key->dp->size);
11705
            if (err == MP_OKAY) {
11706
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
11707
                    WC_TYPE_UNSIGNED_BIN);
11708
            }
11709
        #ifdef WOLFSSL_ECC_BLIND_K
11710
            if (err == 0) {
11711
                err = ecc_blind_k_rng(key, NULL);
11712
            }
11713
        #endif
11714
11715
            if (err == MP_OKAY) {
11716
                /* Create private key from external key buffer*/
11717
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
11718
                                              keyRaw,
11719
                                              keySz,
11720
                                              &key->ctx.privKey);
11721
11722
                if (err != SA_SILIB_RET_OK){
11723
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11724
                    return err;
11725
                }
11726
            }
11727
11728
        #else
11729
0
            key->type = ECC_PRIVATEKEY;
11730
0
            if (encType == WC_TYPE_HEX_STR)
11731
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11732
0
            else {
11733
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11734
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11735
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11736
                    key->dp->size + WC_CAAM_MAC_SZ);
11737
                }
11738
                else
11739
            #endif /* WOLFSSL_QNX_CAAM */
11740
0
                {
11741
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11742
0
                        (word32)key->dp->size);
11743
0
                }
11744
0
            }
11745
        #ifdef WOLFSSL_ECC_BLIND_K
11746
            if (err == 0) {
11747
                err = ecc_blind_k_rng(key, NULL);
11748
            }
11749
        #endif
11750
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11751
            if (err == MP_OKAY) {
11752
                const word32 key_size = key->dp->size;
11753
                word32 buf_size = key_size;
11754
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
11755
                                    WC_TYPE_UNSIGNED_BIN);
11756
                mp_reverse(key->privKey, key_size);
11757
            }
11758
#endif
11759
11760
0
        #endif /* #else-case of custom HW-specific implementations */
11761
0
            if (mp_iszero(key->k) || mp_isneg(key->k)) {
11762
0
                WOLFSSL_MSG("Invalid private key");
11763
0
                err = BAD_FUNC_ARG;
11764
0
            }
11765
0
        } else {
11766
0
            key->type = ECC_PUBLICKEY;
11767
0
        }
11768
0
    }
11769
11770
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11771
    if (err == MP_OKAY) {
11772
        err = wc_ecc_check_key(key);
11773
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
11774
                                  mp_iszero(key->pubkey.y))) {
11775
            err = BAD_FUNC_ARG;
11776
        }
11777
    }
11778
#endif
11779
11780
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11781
    RESTORE_VECTOR_REGISTERS();
11782
#endif
11783
11784
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11785
    if (err == MP_OKAY) {
11786
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11787
    }
11788
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11789
    if (err == MP_OKAY) {
11790
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
11791
    }
11792
#endif
11793
11794
0
    if (err != MP_OKAY) {
11795
0
        mp_clear(key->pubkey.x);
11796
0
        mp_clear(key->pubkey.y);
11797
0
        mp_clear(key->pubkey.z);
11798
0
        mp_clear(key->k);
11799
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11800
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11801
#endif
11802
0
    }
11803
11804
0
    return err;
11805
0
}
11806
11807
/**
11808
   Import raw ECC key
11809
   key       The destination ecc_key structure
11810
   qx        x component of the public key, as ASCII hex string
11811
   qy        y component of the public key, as ASCII hex string
11812
   d         private key, as ASCII hex string, optional if importing public
11813
             key only
11814
   dp        Custom ecc_set_type
11815
   return    MP_OKAY on success
11816
*/
11817
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
11818
                   const char* d, int curve_id)
11819
0
{
11820
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
11821
0
        WC_TYPE_HEX_STR);
11822
11823
0
}
11824
11825
/* Import x, y and optional private (d) as unsigned binary */
11826
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
11827
                   const byte* d, int curve_id)
11828
0
{
11829
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
11830
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
11831
0
}
11832
11833
/**
11834
   Import raw ECC key
11835
   key       The destination ecc_key structure
11836
   qx        x component of the public key, as ASCII hex string
11837
   qy        y component of the public key, as ASCII hex string
11838
   d         private key, as ASCII hex string, optional if importing public
11839
             key only
11840
   curveName ECC curve name, from ecc_sets[]
11841
   return    MP_OKAY on success
11842
*/
11843
WOLFSSL_ABI
11844
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
11845
                   const char* d, const char* curveName)
11846
0
{
11847
0
    int err, x;
11848
11849
    /* if d is NULL, only import as public key using Qx,Qy */
11850
0
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
11851
0
        return BAD_FUNC_ARG;
11852
0
    }
11853
11854
    /* set curve type and index */
11855
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
11856
0
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11857
0
                     XSTRLEN(curveName)) == 0) {
11858
0
            break;
11859
0
        }
11860
0
    }
11861
11862
0
    if (ecc_sets[x].size == 0) {
11863
0
        WOLFSSL_MSG("ecc_set curve name not found");
11864
0
        err = ASN_PARSE_E;
11865
0
    } else {
11866
0
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
11867
0
            WC_TYPE_HEX_STR);
11868
0
    }
11869
11870
0
    return err;
11871
0
}
11872
#endif /* HAVE_ECC_KEY_IMPORT */
11873
11874
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
11875
/* public key size in octets */
11876
static int ecc_public_key_size(ecc_key* key, word32* sz)
11877
{
11878
    if (key == NULL || key->dp == NULL)
11879
        return BAD_FUNC_ARG;
11880
11881
    /* 'Uncompressed' | x | y */
11882
    *sz = 1 + 2 * (word32)key->dp->size;
11883
11884
    return 0;
11885
}
11886
#endif
11887
11888
/* key size in octets */
11889
WOLFSSL_ABI
11890
int wc_ecc_size(ecc_key* key)
11891
0
{
11892
0
    if (key == NULL || key->dp == NULL)
11893
0
        return 0;
11894
11895
0
    return key->dp->size;
11896
0
}
11897
11898
/* maximum signature size based on key size */
11899
WOLFSSL_ABI
11900
int wc_ecc_sig_size_calc(int sz)
11901
0
{
11902
0
    int maxSigSz = 0;
11903
11904
    /* calculate based on key bits */
11905
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
11906
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
11907
11908
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11909
0
    if (maxSigSz < (128 + 2)) {
11910
0
        maxSigSz -= 1;
11911
0
    }
11912
11913
0
    return maxSigSz;
11914
0
}
11915
11916
/* maximum signature size based on actual key curve */
11917
WOLFSSL_ABI
11918
int wc_ecc_sig_size(const ecc_key* key)
11919
0
{
11920
0
    int maxSigSz;
11921
0
    int orderBits, keySz;
11922
11923
0
    if (key == NULL || key->dp == NULL)
11924
0
        return 0;
11925
11926
    /* the signature r and s will always be less than order */
11927
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
11928
        extra byte for r and s, so add 2 */
11929
0
    keySz = key->dp->size;
11930
0
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11931
0
    if (orderBits > keySz * 8) {
11932
0
        keySz = (orderBits + 7) / 8;
11933
0
    }
11934
    /* maximum possible signature header size is 7 bytes */
11935
0
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11936
0
    if ((orderBits % 8) == 0) {
11937
        /* MSB can be set, so add 2 */
11938
0
        maxSigSz += ECC_MAX_PAD_SZ;
11939
0
    }
11940
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11941
0
    if (maxSigSz < (128 + 2)) {
11942
0
        maxSigSz -= 1;
11943
0
    }
11944
11945
0
    return maxSigSz;
11946
0
}
11947
11948
11949
#ifdef FP_ECC
11950
11951
/* fixed point ECC cache */
11952
/* number of entries in the cache */
11953
#ifndef FP_ENTRIES
11954
    #define FP_ENTRIES 15
11955
#endif
11956
11957
/* number of bits in LUT */
11958
#ifndef FP_LUT
11959
    #define FP_LUT     8U
11960
#endif
11961
11962
#ifdef ECC_SHAMIR
11963
    /* Sharmir requires a bigger LUT, TAO */
11964
    #if (FP_LUT > 12) || (FP_LUT < 4)
11965
        #error FP_LUT must be between 4 and 12 inclusively
11966
    #endif
11967
#else
11968
    #if (FP_LUT > 12) || (FP_LUT < 2)
11969
        #error FP_LUT must be between 2 and 12 inclusively
11970
    #endif
11971
#endif
11972
11973
11974
#if !defined(WOLFSSL_SP_MATH)
11975
11976
/** Our FP cache */
11977
typedef struct {
11978
   ecc_point* g;               /* cached COPY of base point */
11979
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
11980
   int        LUT_set;         /* flag to determine if the LUT has been computed */
11981
   mp_int     mu;              /* copy of the montgomery constant */
11982
   int        lru_count;       /* amount of times this entry has been used */
11983
   int        lock;            /* flag to indicate cache eviction */
11984
                               /* permitted (0) or not (1) */
11985
} fp_cache_t;
11986
11987
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
11988
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
11989
11990
#ifndef HAVE_THREAD_LS
11991
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
11992
#ifndef WOLFSSL_MUTEX_INITIALIZER
11993
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
11994
#endif
11995
#endif /* HAVE_THREAD_LS */
11996
11997
/* simple table to help direct the generation of the LUT */
11998
static const struct {
11999
   int ham, terma, termb;
12000
} lut_orders[] = {
12001
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
12002
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
12003
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
12004
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
12005
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
12006
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
12007
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
12008
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
12009
#if FP_LUT > 6
12010
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
12011
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
12012
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
12013
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
12014
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
12015
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
12016
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
12017
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
12018
#if FP_LUT > 7
12019
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
12020
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
12021
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
12022
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
12023
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
12024
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
12025
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
12026
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
12027
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
12028
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
12029
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
12030
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
12031
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
12032
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
12033
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
12034
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
12035
#if FP_LUT > 8
12036
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
12037
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
12038
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
12039
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
12040
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
12041
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
12042
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
12043
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
12044
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
12045
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
12046
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
12047
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
12048
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
12049
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
12050
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
12051
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
12052
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
12053
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
12054
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
12055
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
12056
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
12057
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
12058
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
12059
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
12060
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
12061
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
12062
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
12063
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
12064
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
12065
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
12066
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
12067
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
12068
#if FP_LUT > 9
12069
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
12070
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
12071
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
12072
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
12073
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
12074
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
12075
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
12076
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
12077
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
12078
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
12079
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
12080
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
12081
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
12082
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
12083
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
12084
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
12085
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
12086
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
12087
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
12088
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
12089
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12090
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12091
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12092
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12093
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12094
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12095
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12096
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12097
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12098
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12099
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12100
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12101
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12102
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12103
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12104
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12105
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12106
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12107
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12108
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12109
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12110
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12111
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12112
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12113
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12114
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12115
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12116
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12117
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12118
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12119
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12120
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12121
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12122
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12123
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12124
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12125
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12126
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12127
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12128
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12129
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12130
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12131
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12132
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12133
#if FP_LUT > 10
12134
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12135
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12136
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12137
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12138
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12139
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12140
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12141
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12142
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12143
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12144
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12145
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12146
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12147
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12148
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12149
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12150
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12151
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12152
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12153
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12154
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12155
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12156
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12157
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12158
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12159
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12160
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12161
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12162
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12163
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12164
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12165
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12166
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12167
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12168
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12169
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12170
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12171
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12172
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12173
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12174
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12175
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12176
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12177
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12178
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12179
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12180
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12181
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12182
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12183
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12184
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12185
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12186
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12187
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12188
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12189
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12190
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12191
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12192
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12193
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12194
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12195
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12196
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12197
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12198
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12199
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12200
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12201
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12202
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12203
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12204
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12205
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12206
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12207
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12208
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12209
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12210
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12211
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12212
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12213
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12214
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12215
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12216
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12217
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12218
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12219
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12220
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12221
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12222
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12223
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12224
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12225
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12226
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12227
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12228
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12229
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12230
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12231
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12232
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12233
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12234
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12235
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12236
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12237
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12238
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12239
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12240
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12241
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12242
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12243
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12244
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12245
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12246
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12247
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12248
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12249
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12250
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12251
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12252
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12253
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12254
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12255
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12256
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12257
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12258
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12259
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12260
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12261
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12262
#if FP_LUT > 11
12263
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12264
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12265
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12266
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12267
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12268
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12269
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12270
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12271
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12272
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12273
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12274
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12275
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12276
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12277
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12278
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12279
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12280
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12281
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12282
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12283
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12284
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12285
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12286
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12287
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12288
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12289
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12290
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12291
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12292
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12293
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12294
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12295
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12296
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12297
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12298
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12299
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12300
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12301
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12302
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12303
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12304
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12305
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12306
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12307
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12308
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12309
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12310
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12311
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12312
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12313
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12314
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12315
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12316
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12317
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12318
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12319
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12320
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12321
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12322
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12323
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12324
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12325
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12326
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12327
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12328
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12329
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12330
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12331
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12332
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12333
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12334
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12335
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12336
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12337
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12338
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12339
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12340
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12341
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12342
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12343
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12344
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12345
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12346
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12347
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12348
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12349
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12350
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12351
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12352
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12353
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12354
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12355
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12356
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12357
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12358
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12359
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12360
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12361
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12362
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12363
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12364
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12365
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12366
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12367
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12368
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12369
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12370
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12371
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12372
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12373
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12374
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12375
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12376
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12377
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12378
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12379
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12380
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12381
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12382
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12383
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12384
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12385
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12386
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12387
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12388
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12389
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12390
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12391
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12392
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12393
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12394
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12395
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12396
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12397
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12398
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12399
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12400
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12401
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12402
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12403
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12404
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12405
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12406
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12407
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12408
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12409
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12410
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12411
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12412
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12413
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12414
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12415
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12416
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12417
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12418
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12419
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12420
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12421
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12422
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12423
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12424
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12425
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12426
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12427
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12428
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12429
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12430
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
12431
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
12432
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
12433
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
12434
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
12435
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
12436
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
12437
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
12438
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
12439
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
12440
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
12441
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
12442
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
12443
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
12444
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
12445
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
12446
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
12447
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
12448
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
12449
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
12450
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
12451
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
12452
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
12453
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
12454
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
12455
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
12456
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
12457
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
12458
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
12459
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
12460
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
12461
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
12462
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
12463
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
12464
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
12465
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
12466
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
12467
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
12468
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
12469
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
12470
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
12471
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
12472
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
12473
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
12474
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
12475
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
12476
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
12477
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
12478
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
12479
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
12480
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
12481
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
12482
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
12483
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
12484
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
12485
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
12486
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
12487
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
12488
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
12489
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
12490
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
12491
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
12492
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
12493
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
12494
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
12495
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
12496
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
12497
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
12498
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
12499
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
12500
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
12501
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
12502
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
12503
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
12504
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
12505
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
12506
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
12507
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
12508
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
12509
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
12510
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
12511
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
12512
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
12513
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
12514
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
12515
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
12516
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
12517
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
12518
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
12519
#endif
12520
#endif
12521
#endif
12522
#endif
12523
#endif
12524
#endif
12525
};
12526
12527
12528
/* find a hole and free as required, return -1 if no hole found */
12529
static int find_hole(void)
12530
{
12531
#ifdef WOLFSSL_NO_MALLOC
12532
   return -1;
12533
#else
12534
   int      x, y, z;
12535
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
12536
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
12537
          z = x;
12538
          y = fp_cache[x].lru_count;
12539
       }
12540
   }
12541
12542
   /* decrease all */
12543
   for (x = 0; x < FP_ENTRIES; x++) {
12544
      if (fp_cache[x].lru_count > 3) {
12545
         --(fp_cache[x].lru_count);
12546
      }
12547
   }
12548
12549
   /* free entry z */
12550
   if (z >= 0 && fp_cache[z].g) {
12551
      mp_clear(&fp_cache[z].mu);
12552
      wc_ecc_del_point(fp_cache[z].g);
12553
      fp_cache[z].g  = NULL;
12554
      for (x = 0; x < (1<<FP_LUT); x++) {
12555
         wc_ecc_del_point(fp_cache[z].LUT[x]);
12556
         fp_cache[z].LUT[x] = NULL;
12557
      }
12558
      fp_cache[z].LUT_set = 0;
12559
      fp_cache[z].lru_count = 0;
12560
   }
12561
   return z;
12562
#endif /* !WOLFSSL_NO_MALLOC */
12563
}
12564
12565
/* determine if a base is already in the cache and if so, where */
12566
static int find_base(ecc_point* g)
12567
{
12568
   int x;
12569
   for (x = 0; x < FP_ENTRIES; x++) {
12570
      if (fp_cache[x].g != NULL &&
12571
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
12572
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
12573
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
12574
         break;
12575
      }
12576
   }
12577
   if (x == FP_ENTRIES) {
12578
      x = -1;
12579
   }
12580
   return x;
12581
}
12582
12583
/* add a new base to the cache */
12584
static int add_entry(int idx, ecc_point *g)
12585
{
12586
   unsigned x, y;
12587
12588
   /* allocate base and LUT */
12589
   fp_cache[idx].g = wc_ecc_new_point();
12590
   if (fp_cache[idx].g == NULL) {
12591
      return MP_MEM;
12592
   }
12593
12594
   /* copy x and y */
12595
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
12596
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
12597
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
12598
      wc_ecc_del_point(fp_cache[idx].g);
12599
      fp_cache[idx].g = NULL;
12600
      return MP_MEM;
12601
   }
12602
12603
   for (x = 0; x < (1U<<FP_LUT); x++) {
12604
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
12605
      if (fp_cache[idx].LUT[x] == NULL) {
12606
         for (y = 0; y < x; y++) {
12607
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
12608
            fp_cache[idx].LUT[y] = NULL;
12609
         }
12610
         wc_ecc_del_point(fp_cache[idx].g);
12611
         fp_cache[idx].g         = NULL;
12612
         fp_cache[idx].lru_count = 0;
12613
         return MP_MEM;
12614
      }
12615
   }
12616
12617
   fp_cache[idx].LUT_set   = 0;
12618
   fp_cache[idx].lru_count = 0;
12619
12620
   return MP_OKAY;
12621
}
12622
#endif
12623
12624
#if !defined(WOLFSSL_SP_MATH)
12625
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
12626
 *
12627
 * The algorithm builds patterns in increasing bit order by first making all
12628
 * single bit input patterns, then all two bit input patterns and so on
12629
 */
12630
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
12631
    mp_int* mu)
12632
{
12633
   int err;
12634
   unsigned x, y, bitlen, lut_gap;
12635
#ifdef WOLFSSL_SMALL_STACK
12636
   mp_int *tmp = NULL;
12637
#else
12638
   mp_int tmp[1];
12639
#endif
12640
   int infinity;
12641
12642
#ifdef WOLFSSL_SMALL_STACK
12643
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12644
       return MEMORY_E;
12645
#endif
12646
12647
   err = mp_init(tmp);
12648
   if (err != MP_OKAY) {
12649
       err = MP_MEM;
12650
       goto errout;
12651
   }
12652
12653
   /* sanity check to make sure lut_order table is of correct size,
12654
      should compile out to a NOP if true */
12655
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
12656
       err = BAD_FUNC_ARG;
12657
       goto errout;
12658
   }
12659
12660
   /* get bitlen and round up to next multiple of FP_LUT */
12661
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12662
   x       = bitlen % FP_LUT;
12663
   if (x) {
12664
       bitlen += FP_LUT - x;
12665
   }
12666
   lut_gap = bitlen / FP_LUT;
12667
12668
   /* init the mu */
12669
   err = mp_init_copy(&fp_cache[idx].mu, mu);
12670
   if (err != MP_OKAY)
12671
       goto errout;
12672
12673
   /* copy base */
12674
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
12675
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
12676
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
12677
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
12678
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
12679
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
12680
       err = MP_MULMOD_E;
12681
       goto errout;
12682
   }
12683
12684
   /* make all single bit entries */
12685
   for (x = 1; x < FP_LUT; x++) {
12686
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
12687
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
12688
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
12689
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
12690
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
12691
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
12692
          err = MP_INIT_E;
12693
          goto errout;
12694
      } else {
12695
12696
         /* now double it bitlen/FP_LUT times */
12697
         for (y = 0; y < lut_gap; y++) {
12698
             if ((err = ecc_projective_dbl_point_safe(
12699
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12700
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12701
                                      a, modulus, mp)) != MP_OKAY) {
12702
                 goto errout;
12703
             }
12704
         }
12705
     }
12706
  }
12707
12708
   /* now make all entries in increase order of hamming weight */
12709
   for (x = 2; x <= FP_LUT; x++) {
12710
       if (err != MP_OKAY)
12711
           goto errout;
12712
       for (y = 0; y < (1UL<<FP_LUT); y++) {
12713
           if (lut_orders[y].ham != (int)x) continue;
12714
12715
           /* perform the add */
12716
           if ((err = ecc_projective_add_point_safe(
12717
                           fp_cache[idx].LUT[lut_orders[y].terma],
12718
                           fp_cache[idx].LUT[lut_orders[y].termb],
12719
                           fp_cache[idx].LUT[y], a, modulus, mp,
12720
                           &infinity)) != MP_OKAY) {
12721
               goto errout;
12722
           }
12723
       }
12724
   }
12725
12726
   /* now map all entries back to affine space to make point addition faster */
12727
   for (x = 1; x < (1UL<<FP_LUT); x++) {
12728
       if (err != MP_OKAY)
12729
           break;
12730
12731
       /* convert z to normal from montgomery */
12732
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
12733
12734
       /* invert it */
12735
       if (err == MP_OKAY)
12736
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
12737
                         fp_cache[idx].LUT[x]->z);
12738
12739
       if (err == MP_OKAY)
12740
         /* now square it */
12741
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
12742
12743
       if (err == MP_OKAY)
12744
         /* fix x */
12745
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
12746
                         fp_cache[idx].LUT[x]->x);
12747
12748
       if (err == MP_OKAY)
12749
         /* get 1/z^3 */
12750
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
12751
12752
       if (err == MP_OKAY)
12753
         /* fix y */
12754
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
12755
                         fp_cache[idx].LUT[x]->y);
12756
12757
       if (err == MP_OKAY)
12758
         /* free z */
12759
         mp_clear(fp_cache[idx].LUT[x]->z);
12760
   }
12761
12762
  errout:
12763
12764
   mp_clear(tmp);
12765
#ifdef WOLFSSL_SMALL_STACK
12766
   XFREE(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12767
#endif
12768
12769
   if (err == MP_OKAY) {
12770
       fp_cache[idx].LUT_set = 1;
12771
       return MP_OKAY;
12772
   }
12773
12774
   /* err cleanup */
12775
   for (y = 0; y < (1U<<FP_LUT); y++) {
12776
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
12777
      fp_cache[idx].LUT[y] = NULL;
12778
   }
12779
   wc_ecc_del_point(fp_cache[idx].g);
12780
   fp_cache[idx].g         = NULL;
12781
   fp_cache[idx].LUT_set   = 0;
12782
   fp_cache[idx].lru_count = 0;
12783
   mp_clear(&fp_cache[idx].mu);
12784
12785
   return err;
12786
}
12787
12788
/* perform a fixed point ECC mulmod */
12789
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
12790
                        mp_int* modulus, mp_digit mp, int map)
12791
{
12792
#ifdef WOLFCRYPT_HAVE_SAKKE
12793
    #define KB_SIZE 256
12794
#else
12795
    #define KB_SIZE 128
12796
#endif
12797
12798
#ifdef WOLFSSL_SMALL_STACK
12799
   unsigned char* kb = NULL;
12800
   mp_int*        tk = NULL;
12801
   mp_int*        order = NULL;
12802
#else
12803
   unsigned char kb[KB_SIZE];
12804
   mp_int        tk[1];
12805
   mp_int        order[1];
12806
#endif
12807
   int      x, err;
12808
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
12809
   int first;
12810
   int tk_zeroize = 0;
12811
12812
#ifdef WOLFSSL_SMALL_STACK
12813
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12814
   if (tk == NULL) {
12815
      err = MEMORY_E; goto done;
12816
   }
12817
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12818
   if (order == NULL) {
12819
      err = MEMORY_E; goto done;
12820
   }
12821
#endif
12822
12823
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
12824
       err = MP_INIT_E; goto done;
12825
   }
12826
12827
   if ((err = mp_copy(k, tk)) != MP_OKAY)
12828
       goto done;
12829
   tk_zeroize = 1;
12830
12831
#ifdef WOLFSSL_CHECK_MEM_ZERO
12832
   mp_memzero_add("accel_fp_mul tk", tk);
12833
#endif
12834
12835
   /* if it's smaller than modulus we fine */
12836
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
12837
      /* find order */
12838
       y = (unsigned)mp_unsigned_bin_size(modulus);
12839
      for (x = 0; ecc_sets[x].size; x++) {
12840
         if (y <= (unsigned)ecc_sets[x].size) break;
12841
      }
12842
12843
      /* back off if we are on the 521 bit curve */
12844
      if (y == 66) --x;
12845
12846
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12847
                                                MP_RADIX_HEX)) != MP_OKAY) {
12848
         goto done;
12849
      }
12850
12851
      /* k must be less than modulus */
12852
      if (mp_cmp(tk, order) != MP_LT) {
12853
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
12854
            goto done;
12855
         }
12856
      }
12857
   }
12858
12859
   /* get bitlen and round up to next multiple of FP_LUT */
12860
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12861
   x       = bitlen % FP_LUT;
12862
   if (x) {
12863
      bitlen += FP_LUT - (unsigned)x;
12864
   }
12865
   lut_gap = bitlen / FP_LUT;
12866
12867
   /* get the k value */
12868
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
12869
      err = BUFFER_E; goto done;
12870
   }
12871
12872
   /* store k */
12873
#ifdef WOLFSSL_SMALL_STACK
12874
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12875
   if (kb == NULL) {
12876
      err = MEMORY_E; goto done;
12877
   }
12878
#endif
12879
12880
   XMEMSET(kb, 0, KB_SIZE);
12881
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
12882
   #ifdef WOLFSSL_CHECK_MEM_ZERO
12883
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
12884
   #endif
12885
      /* let's reverse kb so it's little endian */
12886
      x = 0;
12887
      y = (unsigned)mp_unsigned_bin_size(tk);
12888
      if (y > 0) {
12889
          y -= 1;
12890
      }
12891
12892
      while ((unsigned)x < y) {
12893
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
12894
         ++x; --y;
12895
      }
12896
12897
      /* at this point we can start, yipee */
12898
      first = 1;
12899
      for (x = (int)lut_gap-1; x >= 0; x--) {
12900
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
12901
             by x bits from the start */
12902
          bitpos = (unsigned)x;
12903
          for (y = z = 0; y < FP_LUT; y++) {
12904
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
12905
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
12906
                                    the mult in each loop */
12907
          }
12908
12909
          /* double if not first */
12910
          if (!first) {
12911
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
12912
                                                              mp)) != MP_OKAY) {
12913
                break;
12914
             }
12915
          }
12916
12917
          /* add if not first, otherwise copy */
12918
          if (!first && z) {
12919
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
12920
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
12921
                break;
12922
             }
12923
          } else if (z) {
12924
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
12925
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
12926
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
12927
                 err = MP_MEM;
12928
                 break;
12929
             }
12930
             first = 0;
12931
          }
12932
      }
12933
   }
12934
12935
   if (err == MP_OKAY) {
12936
      (void) z; /* Acknowledge the unused assignment */
12937
      ForceZero(kb, KB_SIZE);
12938
12939
      /* map R back from projective space */
12940
      if (map) {
12941
         err = ecc_map(R, modulus, mp);
12942
      } else {
12943
         err = MP_OKAY;
12944
      }
12945
   }
12946
12947
done:
12948
   /* cleanup */
12949
   mp_clear(order);
12950
   /* Ensure it was initialized. */
12951
   if (tk_zeroize) {
12952
       mp_forcezero(tk);
12953
   }
12954
12955
#ifdef WOLFSSL_SMALL_STACK
12956
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12957
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12958
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12959
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
12960
   wc_MemZero_Check(kb, KB_SIZE);
12961
   mp_memzero_check(tk);
12962
#endif
12963
12964
#undef KB_SIZE
12965
12966
   return err;
12967
}
12968
#endif
12969
12970
#ifdef ECC_SHAMIR
12971
#if !defined(WOLFSSL_SP_MATH)
12972
/* perform a fixed point ECC mulmod */
12973
static int accel_fp_mul2add(int idx1, int idx2,
12974
                            mp_int* kA, mp_int* kB,
12975
                            ecc_point *R, mp_int* a,
12976
                            mp_int* modulus, mp_digit mp)
12977
{
12978
#define KB_SIZE 128
12979
12980
#ifdef WOLFSSL_SMALL_STACK
12981
   unsigned char* kb[2] = {NULL, NULL};
12982
   mp_int*        tka = NULL;
12983
   mp_int*        tkb = NULL;
12984
   mp_int*        order = NULL;
12985
#else
12986
   unsigned char kb[2][KB_SIZE];
12987
   mp_int        tka[1];
12988
   mp_int        tkb[1];
12989
   mp_int        order[1];
12990
#endif
12991
   int      x, err;
12992
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
12993
   int first;
12994
12995
#ifdef WOLFSSL_SMALL_STACK
12996
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12997
   if (tka == NULL) {
12998
      err = MEMORY_E; goto done;
12999
   }
13000
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13001
   if (tkb == NULL) {
13002
      err = MEMORY_E; goto done;
13003
   }
13004
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13005
   if (order == NULL) {
13006
      err = MEMORY_E; goto done;
13007
   }
13008
#endif
13009
13010
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
13011
      err = MP_INIT_E; goto done;
13012
   }
13013
13014
   /* if it's smaller than modulus we fine */
13015
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
13016
      /* find order */
13017
      y = (unsigned)mp_unsigned_bin_size(modulus);
13018
      for (x = 0; ecc_sets[x].size; x++) {
13019
         if (y <= (unsigned)ecc_sets[x].size) break;
13020
      }
13021
13022
      /* back off if we are on the 521 bit curve */
13023
      if (y == 66) --x;
13024
13025
      if ((err = mp_read_radix(order, ecc_sets[x].order,
13026
                                                MP_RADIX_HEX)) != MP_OKAY) {
13027
         goto done;
13028
      }
13029
13030
      /* kA must be less than modulus */
13031
      if (mp_cmp(kA, order) != MP_LT) {
13032
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
13033
            goto done;
13034
         }
13035
      } else {
13036
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
13037
            goto done;
13038
         }
13039
      }
13040
   } else {
13041
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
13042
         goto done;
13043
      }
13044
   }
13045
#ifdef WOLFSSL_CHECK_MEM_ZERO
13046
   mp_memzero_add("accel_fp_mul2add tka", tka);
13047
#endif
13048
13049
   /* if it's smaller than modulus we fine */
13050
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
13051
      /* find order */
13052
      y = (unsigned)mp_unsigned_bin_size(modulus);
13053
      for (x = 0; ecc_sets[x].size; x++) {
13054
         if (y <= (unsigned)ecc_sets[x].size) break;
13055
      }
13056
13057
      /* back off if we are on the 521 bit curve */
13058
      if (y == 66) --x;
13059
13060
      if ((err = mp_read_radix(order, ecc_sets[x].order,
13061
                                                MP_RADIX_HEX)) != MP_OKAY) {
13062
         goto done;
13063
      }
13064
13065
      /* kB must be less than modulus */
13066
      if (mp_cmp(kB, order) != MP_LT) {
13067
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
13068
            goto done;
13069
         }
13070
      } else {
13071
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13072
            goto done;
13073
         }
13074
      }
13075
   } else {
13076
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13077
         goto done;
13078
      }
13079
   }
13080
#ifdef WOLFSSL_CHECK_MEM_ZERO
13081
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
13082
#endif
13083
13084
   /* get bitlen and round up to next multiple of FP_LUT */
13085
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13086
   x       = bitlen % FP_LUT;
13087
   if (x) {
13088
      bitlen += FP_LUT - (unsigned)x;
13089
   }
13090
   lut_gap = bitlen / FP_LUT;
13091
13092
   /* get the k value */
13093
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
13094
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
13095
      err = BUFFER_E; goto done;
13096
   }
13097
13098
   /* store k */
13099
#ifdef WOLFSSL_SMALL_STACK
13100
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13101
   if (kb[0] == NULL) {
13102
      err = MEMORY_E; goto done;
13103
   }
13104
#endif
13105
13106
   XMEMSET(kb[0], 0, KB_SIZE);
13107
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13108
      goto done;
13109
   }
13110
#ifdef WOLFSSL_CHECK_MEM_ZERO
13111
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13112
#endif
13113
13114
   /* let's reverse kb so it's little endian */
13115
   x = 0;
13116
   y = (unsigned)mp_unsigned_bin_size(tka);
13117
   if (y > 0) {
13118
       y -= 1;
13119
   }
13120
   mp_clear(tka);
13121
   while ((unsigned)x < y) {
13122
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13123
      ++x; --y;
13124
   }
13125
13126
   /* store b */
13127
#ifdef WOLFSSL_SMALL_STACK
13128
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13129
   if (kb[1] == NULL) {
13130
      err = MEMORY_E; goto done;
13131
   }
13132
#endif
13133
13134
   XMEMSET(kb[1], 0, KB_SIZE);
13135
#ifdef WOLFSSL_CHECK_MEM_ZERO
13136
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13137
#endif
13138
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13139
      x = 0;
13140
      y = (unsigned)mp_unsigned_bin_size(tkb);
13141
      if (y > 0) {
13142
          y -= 1;
13143
      }
13144
13145
      while ((unsigned)x < y) {
13146
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13147
         ++x; --y;
13148
      }
13149
13150
      /* at this point we can start, yipee */
13151
      first = 1;
13152
      for (x = (int)lut_gap-1; x >= 0; x--) {
13153
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13154
             offset by x bits from the start */
13155
          bitpos = (unsigned)x;
13156
          for (y = zA = zB = 0; y < FP_LUT; y++) {
13157
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13158
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13159
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13160
                                      the mult in each loop */
13161
          }
13162
13163
          /* double if not first */
13164
          if (!first) {
13165
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13166
                                                              mp)) != MP_OKAY) {
13167
                break;
13168
             }
13169
13170
             /* add if not first, otherwise copy */
13171
             if (zA) {
13172
                if ((err = ecc_projective_add_point_safe(R,
13173
                                             fp_cache[idx1].LUT[zA], R, a,
13174
                                             modulus, mp, &first)) != MP_OKAY) {
13175
                   break;
13176
                }
13177
             }
13178
13179
             if (zB) {
13180
                if ((err = ecc_projective_add_point_safe(R,
13181
                                             fp_cache[idx2].LUT[zB], R, a,
13182
                                             modulus, mp, &first)) != MP_OKAY) {
13183
                   break;
13184
                }
13185
             }
13186
          } else {
13187
             if (zA) {
13188
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13189
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13190
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13191
                     err = MP_MEM;
13192
                     break;
13193
                 }
13194
                    first = 0;
13195
             }
13196
             if (zB && first == 0) {
13197
                if ((err = ecc_projective_add_point_safe(R,
13198
                                        fp_cache[idx2].LUT[zB], R, a,
13199
                                        modulus, mp, &first)) != MP_OKAY){
13200
                   break;
13201
                }
13202
             } else if (zB && first == 1) {
13203
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13204
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13205
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13206
                     err = MP_MEM;
13207
                     break;
13208
                 }
13209
                    first = 0;
13210
             }
13211
          }
13212
      }
13213
   }
13214
13215
done:
13216
   /* cleanup */
13217
   mp_forcezero(tkb);
13218
   mp_forcezero(tka);
13219
   mp_clear(order);
13220
13221
#ifdef WOLFSSL_SMALL_STACK
13222
   if (kb[0])
13223
#endif
13224
      ForceZero(kb[0], KB_SIZE);
13225
#ifdef WOLFSSL_SMALL_STACK
13226
   if (kb[1])
13227
#endif
13228
      ForceZero(kb[1], KB_SIZE);
13229
13230
#ifdef WOLFSSL_SMALL_STACK
13231
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13232
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13233
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13234
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13235
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13236
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13237
   wc_MemZero_Check(kb[1], KB_SIZE);
13238
   wc_MemZero_Check(kb[0], KB_SIZE);
13239
   mp_memzero_check(tkb);
13240
   mp_memzero_check(tka);
13241
#endif
13242
13243
#undef KB_SIZE
13244
13245
    if (err != MP_OKAY)
13246
        return err;
13247
13248
   return ecc_map(R, modulus, mp);
13249
}
13250
13251
13252
/** ECC Fixed Point mulmod global with heap hint used
13253
  Computes kA*A + kB*B = C using Shamir's Trick
13254
  A        First point to multiply
13255
  kA       What to multiple A by
13256
  B        Second point to multiply
13257
  kB       What to multiple B by
13258
  C        [out] Destination point (can overlap with A or B)
13259
  a        ECC curve parameter a
13260
  modulus  Modulus for curve
13261
  return MP_OKAY on success
13262
*/
13263
int ecc_mul2add(ecc_point* A, mp_int* kA,
13264
                ecc_point* B, mp_int* kB,
13265
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13266
{
13267
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13268
   mp_digit mp = 0;
13269
#ifdef WOLFSSL_SMALL_STACK
13270
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13271
13272
   if (mu == NULL)
13273
       return MP_MEM;
13274
#else
13275
   mp_int   mu[1];
13276
#endif
13277
13278
   err = mp_init(mu);
13279
   if (err != MP_OKAY) {
13280
#ifdef WOLFSSL_SMALL_STACK
13281
       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13282
#endif
13283
       return err;
13284
   }
13285
13286
#ifndef HAVE_THREAD_LS
13287
#ifndef WOLFSSL_MUTEX_INITIALIZER
13288
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13289
        wc_InitMutex(&ecc_fp_lock);
13290
        initMutex = 1;
13291
   }
13292
#endif
13293
13294
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13295
#ifdef WOLFSSL_SMALL_STACK
13296
       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13297
#endif
13298
      return BAD_MUTEX_E;
13299
   }
13300
#endif /* HAVE_THREAD_LS */
13301
13302
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13303
13304
      /* find point */
13305
      idx1 = find_base(A);
13306
13307
      /* no entry? */
13308
      if (idx1 == -1) {
13309
         /* find hole and add it */
13310
         if ((idx1 = find_hole()) >= 0) {
13311
            err = add_entry(idx1, A);
13312
         }
13313
      }
13314
      if (err == MP_OKAY && idx1 != -1) {
13315
         /* increment LRU */
13316
         ++(fp_cache[idx1].lru_count);
13317
      }
13318
13319
      if (err == MP_OKAY) {
13320
        /* find point */
13321
        idx2 = find_base(B);
13322
13323
        /* no entry? */
13324
        if (idx2 == -1) {
13325
           /* find hole and add it */
13326
           if ((idx2 = find_hole()) >= 0)
13327
              err = add_entry(idx2, B);
13328
         }
13329
      }
13330
13331
      if (err == MP_OKAY && idx2 != -1) {
13332
         /* increment LRU */
13333
         ++(fp_cache[idx2].lru_count);
13334
      }
13335
13336
      if (err == MP_OKAY) {
13337
        /* if it's >= 2 AND the LUT is not set build the LUT */
13338
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13339
           /* compute mp */
13340
           err = mp_montgomery_setup(modulus, &mp);
13341
13342
           if (err == MP_OKAY) {
13343
             mpInit = 1;
13344
             err = mp_montgomery_calc_normalization(mu, modulus);
13345
           }
13346
13347
           if (err == MP_OKAY)
13348
             /* build the LUT */
13349
             err = build_lut(idx1, a, modulus, mp, mu);
13350
        }
13351
      }
13352
13353
      if (err == MP_OKAY) {
13354
        /* if it's >= 2 AND the LUT is not set build the LUT */
13355
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13356
           if (mpInit == 0) {
13357
                /* compute mp */
13358
                err = mp_montgomery_setup(modulus, &mp);
13359
                if (err == MP_OKAY) {
13360
                    mpInit = 1;
13361
                    err = mp_montgomery_calc_normalization(mu, modulus);
13362
                }
13363
            }
13364
13365
            if (err == MP_OKAY)
13366
              /* build the LUT */
13367
              err = build_lut(idx2, a, modulus, mp, mu);
13368
        }
13369
      }
13370
13371
13372
      if (err == MP_OKAY) {
13373
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13374
                                     fp_cache[idx2].LUT_set) {
13375
           if (mpInit == 0) {
13376
              /* compute mp */
13377
              err = mp_montgomery_setup(modulus, &mp);
13378
           }
13379
           if (err == MP_OKAY)
13380
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13381
        } else {
13382
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13383
        }
13384
      }
13385
13386
      RESTORE_VECTOR_REGISTERS();
13387
13388
#ifndef HAVE_THREAD_LS
13389
    wc_UnLockMutex(&ecc_fp_lock);
13390
#endif /* HAVE_THREAD_LS */
13391
    mp_clear(mu);
13392
#ifdef WOLFSSL_SMALL_STACK
13393
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13394
#endif
13395
13396
    return err;
13397
}
13398
#endif
13399
#endif /* ECC_SHAMIR */
13400
13401
/** ECC Fixed Point mulmod global
13402
    k        The multiplicand
13403
    G        Base point to multiply
13404
    R        [out] Destination of product
13405
    a        ECC curve parameter a
13406
    modulus  The modulus for the curve
13407
    map      [boolean] If non-zero maps the point back to affine coordinates,
13408
             otherwise it's left in jacobian-montgomery form
13409
    return MP_OKAY if successful
13410
*/
13411
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13412
    mp_int* modulus, int map, void* heap)
13413
{
13414
#if !defined(WOLFSSL_SP_MATH)
13415
   int   idx, err = MP_OKAY;
13416
   mp_digit mp = 0;
13417
#ifdef WOLFSSL_SMALL_STACK
13418
   mp_int   *mu = NULL;
13419
#else
13420
   mp_int   mu[1];
13421
#endif
13422
   int      mpSetup = 0;
13423
#ifndef HAVE_THREAD_LS
13424
   int got_ecc_fp_lock = 0;
13425
#endif
13426
13427
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13428
       return ECC_BAD_ARG_E;
13429
   }
13430
13431
   /* k can't have more bits than modulus count plus 1 */
13432
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13433
      return ECC_OUT_OF_RANGE_E;
13434
   }
13435
13436
#ifdef WOLFSSL_SMALL_STACK
13437
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13438
       return MP_MEM;
13439
#endif
13440
13441
   if (mp_init(mu) != MP_OKAY) {
13442
       err = MP_INIT_E;
13443
       goto out;
13444
   }
13445
13446
#ifndef HAVE_THREAD_LS
13447
#ifndef WOLFSSL_MUTEX_INITIALIZER
13448
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13449
        wc_InitMutex(&ecc_fp_lock);
13450
        initMutex = 1;
13451
   }
13452
#endif
13453
13454
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13455
      err = BAD_MUTEX_E;
13456
      goto out;
13457
   }
13458
   got_ecc_fp_lock = 1;
13459
#endif /* HAVE_THREAD_LS */
13460
13461
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13462
13463
      /* find point */
13464
      idx = find_base(G);
13465
13466
      /* no entry? */
13467
      if (idx == -1) {
13468
         /* find hole and add it */
13469
         idx = find_hole();
13470
13471
         if (idx >= 0)
13472
            err = add_entry(idx, G);
13473
      }
13474
      if (err == MP_OKAY && idx >= 0) {
13475
         /* increment LRU */
13476
         ++(fp_cache[idx].lru_count);
13477
      }
13478
13479
13480
      if (err == MP_OKAY) {
13481
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13482
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13483
           /* compute mp */
13484
           err = mp_montgomery_setup(modulus, &mp);
13485
13486
           if (err == MP_OKAY) {
13487
             /* compute mu */
13488
             mpSetup = 1;
13489
             err = mp_montgomery_calc_normalization(mu, modulus);
13490
           }
13491
13492
           if (err == MP_OKAY)
13493
             /* build the LUT */
13494
             err = build_lut(idx, a, modulus, mp, mu);
13495
        }
13496
      }
13497
13498
      if (err == MP_OKAY) {
13499
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13500
           if (mpSetup == 0) {
13501
              /* compute mp */
13502
              err = mp_montgomery_setup(modulus, &mp);
13503
           }
13504
           if (err == MP_OKAY)
13505
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13506
        } else {
13507
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
13508
        }
13509
      }
13510
13511
      RESTORE_VECTOR_REGISTERS();
13512
13513
  out:
13514
13515
#ifndef HAVE_THREAD_LS
13516
    if (got_ecc_fp_lock)
13517
        wc_UnLockMutex(&ecc_fp_lock);
13518
#endif /* HAVE_THREAD_LS */
13519
    mp_clear(mu);
13520
#ifdef WOLFSSL_SMALL_STACK
13521
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13522
#endif
13523
13524
    return err;
13525
13526
#else /* WOLFSSL_SP_MATH */
13527
13528
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13529
        return ECC_BAD_ARG_E;
13530
    }
13531
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13532
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13533
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13534
        return IS_POINT_E;
13535
    }
13536
13537
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13538
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13539
        int ret;
13540
        SAVE_VECTOR_REGISTERS(return _svr_ret);
13541
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13542
        RESTORE_VECTOR_REGISTERS();
13543
        return ret;
13544
    }
13545
#endif
13546
#ifndef WOLFSSL_SP_NO_256
13547
    if (mp_count_bits(modulus) == 256) {
13548
        int ret;
13549
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13550
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13551
        RESTORE_VECTOR_REGISTERS();
13552
        return ret;
13553
    }
13554
#endif
13555
#ifdef WOLFSSL_SP_384
13556
    if (mp_count_bits(modulus) == 384) {
13557
        int ret;
13558
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13559
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13560
        RESTORE_VECTOR_REGISTERS();
13561
        return ret;
13562
    }
13563
#endif
13564
#ifdef WOLFSSL_SP_521
13565
    if (mp_count_bits(modulus) == 521) {
13566
        int ret;
13567
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13568
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13569
        RESTORE_VECTOR_REGISTERS();
13570
        return ret;
13571
    }
13572
#endif
13573
    return WC_KEY_SIZE_E;
13574
#endif /* WOLFSSL_SP_MATH */
13575
}
13576
13577
/** ECC Fixed Point mulmod global
13578
    k        The multiplicand
13579
    G        Base point to multiply
13580
    R        [out] Destination of product
13581
    a        ECC curve parameter a
13582
    modulus  The modulus for the curve
13583
    map      [boolean] If non-zero maps the point back to affine coordinates,
13584
             otherwise it's left in jacobian-montgomery form
13585
    return MP_OKAY if successful
13586
*/
13587
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13588
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
13589
{
13590
#if !defined(WOLFSSL_SP_MATH)
13591
   int   idx, err = MP_OKAY;
13592
   mp_digit mp = 0;
13593
#ifdef WOLFSSL_SMALL_STACK
13594
   mp_int   *mu = NULL;
13595
#else
13596
   mp_int   mu[1];
13597
#endif
13598
   int      mpSetup = 0;
13599
#ifndef HAVE_THREAD_LS
13600
   int got_ecc_fp_lock = 0;
13601
#endif
13602
13603
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13604
                                                                order == NULL) {
13605
       return ECC_BAD_ARG_E;
13606
   }
13607
13608
   /* k can't have more bits than order */
13609
   if (mp_count_bits(k) > mp_count_bits(order)) {
13610
      return ECC_OUT_OF_RANGE_E;
13611
   }
13612
13613
#ifdef WOLFSSL_SMALL_STACK
13614
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13615
       return MP_MEM;
13616
#endif
13617
13618
   if (mp_init(mu) != MP_OKAY) {
13619
       err = MP_INIT_E;
13620
       goto out;
13621
   }
13622
13623
#ifndef HAVE_THREAD_LS
13624
#ifndef WOLFSSL_MUTEX_INITIALIZER
13625
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13626
        wc_InitMutex(&ecc_fp_lock);
13627
        initMutex = 1;
13628
   }
13629
#endif
13630
13631
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13632
      err = BAD_MUTEX_E;
13633
      goto out;
13634
   }
13635
   got_ecc_fp_lock = 1;
13636
#endif /* HAVE_THREAD_LS */
13637
13638
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13639
13640
      /* find point */
13641
      idx = find_base(G);
13642
13643
      /* no entry? */
13644
      if (idx == -1) {
13645
         /* find hole and add it */
13646
         idx = find_hole();
13647
13648
         if (idx >= 0)
13649
            err = add_entry(idx, G);
13650
      }
13651
      if (err == MP_OKAY && idx >= 0) {
13652
         /* increment LRU */
13653
         ++(fp_cache[idx].lru_count);
13654
      }
13655
13656
13657
      if (err == MP_OKAY) {
13658
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13659
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13660
           /* compute mp */
13661
           err = mp_montgomery_setup(modulus, &mp);
13662
13663
           if (err == MP_OKAY) {
13664
             /* compute mu */
13665
             mpSetup = 1;
13666
             err = mp_montgomery_calc_normalization(mu, modulus);
13667
           }
13668
13669
           if (err == MP_OKAY)
13670
             /* build the LUT */
13671
             err = build_lut(idx, a, modulus, mp, mu);
13672
        }
13673
      }
13674
13675
      if (err == MP_OKAY) {
13676
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13677
           if (mpSetup == 0) {
13678
              /* compute mp */
13679
              err = mp_montgomery_setup(modulus, &mp);
13680
           }
13681
           if (err == MP_OKAY)
13682
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13683
        } else {
13684
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
13685
        }
13686
      }
13687
13688
      RESTORE_VECTOR_REGISTERS();
13689
13690
  out:
13691
13692
#ifndef HAVE_THREAD_LS
13693
    if (got_ecc_fp_lock)
13694
        wc_UnLockMutex(&ecc_fp_lock);
13695
#endif /* HAVE_THREAD_LS */
13696
    mp_clear(mu);
13697
#ifdef WOLFSSL_SMALL_STACK
13698
    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13699
#endif
13700
13701
    return err;
13702
13703
#else /* WOLFSSL_SP_MATH */
13704
13705
    (void)rng;
13706
13707
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13708
                                                                order == NULL) {
13709
        return ECC_BAD_ARG_E;
13710
    }
13711
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13712
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13713
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13714
        return IS_POINT_E;
13715
    }
13716
13717
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13718
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13719
        int ret;
13720
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13721
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13722
        RESTORE_VECTOR_REGISTERS();
13723
        return ret;
13724
    }
13725
#endif
13726
#ifndef WOLFSSL_SP_NO_256
13727
    if (mp_count_bits(modulus) == 256) {
13728
        int ret;
13729
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13730
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13731
        RESTORE_VECTOR_REGISTERS();
13732
        return ret;
13733
    }
13734
#endif
13735
#ifdef WOLFSSL_SP_384
13736
    if (mp_count_bits(modulus) == 384) {
13737
        int ret;
13738
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13739
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13740
        RESTORE_VECTOR_REGISTERS();
13741
        return ret;
13742
    }
13743
#endif
13744
#ifdef WOLFSSL_SP_521
13745
    if (mp_count_bits(modulus) == 521) {
13746
        int ret;
13747
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13748
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13749
        RESTORE_VECTOR_REGISTERS();
13750
        return ret;
13751
    }
13752
#endif
13753
    return WC_KEY_SIZE_E;
13754
#endif /* WOLFSSL_SP_MATH */
13755
}
13756
13757
#if !defined(WOLFSSL_SP_MATH)
13758
/* helper function for freeing the cache ...
13759
   must be called with the cache mutex locked */
13760
static void wc_ecc_fp_free_cache(void)
13761
{
13762
   unsigned x, y;
13763
   for (x = 0; x < FP_ENTRIES; x++) {
13764
      if (fp_cache[x].g != NULL) {
13765
         for (y = 0; y < (1U<<FP_LUT); y++) {
13766
            wc_ecc_del_point(fp_cache[x].LUT[y]);
13767
            fp_cache[x].LUT[y] = NULL;
13768
         }
13769
         wc_ecc_del_point(fp_cache[x].g);
13770
         fp_cache[x].g         = NULL;
13771
         mp_clear(&fp_cache[x].mu);
13772
         fp_cache[x].LUT_set   = 0;
13773
         fp_cache[x].lru_count = 0;
13774
         fp_cache[x].lock = 0;
13775
      }
13776
   }
13777
}
13778
#endif
13779
13780
13781
/** Init the Fixed Point cache */
13782
void wc_ecc_fp_init(void)
13783
{
13784
#ifndef WOLFSSL_SP_MATH
13785
#ifndef HAVE_THREAD_LS
13786
#ifndef WOLFSSL_MUTEX_INITIALIZER
13787
   if (initMutex == 0) {
13788
        wc_InitMutex(&ecc_fp_lock);
13789
        initMutex = 1;
13790
   }
13791
#endif
13792
#endif
13793
#endif
13794
}
13795
13796
13797
/** Free the Fixed Point cache */
13798
WOLFSSL_ABI
13799
void wc_ecc_fp_free(void)
13800
{
13801
#if !defined(WOLFSSL_SP_MATH)
13802
#ifndef HAVE_THREAD_LS
13803
#ifndef WOLFSSL_MUTEX_INITIALIZER
13804
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13805
        wc_InitMutex(&ecc_fp_lock);
13806
        initMutex = 1;
13807
   }
13808
#endif
13809
13810
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
13811
#endif /* HAVE_THREAD_LS */
13812
13813
       wc_ecc_fp_free_cache();
13814
13815
#ifndef HAVE_THREAD_LS
13816
       wc_UnLockMutex(&ecc_fp_lock);
13817
#ifndef WOLFSSL_MUTEX_INITIALIZER
13818
       wc_FreeMutex(&ecc_fp_lock);
13819
       initMutex = 0;
13820
#endif
13821
   }
13822
#endif /* HAVE_THREAD_LS */
13823
#endif
13824
}
13825
13826
13827
#endif /* FP_ECC */
13828
13829
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
13830
0
{
13831
0
    int err = 0;
13832
13833
0
#ifdef ECC_TIMING_RESISTANT
13834
0
    if (key == NULL) {
13835
0
        err = BAD_FUNC_ARG;
13836
0
    }
13837
0
    else {
13838
0
        key->rng = rng;
13839
0
    }
13840
#else
13841
    (void)key;
13842
    (void)rng;
13843
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
13844
#endif
13845
13846
0
    return err;
13847
0
}
13848
13849
#ifdef HAVE_ECC_ENCRYPT
13850
13851
13852
enum ecCliState {
13853
    ecCLI_INIT      = 1,
13854
    ecCLI_SALT_GET  = 2,
13855
    ecCLI_SALT_SET  = 3,
13856
    ecCLI_SENT_REQ  = 4,
13857
    ecCLI_RECV_RESP = 5,
13858
    ecCLI_BAD_STATE = 99
13859
};
13860
13861
enum ecSrvState {
13862
    ecSRV_INIT      = 1,
13863
    ecSRV_SALT_GET  = 2,
13864
    ecSRV_SALT_SET  = 3,
13865
    ecSRV_RECV_REQ  = 4,
13866
    ecSRV_SENT_RESP = 5,
13867
    ecSRV_BAD_STATE = 99
13868
};
13869
13870
13871
struct ecEncCtx {
13872
    const byte* kdfSalt;   /* optional salt for kdf */
13873
    const byte* kdfInfo;   /* optional info for kdf */
13874
    const byte* macSalt;   /* optional salt for mac */
13875
    word32    kdfSaltSz;   /* size of kdfSalt */
13876
    word32    kdfInfoSz;   /* size of kdfInfo */
13877
    word32    macSaltSz;   /* size of macSalt */
13878
    void*     heap;        /* heap hint for memory used */
13879
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13880
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13881
    byte      encAlgo;     /* which encryption type */
13882
    byte      kdfAlgo;     /* which key derivation function type */
13883
    byte      macAlgo;     /* which mac function type */
13884
    byte      protocol;    /* are we REQ_RESP client or server ? */
13885
    byte      cliSt;       /* protocol state, for sanity checks */
13886
    byte      srvSt;       /* protocol state, for sanity checks */
13887
    WC_RNG*   rng;
13888
};
13889
13890
/* optional set info, can be called before or after set_peer_salt */
13891
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
13892
{
13893
    if (ctx == NULL)
13894
        return BAD_FUNC_ARG;
13895
13896
    ctx->encAlgo = encAlgo;
13897
    ctx->kdfAlgo = kdfAlgo;
13898
    ctx->macAlgo = macAlgo;
13899
13900
    return 0;
13901
}
13902
13903
13904
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
13905
{
13906
    if (ctx == NULL || ctx->protocol == 0)
13907
        return NULL;
13908
13909
    if (ctx->protocol == REQ_RESP_CLIENT) {
13910
        if (ctx->cliSt == ecCLI_INIT) {
13911
            ctx->cliSt =  ecCLI_SALT_GET;
13912
            return ctx->clientSalt;
13913
        }
13914
        else {
13915
            ctx->cliSt = ecCLI_BAD_STATE;
13916
            return NULL;
13917
        }
13918
    }
13919
    else if (ctx->protocol == REQ_RESP_SERVER) {
13920
        if (ctx->srvSt == ecSRV_INIT) {
13921
            ctx->srvSt =  ecSRV_SALT_GET;
13922
            return ctx->serverSalt;
13923
        }
13924
        else {
13925
            ctx->srvSt = ecSRV_BAD_STATE;
13926
            return NULL;
13927
        }
13928
    }
13929
13930
    return NULL;
13931
}
13932
13933
13934
/* optional set info, can be called before or after set_peer_salt */
13935
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
13936
{
13937
    if (ctx == NULL || info == 0 || sz < 0)
13938
        return BAD_FUNC_ARG;
13939
13940
    ctx->kdfInfo   = info;
13941
    ctx->kdfInfoSz = (word32)sz;
13942
13943
    return 0;
13944
}
13945
13946
13947
static const char* exchange_info = "Secure Message Exchange";
13948
13949
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
13950
{
13951
    byte tmp[EXCHANGE_SALT_SZ/2];
13952
    int  halfSz = EXCHANGE_SALT_SZ/2;
13953
13954
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13955
        return BAD_FUNC_ARG;
13956
13957
    if (ctx->protocol == REQ_RESP_CLIENT) {
13958
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
13959
        if (ctx->cliSt == ecCLI_SALT_GET)
13960
            ctx->cliSt =  ecCLI_SALT_SET;
13961
        else {
13962
            ctx->cliSt =  ecCLI_BAD_STATE;
13963
            return BAD_STATE_E;
13964
        }
13965
    }
13966
    else {
13967
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
13968
        if (ctx->srvSt == ecSRV_SALT_GET)
13969
            ctx->srvSt =  ecSRV_SALT_SET;
13970
        else {
13971
            ctx->srvSt =  ecSRV_BAD_STATE;
13972
            return BAD_STATE_E;
13973
        }
13974
    }
13975
13976
    /* mix half and half */
13977
    /* tmp stores 2nd half of client before overwrite */
13978
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
13979
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
13980
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
13981
13982
    ctx->kdfSalt   = ctx->clientSalt;
13983
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
13984
13985
    ctx->macSalt   = ctx->serverSalt;
13986
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
13987
13988
    if (ctx->kdfInfo == NULL) {
13989
        /* default info */
13990
        ctx->kdfInfo   = (const byte*)exchange_info;
13991
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
13992
    }
13993
13994
    return 0;
13995
}
13996
13997
/* Set the salt pointer into context.
13998
 *
13999
 * @param  [in, out]  ctx   ECIES context object.
14000
 * @param  [in]       salt  Salt to use with KDF.
14001
 * @param  [in]       sz    Length of salt in bytes.
14002
 * @return  0 on success.
14003
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
14004
 */
14005
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
14006
{
14007
    if (ctx == NULL || (salt == NULL && sz != 0))
14008
        return BAD_FUNC_ARG;
14009
14010
    /* truncate salt if exceeds max */
14011
    if (sz > EXCHANGE_SALT_SZ)
14012
        sz = EXCHANGE_SALT_SZ;
14013
14014
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
14015
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
14016
    if (ctx->protocol == REQ_RESP_CLIENT) {
14017
        ctx->cliSt = ecCLI_SALT_SET;
14018
        ctx->kdfSalt = ctx->clientSalt;
14019
    }
14020
    else if (ctx->protocol == REQ_RESP_SERVER) {
14021
        ctx->srvSt = ecSRV_SALT_SET;
14022
        ctx->kdfSalt = ctx->serverSalt;
14023
    }
14024
14025
    if (salt != NULL) {
14026
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
14027
    }
14028
    ctx->kdfSaltSz = sz;
14029
14030
    return 0;
14031
}
14032
14033
/* Set your own salt. By default we generate a random salt for ourselves.
14034
 * This allows overriding that after init or reset.
14035
 *
14036
 * @param  [in, out]  ctx   ECIES context object.
14037
 * @param  [in]       salt  Salt to use for ourselves
14038
 * @param  [in]       sz    Length of salt in bytes.
14039
 * @return  0 on success.
14040
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
14041
 */
14042
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
14043
{
14044
    byte* saltBuffer;
14045
14046
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
14047
        return BAD_FUNC_ARG;
14048
14049
    if (sz > EXCHANGE_SALT_SZ)
14050
        sz = EXCHANGE_SALT_SZ;
14051
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
14052
        ctx->clientSalt :
14053
        ctx->serverSalt;
14054
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
14055
    XMEMCPY(saltBuffer, salt, sz);
14056
14057
    return 0;
14058
}
14059
14060
14061
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
14062
{
14063
    byte* saltBuffer;
14064
14065
    if (ctx == NULL || flags == 0)
14066
        return BAD_FUNC_ARG;
14067
14068
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
14069
14070
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
14071
}
14072
14073
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
14074
{
14075
    if (ctx) {
14076
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
14077
14078
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14079
        #ifdef WOLFSSL_AES_128
14080
            ctx->encAlgo  = ecAES_128_CBC;
14081
        #else
14082
            ctx->encAlgo  = ecAES_256_CBC;
14083
        #endif
14084
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14085
        #ifdef WOLFSSL_AES_256
14086
            ctx->encAlgo  = ecAES_256_CTR;
14087
        #else
14088
            ctx->encAlgo  = ecAES_128_CTR;
14089
        #endif
14090
    #else
14091
        #error "No valid encryption algorithm for ECIES configured."
14092
    #endif
14093
        ctx->kdfAlgo  = ecHKDF_SHA256;
14094
        ctx->macAlgo  = ecHMAC_SHA256;
14095
        ctx->protocol = (byte)flags;
14096
        ctx->rng      = rng;
14097
14098
        if (flags == REQ_RESP_CLIENT)
14099
            ctx->cliSt = ecCLI_INIT;
14100
        if (flags == REQ_RESP_SERVER)
14101
            ctx->srvSt = ecSRV_INIT;
14102
    }
14103
}
14104
14105
14106
/* allow ecc context reset so user doesn't have to init/free for reuse */
14107
WOLFSSL_ABI
14108
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
14109
{
14110
    if (ctx == NULL || rng == NULL)
14111
        return BAD_FUNC_ARG;
14112
14113
    ecc_ctx_init(ctx, ctx->protocol, rng);
14114
    return ecc_ctx_set_salt(ctx, ctx->protocol);
14115
}
14116
14117
14118
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14119
{
14120
    int       ret = 0;
14121
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14122
                                                              DYNAMIC_TYPE_ECC);
14123
14124
    if (ctx) {
14125
        ctx->protocol = (byte)flags;
14126
        ctx->heap     = heap;
14127
    }
14128
14129
    ret = wc_ecc_ctx_reset(ctx, rng);
14130
    if (ret != 0) {
14131
        wc_ecc_ctx_free(ctx);
14132
        ctx = NULL;
14133
    }
14134
14135
    return ctx;
14136
}
14137
14138
14139
/* alloc/init and set defaults, return new Context  */
14140
WOLFSSL_ABI
14141
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14142
{
14143
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14144
}
14145
14146
14147
/* free any resources, clear any keys */
14148
WOLFSSL_ABI
14149
void wc_ecc_ctx_free(ecEncCtx* ctx)
14150
{
14151
    if (ctx) {
14152
        void* heap = ctx->heap;
14153
        ForceZero(ctx, sizeof(ecEncCtx));
14154
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14155
        (void)heap;
14156
    }
14157
}
14158
14159
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14160
                             int* keysLen, word32* digestSz, word32* blockSz)
14161
{
14162
    if (ctx) {
14163
        switch (ctx->encAlgo) {
14164
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14165
            case ecAES_128_CBC:
14166
                *encKeySz = KEY_SIZE_128;
14167
                *ivSz     = IV_SIZE_128;
14168
                *blockSz  = WC_AES_BLOCK_SIZE;
14169
                break;
14170
            case ecAES_256_CBC:
14171
                *encKeySz = KEY_SIZE_256;
14172
                *ivSz     = IV_SIZE_128;
14173
                *blockSz  = WC_AES_BLOCK_SIZE;
14174
                break;
14175
        #endif
14176
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14177
            case ecAES_128_CTR:
14178
                *encKeySz = KEY_SIZE_128;
14179
                *ivSz     = 12;
14180
                *blockSz  = 1;
14181
                break;
14182
            case ecAES_256_CTR:
14183
                *encKeySz = KEY_SIZE_256;
14184
                *ivSz     = 12;
14185
                *blockSz  = 1;
14186
                break;
14187
        #endif
14188
            default:
14189
                return BAD_FUNC_ARG;
14190
        }
14191
14192
        switch (ctx->macAlgo) {
14193
            case ecHMAC_SHA256:
14194
                *digestSz = WC_SHA256_DIGEST_SIZE;
14195
                break;
14196
            default:
14197
                return BAD_FUNC_ARG;
14198
        }
14199
    } else
14200
        return BAD_FUNC_ARG;
14201
14202
#ifdef WOLFSSL_ECIES_OLD
14203
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14204
#else
14205
    *keysLen  = *encKeySz + (int)*digestSz;
14206
#endif
14207
14208
    return 0;
14209
}
14210
14211
14212
/* ecc encrypt with shared secret run through kdf
14213
   ctx holds non default algos and inputs
14214
   msgSz should be the right size for encAlgo, i.e., already padded
14215
   return 0 on success */
14216
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14217
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14218
{
14219
    int          ret = 0;
14220
    word32       blockSz = 0;
14221
#ifndef WOLFSSL_ECIES_OLD
14222
#ifndef WOLFSSL_ECIES_GEN_IV
14223
    byte         iv[ECC_MAX_IV_SIZE];
14224
#endif
14225
    word32       pubKeySz = 0;
14226
#endif
14227
    word32       digestSz = 0;
14228
    ecEncCtx     localCtx;
14229
#ifdef WOLFSSL_SMALL_STACK
14230
    byte*        sharedSecret;
14231
    byte*        keys;
14232
#else
14233
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14234
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14235
#else
14236
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14237
#endif
14238
    byte         keys[ECC_BUFSIZE];         /* max size */
14239
#endif
14240
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14241
    word32       sharedSz = ECC_MAXSIZE;
14242
#else
14243
    /* 'Uncompressed' byte | public key x | public key y | secret */
14244
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14245
#endif
14246
    int          keysLen = 0;
14247
    int          encKeySz = 0;
14248
    int          ivSz = 0;
14249
    int          offset = 0;         /* keys offset if doing msg exchange */
14250
    byte*        encKey = NULL;
14251
    byte*        encIv = NULL;
14252
    byte*        macKey = NULL;
14253
14254
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14255
                           outSz  == NULL)
14256
        return BAD_FUNC_ARG;
14257
14258
    if (ctx == NULL) {  /* use defaults */
14259
        ecc_ctx_init(&localCtx, 0, NULL);
14260
        ctx = &localCtx;
14261
    }
14262
14263
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14264
                            &blockSz);
14265
    if (ret != 0)
14266
        return ret;
14267
14268
#ifndef WOLFSSL_ECIES_OLD
14269
    if (!compressed) {
14270
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14271
    }
14272
    else {
14273
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14274
    }
14275
#else
14276
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14277
#endif
14278
14279
    if (ctx->protocol == REQ_RESP_SERVER) {
14280
        offset = keysLen;
14281
        keysLen *= 2;
14282
14283
        if (ctx->srvSt != ecSRV_RECV_REQ)
14284
            return BAD_STATE_E;
14285
14286
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14287
    }
14288
    else if (ctx->protocol == REQ_RESP_CLIENT) {
14289
        if (ctx->cliSt != ecCLI_SALT_SET)
14290
            return BAD_STATE_E;
14291
14292
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14293
    }
14294
14295
    if (keysLen > ECC_BUFSIZE) /* keys size */
14296
        return BUFFER_E;
14297
14298
    if ((msgSz % blockSz) != 0)
14299
        return BAD_PADDING_E;
14300
14301
#ifdef WOLFSSL_ECIES_OLD
14302
    if (*outSz < (msgSz + digestSz))
14303
        return BUFFER_E;
14304
#elif defined(WOLFSSL_ECIES_GEN_IV)
14305
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14306
        return BUFFER_E;
14307
#else
14308
    if (*outSz < (pubKeySz + msgSz + digestSz))
14309
        return BUFFER_E;
14310
#endif
14311
14312
#ifdef ECC_TIMING_RESISTANT
14313
    if (ctx->rng != NULL && privKey->rng == NULL)
14314
        privKey->rng = ctx->rng;
14315
#endif
14316
14317
#ifndef WOLFSSL_ECIES_OLD
14318
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14319
#ifdef ECC_TIMING_RESISTANT
14320
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14321
#else
14322
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14323
#endif
14324
        if (ret != 0)
14325
            return ret;
14326
    }
14327
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14328
    if (ret != 0)
14329
        return ret;
14330
    out += pubKeySz;
14331
#endif
14332
14333
#ifdef WOLFSSL_SMALL_STACK
14334
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14335
    if (sharedSecret == NULL)
14336
        return MEMORY_E;
14337
14338
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14339
    if (keys == NULL) {
14340
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14341
        return MEMORY_E;
14342
    }
14343
#endif
14344
14345
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14346
14347
#ifdef WOLFSSL_ECIES_ISO18033
14348
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14349
    sharedSz -= pubKeySz;
14350
#endif
14351
14352
    do {
14353
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14354
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14355
        if (ret != 0)
14356
            break;
14357
    #endif
14358
    #ifndef WOLFSSL_ECIES_ISO18033
14359
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14360
    #else
14361
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14362
                                                                     &sharedSz);
14363
    #endif
14364
    }
14365
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14366
14367
    if (ret == 0) {
14368
    #ifdef WOLFSSL_ECIES_ISO18033
14369
        /* KDF data is encoded public key and secret. */
14370
        sharedSz += pubKeySz;
14371
    #endif
14372
        switch (ctx->kdfAlgo) {
14373
            case ecHKDF_SHA256 :
14374
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14375
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14376
                           keys, (word32)keysLen);
14377
                break;
14378
            case ecHKDF_SHA1 :
14379
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14380
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14381
                           keys, (word32)keysLen);
14382
                break;
14383
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14384
            case ecKDF_X963_SHA1 :
14385
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14386
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14387
                break;
14388
            case ecKDF_X963_SHA256 :
14389
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14390
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14391
                break;
14392
            case ecKDF_SHA1 :
14393
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14394
                           NULL, 0, keys, (word32)keysLen);
14395
                break;
14396
            case ecKDF_SHA256 :
14397
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14398
                           NULL, 0, keys, (word32)keysLen);
14399
                break;
14400
#endif
14401
14402
14403
            default:
14404
                ret = BAD_FUNC_ARG;
14405
                break;
14406
        }
14407
    }
14408
14409
    if (ret == 0) {
14410
    #ifdef WOLFSSL_ECIES_OLD
14411
        encKey = keys + offset;
14412
        encIv  = encKey + encKeySz;
14413
        macKey = encKey + encKeySz + ivSz;
14414
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14415
        encKey = keys + offset;
14416
        encIv  = out;
14417
        out += ivSz;
14418
        macKey = encKey + encKeySz;
14419
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14420
    #else
14421
        XMEMSET(iv, 0, (size_t)ivSz);
14422
        encKey = keys + offset;
14423
        encIv  = iv;
14424
        macKey = encKey + encKeySz;
14425
    #endif
14426
    }
14427
14428
    if (ret == 0) {
14429
       switch (ctx->encAlgo) {
14430
            case ecAES_128_CBC:
14431
            case ecAES_256_CBC:
14432
            {
14433
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14434
            #ifdef WOLFSSL_SMALL_STACK
14435
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14436
                                          DYNAMIC_TYPE_AES);
14437
                if (aes == NULL) {
14438
                    ret = MEMORY_E;
14439
                    break;
14440
                }
14441
            #else
14442
                Aes aes[1];
14443
            #endif
14444
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14445
                if (ret == 0) {
14446
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14447
                                                                AES_ENCRYPTION);
14448
                    if (ret == 0) {
14449
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14450
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14451
                                                    defined(WC_ASYNC_ENABLE_AES)
14452
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14453
                                            WC_ASYNC_FLAG_NONE);
14454
                    #endif
14455
                    }
14456
                    wc_AesFree(aes);
14457
                }
14458
            #ifdef WOLFSSL_SMALL_STACK
14459
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
14460
            #endif
14461
        #else
14462
                ret = NOT_COMPILED_IN;
14463
        #endif
14464
                break;
14465
            }
14466
            case ecAES_128_CTR:
14467
            case ecAES_256_CTR:
14468
            {
14469
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14470
                byte ctr_iv[WC_AES_BLOCK_SIZE];
14471
            #ifndef WOLFSSL_SMALL_STACK
14472
                Aes aes[1];
14473
            #else
14474
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14475
                                            DYNAMIC_TYPE_AES);
14476
                if (aes == NULL) {
14477
                    ret = MEMORY_E;
14478
                    break;
14479
                }
14480
            #endif
14481
14482
                /* Include 4 byte counter starting at all zeros. */
14483
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14484
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14485
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14486
14487
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14488
                if (ret == 0) {
14489
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14490
                                                                AES_ENCRYPTION);
14491
                    if (ret == 0) {
14492
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
14493
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14494
                                                    defined(WC_ASYNC_ENABLE_AES)
14495
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14496
                                            WC_ASYNC_FLAG_NONE);
14497
                    #endif
14498
                    }
14499
                    wc_AesFree(aes);
14500
                }
14501
            #ifdef WOLFSSL_SMALL_STACK
14502
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
14503
            #endif
14504
        #else
14505
                ret = NOT_COMPILED_IN;
14506
        #endif
14507
                break;
14508
            }
14509
            default:
14510
                ret = BAD_FUNC_ARG;
14511
                break;
14512
        }
14513
    }
14514
14515
    if (ret == 0) {
14516
        switch (ctx->macAlgo) {
14517
            case ecHMAC_SHA256:
14518
            {
14519
            #ifdef WOLFSSL_SMALL_STACK
14520
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14521
                                             DYNAMIC_TYPE_HMAC);
14522
                if (hmac == NULL) {
14523
                    ret = MEMORY_E;
14524
                    break;
14525
                }
14526
            #else
14527
                Hmac hmac[1];
14528
            #endif
14529
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14530
                if (ret == 0) {
14531
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14532
                                                         WC_SHA256_DIGEST_SIZE);
14533
                    if (ret == 0) {
14534
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14535
                        ret = wc_HmacUpdate(hmac, out, msgSz);
14536
                    #else
14537
                        /* IV is before encrypted message. */
14538
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
14539
                    #endif
14540
                    }
14541
                    if (ret == 0)
14542
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14543
                    if (ret == 0)
14544
                        ret = wc_HmacFinal(hmac, out+msgSz);
14545
                    wc_HmacFree(hmac);
14546
                }
14547
            #ifdef WOLFSSL_SMALL_STACK
14548
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14549
            #endif
14550
                break;
14551
            }
14552
14553
            default:
14554
                ret = BAD_FUNC_ARG;
14555
                break;
14556
        }
14557
    }
14558
14559
    if (ret == 0) {
14560
#ifdef WOLFSSL_ECIES_OLD
14561
        *outSz = msgSz + digestSz;
14562
#elif defined(WOLFSSL_ECIES_GEN_IV)
14563
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
14564
#else
14565
        *outSz = pubKeySz + msgSz + digestSz;
14566
#endif
14567
    }
14568
14569
    RESTORE_VECTOR_REGISTERS();
14570
14571
#ifdef WOLFSSL_SMALL_STACK
14572
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14573
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14574
#endif
14575
14576
    return ret;
14577
}
14578
14579
/* ecc encrypt with shared secret run through kdf
14580
   ctx holds non default algos and inputs
14581
   msgSz should be the right size for encAlgo, i.e., already padded
14582
   return 0 on success */
14583
WOLFSSL_ABI
14584
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14585
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14586
{
14587
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14588
}
14589
14590
/* ecc decrypt with shared secret run through kdf
14591
   ctx holds non default algos and inputs
14592
   return 0 on success */
14593
WOLFSSL_ABI
14594
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14595
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14596
{
14597
    int          ret = 0;
14598
    word32       blockSz = 0;
14599
#ifndef WOLFSSL_ECIES_OLD
14600
#ifndef WOLFSSL_ECIES_GEN_IV
14601
    byte         iv[ECC_MAX_IV_SIZE];
14602
#endif
14603
    word32       pubKeySz = 0;
14604
#ifdef WOLFSSL_SMALL_STACK
14605
    ecc_key*     peerKey = NULL;
14606
#else
14607
    ecc_key      peerKey[1];
14608
#endif
14609
#endif
14610
    word32       digestSz = 0;
14611
    ecEncCtx     localCtx;
14612
#ifdef WOLFSSL_SMALL_STACK
14613
    byte*        sharedSecret;
14614
    byte*        keys;
14615
#else
14616
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14617
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14618
#else
14619
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14620
#endif
14621
    byte         keys[ECC_BUFSIZE];         /* max size */
14622
#endif
14623
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14624
    word32       sharedSz = ECC_MAXSIZE;
14625
#else
14626
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14627
#endif
14628
    int          keysLen = 0;
14629
    int          encKeySz = 0;
14630
    int          ivSz = 0;
14631
    int          offset = 0;       /* in case using msg exchange */
14632
    byte*        encKey = NULL;
14633
    const byte*  encIv = NULL;
14634
    byte*        macKey = NULL;
14635
14636
14637
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14638
        return BAD_FUNC_ARG;
14639
#ifdef WOLFSSL_ECIES_OLD
14640
    if (pubKey == NULL)
14641
        return BAD_FUNC_ARG;
14642
#endif
14643
14644
    if (ctx == NULL) {  /* use defaults */
14645
        ecc_ctx_init(&localCtx, 0, NULL);
14646
        ctx = &localCtx;
14647
    }
14648
14649
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14650
                            &blockSz);
14651
    if (ret != 0)
14652
        return ret;
14653
14654
#ifndef WOLFSSL_ECIES_OLD
14655
    ret = ecc_public_key_size(privKey, &pubKeySz);
14656
    if (ret != 0)
14657
        return ret;
14658
#ifdef HAVE_COMP_KEY
14659
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14660
        pubKeySz = (pubKeySz / 2) + 1;
14661
    }
14662
#endif /* HAVE_COMP_KEY */
14663
#endif /* WOLFSSL_ECIES_OLD */
14664
14665
    if (ctx->protocol == REQ_RESP_CLIENT) {
14666
        offset = keysLen;
14667
        keysLen *= 2;
14668
14669
        if (ctx->cliSt != ecCLI_SENT_REQ)
14670
            return BAD_STATE_E;
14671
14672
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14673
    }
14674
    else if (ctx->protocol == REQ_RESP_SERVER) {
14675
        if (ctx->srvSt != ecSRV_SALT_SET)
14676
            return BAD_STATE_E;
14677
14678
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
14679
    }
14680
14681
    if (keysLen > ECC_BUFSIZE) /* keys size */
14682
        return BUFFER_E;
14683
14684
#ifdef WOLFSSL_ECIES_OLD
14685
    if (((msgSz - digestSz) % blockSz) != 0)
14686
        return BAD_PADDING_E;
14687
14688
    if (*outSz < (msgSz - digestSz))
14689
        return BUFFER_E;
14690
#elif defined(WOLFSSL_ECIES_GEN_IV)
14691
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
14692
        return BAD_PADDING_E;
14693
14694
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
14695
        return BAD_FUNC_ARG;
14696
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
14697
        return BUFFER_E;
14698
#else
14699
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14700
        return BAD_PADDING_E;
14701
14702
    if (msgSz < pubKeySz + blockSz + digestSz)
14703
        return BAD_FUNC_ARG;
14704
    if (*outSz < (msgSz - digestSz - pubKeySz))
14705
        return BUFFER_E;
14706
#endif
14707
14708
#ifdef ECC_TIMING_RESISTANT
14709
    if (ctx->rng != NULL && privKey->rng == NULL)
14710
        privKey->rng = ctx->rng;
14711
#endif
14712
14713
#ifdef WOLFSSL_SMALL_STACK
14714
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14715
    if (sharedSecret == NULL) {
14716
    #ifndef WOLFSSL_ECIES_OLD
14717
        if (pubKey == peerKey)
14718
            wc_ecc_free(peerKey);
14719
    #endif
14720
        return MEMORY_E;
14721
    }
14722
14723
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14724
    if (keys == NULL) {
14725
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14726
    #ifndef WOLFSSL_ECIES_OLD
14727
        if (pubKey == peerKey)
14728
            wc_ecc_free(peerKey);
14729
    #endif
14730
        return MEMORY_E;
14731
    }
14732
#endif
14733
14734
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14735
14736
#ifndef WOLFSSL_ECIES_OLD
14737
    if (pubKey == NULL) {
14738
#ifdef WOLFSSL_SMALL_STACK
14739
        peerKey = (ecc_key*)XMALLOC(sizeof(*peerKey), ctx->heap,
14740
                                                       DYNAMIC_TYPE_ECC_BUFFER);
14741
        if (peerKey == NULL)
14742
            ret = MEMORY_E;
14743
#endif
14744
        pubKey = peerKey;
14745
    }
14746
    else {
14747
        /* if a public key was passed in we should free it here before init
14748
         * and import */
14749
        wc_ecc_free(pubKey);
14750
    }
14751
    if (ret == 0) {
14752
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14753
    }
14754
    if (ret == 0) {
14755
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14756
    }
14757
    if (ret == 0) {
14758
        /* Point is not MACed. */
14759
        msg += pubKeySz;
14760
        msgSz -= pubKeySz;
14761
    }
14762
#endif
14763
14764
    if (ret == 0) {
14765
    #ifdef WOLFSSL_ECIES_ISO18033
14766
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14767
        sharedSz -= pubKeySz;
14768
    #endif
14769
14770
        do {
14771
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14772
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
14773
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
14774
            if (ret != 0)
14775
                break;
14776
        #endif
14777
        #ifndef WOLFSSL_ECIES_ISO18033
14778
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14779
                                                                    &sharedSz);
14780
        #else
14781
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14782
                                                          pubKeySz, &sharedSz);
14783
        #endif
14784
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14785
    }
14786
    if (ret == 0) {
14787
    #ifdef WOLFSSL_ECIES_ISO18033
14788
        /* KDF data is encoded public key and secret. */
14789
        sharedSz += pubKeySz;
14790
    #endif
14791
        switch (ctx->kdfAlgo) {
14792
            case ecHKDF_SHA256 :
14793
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14794
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14795
                           keys, (word32)keysLen);
14796
                break;
14797
            case ecHKDF_SHA1 :
14798
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14799
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14800
                           keys, (word32)keysLen);
14801
                break;
14802
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14803
            case ecKDF_X963_SHA1 :
14804
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14805
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14806
                break;
14807
            case ecKDF_X963_SHA256 :
14808
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14809
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14810
                break;
14811
            case ecKDF_SHA1 :
14812
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14813
                           NULL, 0, keys, (word32)keysLen);
14814
                break;
14815
            case ecKDF_SHA256 :
14816
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14817
                           NULL, 0, keys, (word32)keysLen);
14818
                break;
14819
#endif
14820
14821
            default:
14822
                ret = BAD_FUNC_ARG;
14823
                break;
14824
         }
14825
    }
14826
14827
    if (ret == 0) {
14828
    #ifdef WOLFSSL_ECIES_OLD
14829
        encKey = keys + offset;
14830
        encIv  = encKey + encKeySz;
14831
        macKey = encKey + encKeySz + ivSz;
14832
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14833
        encKey = keys + offset;
14834
        encIv  = msg;
14835
        msg   += ivSz;
14836
        msgSz -= ivSz;
14837
        macKey = encKey + encKeySz;
14838
    #else
14839
        XMEMSET(iv, 0, (size_t)ivSz);
14840
        encKey = keys + offset;
14841
        encIv  = iv;
14842
        macKey = encKey + encKeySz;
14843
    #endif
14844
14845
        switch (ctx->macAlgo) {
14846
            case ecHMAC_SHA256:
14847
            {
14848
                byte verify[WC_SHA256_DIGEST_SIZE];
14849
            #ifdef WOLFSSL_SMALL_STACK
14850
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14851
                                             DYNAMIC_TYPE_HMAC);
14852
                if (hmac == NULL) {
14853
                    ret = MEMORY_E;
14854
                    break;
14855
                }
14856
            #else
14857
                Hmac hmac[1];
14858
            #endif
14859
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14860
                if (ret == 0) {
14861
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14862
                                                         WC_SHA256_DIGEST_SIZE);
14863
                    if (ret == 0)
14864
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14865
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
14866
                    #else
14867
                        /* IV is before encrypted message. */
14868
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
14869
                    #endif
14870
                    if (ret == 0)
14871
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14872
14873
                    if (ret == 0)
14874
                        ret = wc_HmacFinal(hmac, verify);
14875
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14876
                                                             digestSz) != 0)) {
14877
                        ret = HASH_TYPE_E;
14878
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14879
                    }
14880
14881
                    wc_HmacFree(hmac);
14882
                }
14883
            #ifdef WOLFSSL_SMALL_STACK
14884
                XFREE(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14885
            #endif
14886
                break;
14887
            }
14888
14889
            default:
14890
                ret = BAD_FUNC_ARG;
14891
                break;
14892
        }
14893
    }
14894
14895
    if (ret == 0) {
14896
        switch (ctx->encAlgo) {
14897
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14898
            case ecAES_128_CBC:
14899
            case ecAES_256_CBC:
14900
            {
14901
            #ifdef WOLFSSL_SMALL_STACK
14902
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14903
                                          DYNAMIC_TYPE_AES);
14904
                if (aes == NULL) {
14905
                    ret = MEMORY_E;
14906
                    break;
14907
                }
14908
            #else
14909
                Aes aes[1];
14910
            #endif
14911
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14912
                if (ret == 0) {
14913
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14914
                                                                AES_DECRYPTION);
14915
                    if (ret == 0) {
14916
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
14917
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14918
                                                    defined(WC_ASYNC_ENABLE_AES)
14919
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14920
                                                            WC_ASYNC_FLAG_NONE);
14921
                    #endif
14922
                    }
14923
                    wc_AesFree(aes);
14924
                }
14925
            #ifdef WOLFSSL_SMALL_STACK
14926
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
14927
            #endif
14928
                break;
14929
            }
14930
        #endif
14931
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14932
            case ecAES_128_CTR:
14933
            case ecAES_256_CTR:
14934
            {
14935
            #ifdef WOLFSSL_SMALL_STACK
14936
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14937
                                          DYNAMIC_TYPE_AES);
14938
                if (aes == NULL) {
14939
                    ret = MEMORY_E;
14940
                    break;
14941
                }
14942
             #else
14943
                Aes aes[1];
14944
             #endif
14945
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14946
                if (ret == 0) {
14947
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
14948
                    /* Make a 16 byte IV from the bytes passed in. */
14949
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14950
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14951
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14952
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14953
                                                                AES_ENCRYPTION);
14954
                    if (ret == 0) {
14955
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
14956
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14957
                                                    defined(WC_ASYNC_ENABLE_AES)
14958
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14959
                                                            WC_ASYNC_FLAG_NONE);
14960
                    #endif
14961
                    }
14962
                    wc_AesFree(aes);
14963
                }
14964
            #ifdef WOLFSSL_SMALL_STACK
14965
                XFREE(aes, ctx->heap, DYNAMIC_TYPE_AES);
14966
            #endif
14967
                break;
14968
            }
14969
        #endif
14970
            default:
14971
                ret = BAD_FUNC_ARG;
14972
                break;
14973
        }
14974
    }
14975
14976
    if (ret == 0)
14977
       *outSz = msgSz - digestSz;
14978
14979
    RESTORE_VECTOR_REGISTERS();
14980
14981
#ifndef WOLFSSL_ECIES_OLD
14982
    if (pubKey == peerKey)
14983
        wc_ecc_free(peerKey);
14984
#endif
14985
#ifdef WOLFSSL_SMALL_STACK
14986
#ifndef WOLFSSL_ECIES_OLD
14987
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14988
#endif
14989
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14990
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14991
#endif
14992
14993
    return ret;
14994
}
14995
14996
14997
#endif /* HAVE_ECC_ENCRYPT */
14998
14999
15000
#ifdef HAVE_COMP_KEY
15001
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
15002
    !defined(WOLFSSL_CRYPTOCELL)
15003
15004
#ifndef WOLFSSL_SP_MATH
15005
#if !defined(SQRTMOD_USE_MOD_EXP)
15006
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
15007
 */
15008
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
15009
{
15010
#ifdef WOLFSSL_SMALL_STACK
15011
    mp_int*  a1 = NULL;
15012
    mp_int*  n1 = NULL;
15013
#else
15014
    mp_int   a1[1], n1[1];
15015
#endif
15016
    int      res;
15017
    int      s = 1;
15018
    int      k;
15019
    mp_int*  t[2];
15020
    mp_int*  ts;
15021
    mp_digit residue;
15022
15023
    if (mp_isneg(a) == MP_YES) {
15024
        return MP_VAL;
15025
    }
15026
    if (mp_isneg(n) == MP_YES) {
15027
        return MP_VAL;
15028
    }
15029
    if (mp_iseven(n) == MP_YES) {
15030
        return MP_VAL;
15031
    }
15032
15033
#ifdef WOLFSSL_SMALL_STACK
15034
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
15035
    if (a1 == NULL) {
15036
        return MP_MEM;
15037
    }
15038
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
15039
    if (n1 == NULL) {
15040
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
15041
        return MP_MEM;
15042
    }
15043
#endif
15044
15045
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
15046
#ifdef WOLFSSL_SMALL_STACK
15047
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
15048
        XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
15049
#endif
15050
        return res;
15051
    }
15052
15053
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
15054
15055
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
15056
        goto done;
15057
    }
15058
15059
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
15060
        goto done;
15061
    }
15062
15063
    t[0] = a1;
15064
    t[1] = n1;
15065
15066
    /* Keep reducing until first number is 0. */
15067
    while (!mp_iszero(t[0])) {
15068
        /* Divide by 2 until odd. */
15069
        k = mp_cnt_lsb(t[0]);
15070
        if (k > 0) {
15071
            mp_rshb(t[0], k);
15072
15073
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
15074
             * Odd number of divides results in a negate.
15075
             */
15076
            residue = t[1]->dp[0] & 7;
15077
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
15078
                s = -s;
15079
            }
15080
        }
15081
15082
        /* Swap t[0] and t[1]. */
15083
        ts   = t[0];
15084
        t[0] = t[1];
15085
        t[1] = ts;
15086
15087
        /* Negate s if both numbers == 3 mod 4. */
15088
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
15089
             s = -s;
15090
        }
15091
15092
        /* Reduce first number modulo second. */
15093
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
15094
            res = mp_sub(t[0], t[1], t[0]);
15095
        }
15096
        else {
15097
            res = mp_mod(t[0], t[1], t[0]);
15098
        }
15099
        if (res != MP_OKAY) {
15100
            goto done;
15101
        }
15102
    }
15103
15104
    /* When the two numbers have divisors in common. */
15105
    if (!mp_isone(t[1])) {
15106
        s = 0;
15107
    }
15108
    *c = s;
15109
15110
done:
15111
15112
    RESTORE_VECTOR_REGISTERS();
15113
15114
    /* cleanup */
15115
    mp_clear(n1);
15116
    mp_clear(a1);
15117
15118
#ifdef WOLFSSL_SMALL_STACK
15119
    XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
15120
    XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
15121
#endif
15122
15123
  return res;
15124
}
15125
#endif /* !SQRTMOD_USE_MOD_EXP */
15126
15127
15128
/* Solves the modular equation x^2 = n (mod p)
15129
 * where prime number is greater than 2 (odd prime).
15130
 * The result is returned in the third argument x
15131
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
15132
 */
15133
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
15134
{
15135
#if defined(SQRTMOD_USE_MOD_EXP)
15136
  int res;
15137
  mp_digit i;
15138
  mp_int e;
15139
15140
  /* first handle the simple cases n = 0 or n = 1 */
15141
  if (mp_cmp_d(n, 0) == MP_EQ) {
15142
      mp_zero(ret);
15143
      return MP_OKAY;
15144
  }
15145
  if (mp_cmp_d(n, 1) == MP_EQ) {
15146
      return mp_set(ret, 1);
15147
  }
15148
15149
  if (mp_iseven(prime)) {
15150
      return MP_VAL;
15151
  }
15152
15153
  SAVE_VECTOR_REGISTERS(return _svr_ret;);
15154
15155
  res = mp_init(&e);
15156
  if (res == MP_OKAY)
15157
      res = mp_mod_d(prime, 8, &i);
15158
  if (res == MP_OKAY && i == 1) {
15159
      return MP_VAL;
15160
  }
15161
  /* prime mod 8 = 5 */
15162
  else if (res == MP_OKAY && i == 5) {
15163
      res = mp_sub_d(prime, 1, &e);
15164
      if (res == MP_OKAY)
15165
          res = mp_div_2d(&e, 2, &e, NULL);
15166
  }
15167
  /* prime mod 4 = 3 */
15168
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
15169
      res = mp_add_d(prime, 1, &e);
15170
      if (res == MP_OKAY)
15171
          res = mp_div_2d(&e, 2, &e, NULL);
15172
  }
15173
  if (res == MP_OKAY)
15174
      res = mp_exptmod(n, &e, prime, ret);
15175
15176
  mp_clear(&e);
15177
15178
  RESTORE_VECTOR_REGISTERS();
15179
15180
  return res;
15181
#else
15182
  int res, legendre, done = 0;
15183
  mp_digit i;
15184
#ifdef WOLFSSL_SMALL_STACK
15185
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15186
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15187
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15188
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15189
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15190
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15191
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15192
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15193
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15194
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15195
#else
15196
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
15197
#endif
15198
15199
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15200
15201
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15202
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15203
    res = MP_INIT_E;
15204
    goto out;
15205
  }
15206
15207
#ifdef WOLFSSL_SMALL_STACK
15208
  if ((t1 == NULL) ||
15209
      (C == NULL) ||
15210
      (Q == NULL) ||
15211
      (S == NULL) ||
15212
      (Z == NULL) ||
15213
      (M == NULL) ||
15214
      (T == NULL) ||
15215
      (R == NULL) ||
15216
      (N == NULL) ||
15217
      (two == NULL)) {
15218
    res = MP_MEM;
15219
    goto out;
15220
  }
15221
#endif
15222
15223
  /* first handle the simple cases n = 0 or n = 1 */
15224
  if (mp_cmp_d(n, 0) == MP_EQ) {
15225
    mp_zero(ret);
15226
    res = MP_OKAY;
15227
    goto out;
15228
  }
15229
  if (mp_cmp_d(n, 1) == MP_EQ) {
15230
    res = mp_set(ret, 1);
15231
    goto out;
15232
  }
15233
15234
  /* prime must be odd */
15235
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15236
    res = MP_VAL;
15237
    goto out;
15238
  }
15239
15240
  /* reduce n to less than prime */
15241
  res = mp_mod(n, prime, N);
15242
  if (res != MP_OKAY) {
15243
    goto out;
15244
  }
15245
  /* when N is zero, sqrt is zero */
15246
  if (mp_iszero(N)) {
15247
    mp_set(ret, 0);
15248
    goto out;
15249
  }
15250
15251
  /* is quadratic non-residue mod prime */
15252
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15253
    goto out;
15254
  }
15255
  if (legendre == -1) {
15256
    res = MP_VAL;
15257
    goto out;
15258
  }
15259
15260
  /* SPECIAL CASE: if prime mod 4 == 3
15261
   * compute directly: res = n^(prime+1)/4 mod prime
15262
   * Handbook of Applied Cryptography algorithm 3.36
15263
   */
15264
  res = mp_mod_d(prime, 4, &i);
15265
  if (res == MP_OKAY && i == 3) {
15266
    res = mp_add_d(prime, 1, t1);
15267
15268
    if (res == MP_OKAY)
15269
      res = mp_div_2(t1, t1);
15270
    if (res == MP_OKAY)
15271
      res = mp_div_2(t1, t1);
15272
    if (res == MP_OKAY)
15273
      res = mp_exptmod(N, t1, prime, ret);
15274
15275
    done = 1;
15276
  }
15277
15278
  /* NOW: TonelliShanks algorithm */
15279
  if (res == MP_OKAY && done == 0) {
15280
15281
    /* factor out powers of 2 from prime-1, defining Q and S
15282
    *                                      as: prime-1 = Q*2^S */
15283
    /* Q = prime - 1 */
15284
    res = mp_copy(prime, Q);
15285
    if (res == MP_OKAY)
15286
      res = mp_sub_d(Q, 1, Q);
15287
15288
    /* S = 0 */
15289
    if (res == MP_OKAY)
15290
      mp_zero(S);
15291
15292
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15293
      /* Q = Q / 2 */
15294
      res = mp_div_2(Q, Q);
15295
15296
      /* S = S + 1 */
15297
      if (res == MP_OKAY)
15298
        res = mp_add_d(S, 1, S);
15299
    }
15300
15301
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15302
    /* Z = 2 */
15303
    if (res == MP_OKAY)
15304
      res = mp_set_int(Z, 2);
15305
15306
    while (res == MP_OKAY) {
15307
      res = mp_jacobi(Z, prime, &legendre);
15308
      if (res == MP_OKAY && legendre == -1)
15309
        break;
15310
15311
#if defined(WOLFSSL_CUSTOM_CURVES)
15312
      /* P224R1 succeeds with a value of 11. */
15313
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15314
        /* This is to clamp the loop in case 'prime' is not really prime */
15315
        res = MP_VAL;
15316
        break;
15317
      }
15318
#endif
15319
15320
      /* Z = Z + 1 */
15321
      if (res == MP_OKAY)
15322
        res = mp_add_d(Z, 1, Z);
15323
15324
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
15325
        /* This is to clamp the loop in case 'prime' is not really prime */
15326
        res = MP_VAL;
15327
        break;
15328
      }
15329
    }
15330
15331
    /* C = Z ^ Q mod prime */
15332
    if (res == MP_OKAY)
15333
      res = mp_exptmod(Z, Q, prime, C);
15334
15335
    /* t1 = (Q + 1) / 2 */
15336
    if (res == MP_OKAY)
15337
      res = mp_add_d(Q, 1, t1);
15338
    if (res == MP_OKAY)
15339
      res = mp_div_2(t1, t1);
15340
15341
    /* R = n ^ ((Q + 1) / 2) mod prime */
15342
    if (res == MP_OKAY)
15343
      res = mp_exptmod(N, t1, prime, R);
15344
15345
    /* T = n ^ Q mod prime */
15346
    if (res == MP_OKAY)
15347
      res = mp_exptmod(N, Q, prime, T);
15348
15349
    /* M = S */
15350
    if (res == MP_OKAY)
15351
      res = mp_copy(S, M);
15352
15353
    if (res == MP_OKAY)
15354
      res = mp_set_int(two, 2);
15355
15356
    while (res == MP_OKAY && done == 0) {
15357
      res = mp_copy(T, t1);
15358
15359
      /* reduce to 1 and count */
15360
      i = 0;
15361
      while (res == MP_OKAY) {
15362
        if (mp_cmp_d(t1, 1) == MP_EQ)
15363
            break;
15364
        res = mp_exptmod(t1, two, prime, t1);
15365
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
15366
          /* This is to clamp the loop in case 'prime' is not really prime */
15367
          res = MP_VAL;
15368
          break;
15369
        }
15370
        if (res == MP_OKAY)
15371
          i++;
15372
      }
15373
      if (res == MP_OKAY && i == 0) {
15374
        res = mp_copy(R, ret);
15375
        done = 1;
15376
      }
15377
15378
      if (done == 0) {
15379
        /* t1 = 2 ^ (M - i - 1) */
15380
        if (res == MP_OKAY)
15381
          res = mp_sub_d(M, i, t1);
15382
        if (res == MP_OKAY)
15383
          res = mp_sub_d(t1, 1, t1);
15384
        if (res == MP_OKAY)
15385
          res = mp_exptmod(two, t1, prime, t1);
15386
15387
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15388
        if (res == MP_OKAY)
15389
          res = mp_exptmod(C, t1, prime, t1);
15390
15391
        /* C = (t1 * t1) mod prime */
15392
        if (res == MP_OKAY)
15393
          res = mp_sqrmod(t1, prime, C);
15394
15395
        /* R = (R * t1) mod prime */
15396
        if (res == MP_OKAY)
15397
          res = mp_mulmod(R, t1, prime, R);
15398
15399
        /* T = (T * C) mod prime */
15400
        if (res == MP_OKAY)
15401
          res = mp_mulmod(T, C, prime, T);
15402
15403
        /* M = i */
15404
        if (res == MP_OKAY)
15405
          res = mp_set(M, i);
15406
      }
15407
    }
15408
  }
15409
15410
  out:
15411
15412
  RESTORE_VECTOR_REGISTERS();
15413
15414
#ifdef WOLFSSL_SMALL_STACK
15415
  if (t1) {
15416
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15417
      mp_clear(t1);
15418
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15419
  }
15420
  if (C) {
15421
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15422
      mp_clear(C);
15423
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15424
  }
15425
  if (Q) {
15426
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15427
      mp_clear(Q);
15428
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15429
  }
15430
  if (S) {
15431
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15432
      mp_clear(S);
15433
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15434
  }
15435
  if (Z) {
15436
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15437
      mp_clear(Z);
15438
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15439
  }
15440
  if (M) {
15441
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15442
      mp_clear(M);
15443
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15444
  }
15445
  if (T) {
15446
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15447
      mp_clear(T);
15448
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15449
  }
15450
  if (R) {
15451
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15452
      mp_clear(R);
15453
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15454
  }
15455
  if (N) {
15456
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15457
      mp_clear(N);
15458
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15459
  }
15460
  if (two) {
15461
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15462
      mp_clear(two);
15463
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15464
  }
15465
#else
15466
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
15467
    mp_clear(t1);
15468
    mp_clear(C);
15469
    mp_clear(Q);
15470
    mp_clear(S);
15471
    mp_clear(Z);
15472
    mp_clear(M);
15473
    mp_clear(T);
15474
    mp_clear(R);
15475
    mp_clear(N);
15476
    mp_clear(two);
15477
  }
15478
#endif
15479
15480
  return res;
15481
#endif
15482
}
15483
#endif /* !WOLFSSL_SP_MATH */
15484
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
15485
15486
#ifdef HAVE_ECC_KEY_EXPORT
15487
/* export public ECC key in ANSI X9.63 format compressed */
15488
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
15489
{
15490
   word32 numlen;
15491
   int    ret = MP_OKAY;
15492
15493
   if (key == NULL || outLen == NULL)
15494
       return BAD_FUNC_ARG;
15495
15496
   if (key->type == ECC_PRIVATEKEY_ONLY)
15497
       return ECC_PRIVATEONLY_E;
15498
15499
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15500
       return ECC_BAD_ARG_E;
15501
   }
15502
15503
   numlen = (word32)key->dp->size;
15504
15505
   if (*outLen < (1 + numlen)) {
15506
      *outLen = 1 + numlen;
15507
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15508
   }
15509
15510
   if (out == NULL)
15511
       return BAD_FUNC_ARG;
15512
15513
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15514
       return ECC_BAD_ARG_E;
15515
15516
   /* store first byte */
15517
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15518
15519
   /* pad and store x */
15520
   XMEMSET(out+1, 0, numlen);
15521
   ret = mp_to_unsigned_bin(
15522
       key->pubkey.x,
15523
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15524
   *outLen = 1 + numlen;
15525
15526
   return ret;
15527
}
15528
#endif /* HAVE_ECC_KEY_EXPORT */
15529
#endif /* HAVE_COMP_KEY */
15530
15531
#ifdef HAVE_OID_ENCODING
15532
int wc_ecc_oid_cache_init(void)
15533
{
15534
    int ret = 0;
15535
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15536
    ret = wc_InitMutex(&ecc_oid_cache_lock);
15537
#endif
15538
    return ret;
15539
}
15540
15541
void wc_ecc_oid_cache_free(void)
15542
{
15543
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15544
    wc_FreeMutex(&ecc_oid_cache_lock);
15545
#endif
15546
}
15547
#endif /* HAVE_OID_ENCODING */
15548
15549
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
15550
0
{
15551
0
    int x;
15552
0
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
15553
#ifdef HAVE_OID_ENCODING
15554
    oid_cache_t* o = NULL;
15555
#endif
15556
15557
0
    if (oidSum == 0) {
15558
0
        return BAD_FUNC_ARG;
15559
0
    }
15560
15561
#ifdef HAVE_OID_ENCODING
15562
    #ifndef WOLFSSL_MUTEX_INITIALIZER
15563
        /* extra sanity check if wolfCrypt_Init not called */
15564
        if (eccOidLockInit == 0) {
15565
            wc_InitMutex(&ecc_oid_cache_lock);
15566
            eccOidLockInit = 1;
15567
        }
15568
    #endif
15569
15570
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
15571
        return BAD_MUTEX_E;
15572
    }
15573
#endif
15574
15575
    /* find matching OID sum (based on encoded value) */
15576
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
15577
0
        if (ecc_sets[x].oidSum == oidSum) {
15578
        #ifdef HAVE_OID_ENCODING
15579
            /* check cache */
15580
            ret = 0;
15581
            o = &ecc_oid_cache[x];
15582
            if (o->oidSz == 0) {
15583
                o->oidSz = sizeof(o->oid);
15584
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
15585
                                                            o->oid, &o->oidSz);
15586
            }
15587
            if (oidSz) {
15588
                *oidSz = o->oidSz;
15589
            }
15590
            if (oid) {
15591
                *oid = o->oid;
15592
            }
15593
15594
            /* on success return curve id */
15595
            if (ret == 0) {
15596
                ret = ecc_sets[x].id;
15597
            }
15598
            break;
15599
        #else
15600
0
            if (oidSz) {
15601
0
                *oidSz = ecc_sets[x].oidSz;
15602
0
            }
15603
0
            if (oid) {
15604
0
                *oid = ecc_sets[x].oid;
15605
0
            }
15606
0
            ret = ecc_sets[x].id;
15607
0
            break;
15608
0
        #endif
15609
0
        }
15610
0
    }
15611
15612
#ifdef HAVE_OID_ENCODING
15613
    wc_UnLockMutex(&ecc_oid_cache_lock);
15614
#endif
15615
15616
0
    return ret;
15617
0
}
15618
15619
#ifdef WOLFSSL_CUSTOM_CURVES
15620
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15621
{
15622
    if (key == NULL || dp == NULL) {
15623
        return BAD_FUNC_ARG;
15624
    }
15625
15626
    key->idx = ECC_CUSTOM_IDX;
15627
    key->dp = dp;
15628
15629
    return 0;
15630
}
15631
#endif /* WOLFSSL_CUSTOM_CURVES */
15632
15633
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15634
15635
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
15636
{
15637
    int i;
15638
15639
    /* in network byte order so start at end and work back */
15640
    for (i = 3; i >= 0; i--) {
15641
        if (++inOutCtr[i])  /* we're done unless we overflow */
15642
            return;
15643
    }
15644
}
15645
15646
/* ASN X9.63 Key Derivation Function (SEC1) */
15647
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
15648
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
15649
{
15650
    int ret;
15651
    word32 digestSz, copySz, remaining = outSz;
15652
    byte* outIdx;
15653
    byte  counter[4];
15654
    byte  tmp[WC_MAX_DIGEST_SIZE];
15655
15656
#ifdef WOLFSSL_SMALL_STACK
15657
    wc_HashAlg* hash;
15658
#else
15659
    wc_HashAlg hash[1];
15660
#endif
15661
15662
    if (secret == NULL || secretSz == 0 || out == NULL)
15663
        return BAD_FUNC_ARG;
15664
15665
    /* X9.63 allowed algos only */
15666
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
15667
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
15668
        type != WC_HASH_TYPE_SHA512)
15669
        return BAD_FUNC_ARG;
15670
15671
    ret = wc_HashGetDigestSize(type);
15672
    if (ret < 0)
15673
        return ret;
15674
    digestSz = (word32)ret;
15675
15676
#ifdef WOLFSSL_SMALL_STACK
15677
    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
15678
                                DYNAMIC_TYPE_HASHES);
15679
    if (hash == NULL)
15680
        return MEMORY_E;
15681
#endif
15682
15683
    ret = wc_HashInit(hash, type);
15684
    if (ret != 0) {
15685
#ifdef WOLFSSL_SMALL_STACK
15686
        XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
15687
#endif
15688
        return ret;
15689
    }
15690
15691
    outIdx = out;
15692
    XMEMSET(counter, 0, sizeof(counter));
15693
15694
    while (remaining > 0) {
15695
15696
        IncrementX963KdfCounter(counter);
15697
15698
        ret = wc_HashUpdate(hash, type, secret, secretSz);
15699
        if (ret != 0) {
15700
            break;
15701
        }
15702
15703
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
15704
        if (ret != 0) {
15705
            break;
15706
        }
15707
15708
        if (sinfo) {
15709
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
15710
            if (ret != 0) {
15711
                break;
15712
            }
15713
        }
15714
15715
        ret = wc_HashFinal(hash, type, tmp);
15716
        if (ret != 0) {
15717
            break;
15718
        }
15719
15720
        copySz = min(remaining, digestSz);
15721
        XMEMCPY(outIdx, tmp, copySz);
15722
15723
        remaining -= copySz;
15724
        outIdx += copySz;
15725
    }
15726
15727
    wc_HashFree(hash, type);
15728
15729
#ifdef WOLFSSL_SMALL_STACK
15730
     XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
15731
#endif
15732
15733
    return ret;
15734
}
15735
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
15736
15737
#ifdef WOLFSSL_SE050
15738
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
15739
 * keyId is a word32, can be used for key IDs larger than an int.
15740
 *
15741
 * key    initialized ecc_key struct
15742
 * keyId  hardware key ID which stores ECC key
15743
 * flags  optional flags, currently unused
15744
 *
15745
 * Return 0 on success, negative on error */
15746
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
15747
{
15748
    (void)flags;
15749
15750
    if (key == NULL) {
15751
        return BAD_FUNC_ARG;
15752
    }
15753
15754
    return se050_ecc_use_key_id(key, keyId);
15755
}
15756
15757
/* Get hardware key ID associated with this ecc_key structure.
15758
 *
15759
 * key    initialized ecc_key struct
15760
 * keyId  [OUT] output for key ID associated with this structure
15761
 *
15762
 * Returns 0 on success, negative on error.
15763
 */
15764
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
15765
{
15766
    if (key == NULL || keyId == NULL) {
15767
        return BAD_FUNC_ARG;
15768
    }
15769
15770
    return se050_ecc_get_key_id(key, keyId);
15771
}
15772
#endif /* WOLFSSL_SE050 */
15773
15774
15775
#ifdef WC_ECC_NONBLOCK
15776
/* Enable ECC support for non-blocking operations */
15777
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
15778
{
15779
    if (key) {
15780
        if (ctx) {
15781
            XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
15782
        }
15783
        key->nb_ctx = ctx;
15784
    }
15785
    return 0;
15786
}
15787
#endif /* WC_ECC_NONBLOCK */
15788
15789
#endif /* HAVE_ECC */