Coverage Report

Created: 2025-11-16 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/wolfcrypt/src/ecc.c
Line
Count
Source
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
25
#undef WOLFSSL_SMALL_STACK
26
#undef WOLFSSL_SMALL_STACK_CACHE
27
#endif
28
29
/*
30
Possible ECC enable options:
31
 * HAVE_ECC:            Overall control of ECC                  default: on
32
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
33
 * HAVE_ECC_SIGN:       ECC sign                                default: on
34
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
35
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
36
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
37
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
38
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
39
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
40
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
41
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
42
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
43
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
44
 *                        Includes the curve "a" variable in calculation
45
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
46
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
47
 *                                                              default: off
48
 * FP_ECC:              ECC Fixed Point Cache                   default: off
49
 *                      FP cache is not supported for SECP160R1, SECP160R2,
50
 *                      SECP160K1 and SECP224K1. These do not work with scalars
51
 *                      that are the length of the order when the order is
52
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
53
 * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off
54
 *                      (on for HAVE_COMP_KEY)
55
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
56
 *                      For the ECC curve parameters `ecc_set_type` use fixed
57
 *                      array for hex string
58
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
59
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
60
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
61
 *                      normal blocking API's
62
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
63
 *                      signing. If the value is invalid, a new random 'k' is
64
 *                      generated in the loop. (For testing)
65
 *                                                              default: off
66
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
67
 *                      Enables the setting of the 'k' value to use during ECDSA
68
 *                      signing. If the value is invalid then an error is
69
 *                      returned rather than generating a new 'k'. (For testing)
70
 *                                                              default: off
71
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
72
 *                      deterministic ECC signatures. The following function
73
 *                      can be used to set the deterministic signing flag in the
74
 *                      ecc key structure.
75
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
76
 *                                                              default: off
77
 *
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
79
 *                      hash directly instead of doing bits2octets(H(m)), when
80
 *                      the variant macro is used the bits2octets operation on
81
 *                      the hash is removed.
82
 *                                                              default: off
83
 *
84
 * WC_PROTECT_ENCRYPTED_MEM:
85
 *                      Enables implementations that protect data that is in
86
 *                      encrypted memory.
87
 *                                                              default: off
88
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
89
 *                      Enables generation of scalar (private key and ECDSA
90
 *                      nonce) to be performed using reject sampling algorithm.
91
 *                      Use this when CPU state can be closely observed by
92
 *                      attacker.
93
 *                                                              default: off
94
 * WOLFSSL_ECC_BLIND_K
95
 *                      Blind the private key k by using a random mask.
96
 *                      The private key is never stored unprotected but an
97
 *                      unmasked copy is computed and stored each time it is
98
 *                      needed.
99
 *                                                              default: off
100
 * WOLFSSL_CHECK_VER_FAULTS
101
 *                      Sanity check on verification steps in case of faults.
102
 *                                                              default: off
103
 */
104
105
/*
106
ECC Curve Types:
107
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
108
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
109
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
110
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
111
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
112
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
113
 */
114
115
/*
116
ECC Curve Sizes:
117
 * ECC_USER_CURVES: Allows custom combination of key sizes below
118
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
119
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
120
 * HAVE_ECC112: 112 bit key
121
 * HAVE_ECC128: 128 bit key
122
 * HAVE_ECC160: 160 bit key
123
 * HAVE_ECC192: 192 bit key
124
 * HAVE_ECC224: 224 bit key
125
 * HAVE_ECC239: 239 bit key
126
 * NO_ECC256: Disables 256 bit key (on by default)
127
 * HAVE_ECC320: 320 bit key
128
 * HAVE_ECC384: 384 bit key
129
 * HAVE_ECC512: 512 bit key
130
 * HAVE_ECC521: 521 bit key
131
 */
132
133
134
#ifdef HAVE_ECC
135
136
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
137
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
138
    !defined(WOLFSSL_CUSTOM_CURVES)
139
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
140
#endif
141
142
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
143
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
144
    #define FIPS_NO_WRAPPERS
145
146
    #ifdef USE_WINDOWS_API
147
        #pragma code_seg(".fipsA$f")
148
        #pragma const_seg(".fipsB$f")
149
    #endif
150
#endif
151
152
/* public ASN interface */
153
#include <wolfssl/wolfcrypt/asn_public.h>
154
155
#include <wolfssl/wolfcrypt/ecc.h>
156
#include <wolfssl/wolfcrypt/asn.h>
157
158
#ifdef WOLFSSL_HAVE_SP_ECC
159
#include <wolfssl/wolfcrypt/sp.h>
160
#endif
161
162
#ifdef HAVE_ECC_ENCRYPT
163
    #include <wolfssl/wolfcrypt/kdf.h>
164
    #include <wolfssl/wolfcrypt/aes.h>
165
#endif
166
167
#ifdef HAVE_X963_KDF
168
    #include <wolfssl/wolfcrypt/hash.h>
169
#endif
170
171
#ifdef WOLF_CRYPTO_CB
172
    #include <wolfssl/wolfcrypt/cryptocb.h>
173
#endif
174
175
#ifdef NO_INLINE
176
    #include <wolfssl/wolfcrypt/misc.h>
177
#else
178
    #define WOLFSSL_MISC_INCLUDED
179
    #include <wolfcrypt/src/misc.c>
180
#endif
181
182
#if FIPS_VERSION3_GE(6,0,0)
183
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
184
                                                     { 0x1a2b3c4d, 0x00000005 };
185
    int wolfCrypt_FIPS_ECC_sanity(void)
186
    {
187
        return 0;
188
    }
189
#endif
190
191
#if defined(FREESCALE_LTC_ECC)
192
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
193
#endif
194
195
#if defined(WOLFSSL_STM32_PKA)
196
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
197
#endif
198
199
#if defined(WOLFSSL_PSOC6_CRYPTO)
200
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
201
#endif
202
203
#if defined(WOLFSSL_CAAM)
204
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
205
#endif
206
207
#if defined(WOLFSSL_KCAPI_ECC)
208
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
209
#endif
210
211
#ifdef WOLFSSL_SE050
212
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
213
#endif
214
215
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
216
    #include <xsecure_ellipticclient.h>
217
#endif
218
219
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
220
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
221
    #include <wolfssl/wolfcrypt/hmac.h>
222
#endif
223
224
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WOLFSSL_SP_ASM)
225
    /* force off unneeded vector register save/restore. */
226
    #undef SAVE_VECTOR_REGISTERS
227
    #define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
228
    #undef RESTORE_VECTOR_REGISTERS
229
    #define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
230
#endif
231
232
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
233
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
234
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
235
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) && \
236
    !defined(WOLFSSL_PSOC6_CRYPTO)
237
    #undef  HAVE_ECC_VERIFY_HELPER
238
    #define HAVE_ECC_VERIFY_HELPER
239
#endif
240
241
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
242
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
243
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
244
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
245
    #undef  HAVE_ECC_MAKE_PUB
246
    #define HAVE_ECC_MAKE_PUB
247
#endif
248
249
250
/* macro guard for ecc_check_pubkey_order functionality */
251
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
252
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
253
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
254
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
255
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
256
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
257
258
    /* CAAM builds use public key validation as a means to check if an
259
     * imported private key is an encrypted black key or not */
260
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
261
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
262
#endif
263
264
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
265
#define MAX_ECC_BITS_USE    SP_INT_BITS
266
#else
267
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
268
#endif
269
270
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
271
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
272
273
#define ECC_KEY_MAX_BITS(key)                                       \
274
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
275
        ((unsigned)((key)->dp->size * 8)))
276
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
277
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
278
        ((unsigned)((key)->dp->size * 8)))
279
280
#else
281
282
/* Add one bit for cases when order is a bit greater than prime. */
283
#define ECC_KEY_MAX_BITS(key)                                       \
284
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
285
        ((unsigned)((key)->dp->size * 8 + 1)))
286
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
287
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
288
        ((unsigned)((key)->dp->size * 8 + 1)))
289
290
#endif
291
292
#ifdef WOLFSSL_ECC_BLIND_K
293
mp_int* ecc_get_k(ecc_key* key)
294
{
295
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
296
    return key->ku;
297
}
298
void ecc_blind_k(ecc_key* key, mp_int* b)
299
{
300
    mp_xor_ct(key->k, b, key->dp->size, key->k);
301
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
302
}
303
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
304
{
305
    int ret = 0;
306
    WC_RNG local_rng;
307
308
#ifdef ECC_TIMING_RESISTANT
309
    if (rng == NULL) {
310
        rng = key->rng;
311
    }
312
#endif
313
    if (rng == NULL) {
314
        ret = wc_InitRng(&local_rng);
315
        if (ret == 0) {
316
            rng = &local_rng;
317
        }
318
    }
319
    if (ret == 0) {
320
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
321
            sizeof(mp_digit), rng);
322
        if (ret == 0) {
323
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
324
        }
325
    }
326
327
    if (rng == &local_rng) {
328
        wc_FreeRng(&local_rng);
329
    }
330
    return ret;
331
}
332
333
mp_int* wc_ecc_key_get_priv(ecc_key* key)
334
{
335
    return ecc_get_k(key);
336
}
337
#endif
338
339
/* forward declarations */
340
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
341
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
342
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
343
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
344
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
345
#endif
346
347
/* internal ECC states */
348
enum {
349
    ECC_STATE_NONE = 0,
350
351
    ECC_STATE_SHARED_SEC_GEN,
352
    ECC_STATE_SHARED_SEC_RES,
353
354
    ECC_STATE_SIGN_DO,
355
    ECC_STATE_SIGN_ENCODE,
356
357
    ECC_STATE_VERIFY_DECODE,
358
    ECC_STATE_VERIFY_DO,
359
    ECC_STATE_VERIFY_RES
360
};
361
362
363
/* map
364
   ptmul -> mulmod
365
*/
366
367
/* 256-bit curve on by default whether user curves or not */
368
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
369
    #define ECC112
370
#endif
371
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
372
    #define ECC128
373
#endif
374
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
375
    #define ECC160
376
#endif
377
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
378
    #define ECC192
379
#endif
380
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
381
    #define ECC224
382
#endif
383
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
384
    #define ECC239
385
#endif
386
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
387
    #define ECC256
388
#endif
389
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
390
    #define ECC320
391
#endif
392
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
393
    #define ECC384
394
#endif
395
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
396
    #define ECC512
397
#endif
398
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
399
    #define ECC521
400
#endif
401
402
/* The encoded OID's for ECC curves */
403
#ifdef ECC112
404
    #ifndef NO_ECC_SECP
405
        #ifdef HAVE_OID_ENCODING
406
            #define CODED_SECP112R1    {1,3,132,0,6}
407
            #define CODED_SECP112R1_SZ 5
408
        #else
409
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
410
            #define CODED_SECP112R1_SZ 5
411
        #endif
412
        #ifndef WOLFSSL_ECC_CURVE_STATIC
413
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
414
        #else
415
            #define ecc_oid_secp112r1 CODED_SECP112R1
416
        #endif
417
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
418
    #endif /* !NO_ECC_SECP */
419
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
420
        #ifdef HAVE_OID_ENCODING
421
            #define CODED_SECP112R2    {1,3,132,0,7}
422
            #define CODED_SECP112R2_SZ 5
423
        #else
424
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
425
            #define CODED_SECP112R2_SZ 5
426
        #endif
427
        #ifndef WOLFSSL_ECC_CURVE_STATIC
428
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
429
        #else
430
            #define ecc_oid_secp112r2 CODED_SECP112R2
431
        #endif
432
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
433
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
434
#endif /* ECC112 */
435
#ifdef ECC128
436
    #ifndef NO_ECC_SECP
437
        #ifdef HAVE_OID_ENCODING
438
            #define CODED_SECP128R1    {1,3,132,0,28}
439
            #define CODED_SECP128R1_SZ 5
440
        #else
441
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
442
            #define CODED_SECP128R1_SZ 5
443
        #endif
444
        #ifndef WOLFSSL_ECC_CURVE_STATIC
445
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
446
        #else
447
            #define ecc_oid_secp128r1 CODED_SECP128R1
448
        #endif
449
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
450
    #endif /* !NO_ECC_SECP */
451
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
452
        #ifdef HAVE_OID_ENCODING
453
            #define CODED_SECP128R2    {1,3,132,0,29}
454
            #define CODED_SECP128R2_SZ 5
455
        #else
456
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
457
            #define CODED_SECP128R2_SZ 5
458
        #endif
459
        #ifndef WOLFSSL_ECC_CURVE_STATIC
460
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
461
        #else
462
            #define ecc_oid_secp128r2 CODED_SECP128R2
463
        #endif
464
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
465
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
466
#endif /* ECC128 */
467
#ifdef ECC160
468
#ifndef FP_ECC
469
    #ifndef NO_ECC_SECP
470
        #ifdef HAVE_OID_ENCODING
471
            #define CODED_SECP160R1    {1,3,132,0,8}
472
            #define CODED_SECP160R1_SZ 5
473
        #else
474
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
475
            #define CODED_SECP160R1_SZ 5
476
        #endif
477
        #ifndef WOLFSSL_ECC_CURVE_STATIC
478
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
479
        #else
480
            #define ecc_oid_secp160r1 CODED_SECP160R1
481
        #endif
482
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
483
    #endif /* !NO_ECC_SECP */
484
    #ifdef HAVE_ECC_SECPR2
485
        #ifdef HAVE_OID_ENCODING
486
            #define CODED_SECP160R2    {1,3,132,0,30}
487
            #define CODED_SECP160R2_SZ 5
488
        #else
489
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
490
            #define CODED_SECP160R2_SZ 5
491
        #endif
492
        #ifndef WOLFSSL_ECC_CURVE_STATIC
493
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
494
        #else
495
            #define ecc_oid_secp160r2 CODED_SECP160R2
496
        #endif
497
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
498
    #endif /* HAVE_ECC_SECPR2 */
499
    #ifdef HAVE_ECC_KOBLITZ
500
        #ifdef HAVE_OID_ENCODING
501
            #define CODED_SECP160K1    {1,3,132,0,9}
502
            #define CODED_SECP160K1_SZ 5
503
        #else
504
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
505
            #define CODED_SECP160K1_SZ 5
506
        #endif
507
        #ifndef WOLFSSL_ECC_CURVE_STATIC
508
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
509
        #else
510
            #define ecc_oid_secp160k1 CODED_SECP160K1
511
        #endif
512
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
513
    #endif /* HAVE_ECC_KOBLITZ */
514
#endif /* !FP_ECC */
515
    #ifdef HAVE_ECC_BRAINPOOL
516
        #ifdef HAVE_OID_ENCODING
517
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
518
            #define CODED_BRAINPOOLP160R1_SZ 10
519
        #else
520
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
521
            #define CODED_BRAINPOOLP160R1_SZ 9
522
        #endif
523
        #ifndef WOLFSSL_ECC_CURVE_STATIC
524
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
525
        #else
526
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
527
        #endif
528
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
529
    #endif /* HAVE_ECC_BRAINPOOL */
530
#endif /* ECC160 */
531
#ifdef ECC192
532
    #ifndef NO_ECC_SECP
533
        #ifdef HAVE_OID_ENCODING
534
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
535
            #define CODED_SECP192R1_SZ 7
536
        #else
537
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
538
            #define CODED_SECP192R1_SZ 8
539
        #endif
540
        #ifndef WOLFSSL_ECC_CURVE_STATIC
541
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
542
        #else
543
            #define ecc_oid_secp192r1 CODED_SECP192R1
544
        #endif
545
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
546
    #endif /* !NO_ECC_SECP */
547
    #ifdef HAVE_ECC_SECPR2
548
        #ifdef HAVE_OID_ENCODING
549
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
550
            #define CODED_PRIME192V2_SZ 7
551
        #else
552
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
553
            #define CODED_PRIME192V2_SZ 8
554
        #endif
555
        #ifndef WOLFSSL_ECC_CURVE_STATIC
556
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
557
        #else
558
            #define ecc_oid_prime192v2 CODED_PRIME192V2
559
        #endif
560
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
561
    #endif /* HAVE_ECC_SECPR2 */
562
    #ifdef HAVE_ECC_SECPR3
563
        #ifdef HAVE_OID_ENCODING
564
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
565
            #define CODED_PRIME192V3_SZ 7
566
        #else
567
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
568
            #define CODED_PRIME192V3_SZ 8
569
        #endif
570
        #ifndef WOLFSSL_ECC_CURVE_STATIC
571
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
572
        #else
573
            #define ecc_oid_prime192v3 CODED_PRIME192V3
574
        #endif
575
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
576
    #endif /* HAVE_ECC_SECPR3 */
577
    #ifdef HAVE_ECC_KOBLITZ
578
        #ifdef HAVE_OID_ENCODING
579
            #define CODED_SECP192K1    {1,3,132,0,31}
580
            #define CODED_SECP192K1_SZ 5
581
        #else
582
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
583
            #define CODED_SECP192K1_SZ 5
584
        #endif
585
        #ifndef WOLFSSL_ECC_CURVE_STATIC
586
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
587
        #else
588
            #define ecc_oid_secp192k1 CODED_SECP192K1
589
        #endif
590
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
591
    #endif /* HAVE_ECC_KOBLITZ */
592
    #ifdef HAVE_ECC_BRAINPOOL
593
        #ifdef HAVE_OID_ENCODING
594
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
595
            #define CODED_BRAINPOOLP192R1_SZ 10
596
        #else
597
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
598
            #define CODED_BRAINPOOLP192R1_SZ 9
599
        #endif
600
        #ifndef WOLFSSL_ECC_CURVE_STATIC
601
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
602
        #else
603
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
604
        #endif
605
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
606
    #endif /* HAVE_ECC_BRAINPOOL */
607
#endif /* ECC192 */
608
#ifdef ECC224
609
    #ifndef NO_ECC_SECP
610
        #ifdef HAVE_OID_ENCODING
611
            #define CODED_SECP224R1    {1,3,132,0,33}
612
            #define CODED_SECP224R1_SZ 5
613
        #else
614
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
615
            #define CODED_SECP224R1_SZ 5
616
        #endif
617
        #ifndef WOLFSSL_ECC_CURVE_STATIC
618
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
619
        #else
620
            #define ecc_oid_secp224r1 CODED_SECP224R1
621
        #endif
622
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
623
    #endif /* !NO_ECC_SECP */
624
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
625
        #ifdef HAVE_OID_ENCODING
626
            #define CODED_SECP224K1    {1,3,132,0,32}
627
            #define CODED_SECP224K1_SZ 5
628
        #else
629
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
630
            #define CODED_SECP224K1_SZ 5
631
        #endif
632
        #ifndef WOLFSSL_ECC_CURVE_STATIC
633
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
634
        #else
635
            #define ecc_oid_secp224k1 CODED_SECP224K1
636
        #endif
637
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
638
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
639
    #ifdef HAVE_ECC_BRAINPOOL
640
        #ifdef HAVE_OID_ENCODING
641
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
642
            #define CODED_BRAINPOOLP224R1_SZ 10
643
        #else
644
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
645
            #define CODED_BRAINPOOLP224R1_SZ 9
646
        #endif
647
        #ifndef WOLFSSL_ECC_CURVE_STATIC
648
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
649
        #else
650
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
651
        #endif
652
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
653
    #endif /* HAVE_ECC_BRAINPOOL */
654
#endif /* ECC224 */
655
#ifdef ECC239
656
    #ifndef NO_ECC_SECP
657
        #ifdef HAVE_OID_ENCODING
658
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
659
            #define CODED_PRIME239V1_SZ 7
660
        #else
661
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
662
            #define CODED_PRIME239V1_SZ 8
663
        #endif
664
        #ifndef WOLFSSL_ECC_CURVE_STATIC
665
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
666
        #else
667
            #define ecc_oid_prime239v1 CODED_PRIME239V1
668
        #endif
669
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
670
    #endif /* !NO_ECC_SECP */
671
    #ifdef HAVE_ECC_SECPR2
672
        #ifdef HAVE_OID_ENCODING
673
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
674
            #define CODED_PRIME239V2_SZ 7
675
        #else
676
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
677
            #define CODED_PRIME239V2_SZ 8
678
        #endif
679
        #ifndef WOLFSSL_ECC_CURVE_STATIC
680
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
681
        #else
682
            #define ecc_oid_prime239v2 CODED_PRIME239V2
683
        #endif
684
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
685
    #endif /* HAVE_ECC_SECPR2 */
686
    #ifdef HAVE_ECC_SECPR3
687
        #ifdef HAVE_OID_ENCODING
688
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
689
            #define CODED_PRIME239V3_SZ 7
690
        #else
691
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
692
            #define CODED_PRIME239V3_SZ 8
693
        #endif
694
        #ifndef WOLFSSL_ECC_CURVE_STATIC
695
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
696
        #else
697
            #define ecc_oid_prime239v3 CODED_PRIME239V3
698
        #endif
699
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
700
    #endif /* HAVE_ECC_SECPR3 */
701
#endif /* ECC239 */
702
#ifdef ECC256
703
    #ifndef NO_ECC_SECP
704
        #ifdef HAVE_OID_ENCODING
705
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
706
            #define CODED_SECP256R1_SZ 7
707
        #else
708
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
709
            #define CODED_SECP256R1_SZ 8
710
        #endif
711
        #ifndef WOLFSSL_ECC_CURVE_STATIC
712
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
713
        #else
714
            #define ecc_oid_secp256r1 CODED_SECP256R1
715
        #endif
716
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
717
    #endif /* !NO_ECC_SECP */
718
    #ifdef HAVE_ECC_KOBLITZ
719
        #ifdef HAVE_OID_ENCODING
720
            #define CODED_SECP256K1    {1,3,132,0,10}
721
            #define CODED_SECP256K1_SZ 5
722
        #else
723
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
724
            #define CODED_SECP256K1_SZ 5
725
        #endif
726
        #ifndef WOLFSSL_ECC_CURVE_STATIC
727
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
728
        #else
729
            #define ecc_oid_secp256k1 CODED_SECP256K1
730
        #endif
731
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
732
    #endif /* HAVE_ECC_KOBLITZ */
733
    #ifdef HAVE_ECC_BRAINPOOL
734
        #ifdef HAVE_OID_ENCODING
735
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
736
            #define CODED_BRAINPOOLP256R1_SZ 10
737
        #else
738
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
739
            #define CODED_BRAINPOOLP256R1_SZ 9
740
        #endif
741
        #ifndef WOLFSSL_ECC_CURVE_STATIC
742
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
743
        #else
744
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
745
        #endif
746
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
747
    #endif /* HAVE_ECC_BRAINPOOL */
748
#endif /* ECC256 */
749
    #if defined(WOLFSSL_SM2)
750
        #ifdef HAVE_OID_ENCODING
751
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
752
            #define CODED_SM2P256V1_SZ 6
753
        #else
754
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
755
            #define CODED_SM2P256V1_SZ 8
756
        #endif
757
        #ifndef WOLFSSL_ECC_CURVE_STATIC
758
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
759
        #else
760
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
761
        #endif
762
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
763
    #endif /* WOLFSSL_SM2 */
764
#ifdef ECC320
765
    #ifdef HAVE_ECC_BRAINPOOL
766
        #ifdef HAVE_OID_ENCODING
767
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
768
            #define CODED_BRAINPOOLP320R1_SZ 10
769
        #else
770
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
771
            #define CODED_BRAINPOOLP320R1_SZ 9
772
        #endif
773
        #ifndef WOLFSSL_ECC_CURVE_STATIC
774
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
775
        #else
776
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
777
        #endif
778
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
779
    #endif /* HAVE_ECC_BRAINPOOL */
780
#endif /* ECC320 */
781
#ifdef ECC384
782
    #ifndef NO_ECC_SECP
783
        #ifdef HAVE_OID_ENCODING
784
            #define CODED_SECP384R1    {1,3,132,0,34}
785
            #define CODED_SECP384R1_SZ 5
786
        #else
787
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
788
            #define CODED_SECP384R1_SZ 5
789
        #endif
790
        #ifndef WOLFSSL_ECC_CURVE_STATIC
791
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
792
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
793
        #else
794
            #define ecc_oid_secp384r1 CODED_SECP384R1
795
        #endif
796
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
797
    #endif /* !NO_ECC_SECP */
798
    #ifdef HAVE_ECC_BRAINPOOL
799
        #ifdef HAVE_OID_ENCODING
800
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
801
            #define CODED_BRAINPOOLP384R1_SZ 10
802
        #else
803
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
804
            #define CODED_BRAINPOOLP384R1_SZ 9
805
        #endif
806
        #ifndef WOLFSSL_ECC_CURVE_STATIC
807
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
808
        #else
809
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
810
        #endif
811
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
812
    #endif /* HAVE_ECC_BRAINPOOL */
813
#endif /* ECC384 */
814
#ifdef ECC512
815
    #ifdef HAVE_ECC_BRAINPOOL
816
        #ifdef HAVE_OID_ENCODING
817
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
818
            #define CODED_BRAINPOOLP512R1_SZ 10
819
        #else
820
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
821
            #define CODED_BRAINPOOLP512R1_SZ 9
822
        #endif
823
        #ifndef WOLFSSL_ECC_CURVE_STATIC
824
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
825
        #else
826
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
827
        #endif
828
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
829
    #endif /* HAVE_ECC_BRAINPOOL */
830
#endif /* ECC512 */
831
#ifdef ECC521
832
    #ifndef NO_ECC_SECP
833
        #ifdef HAVE_OID_ENCODING
834
            #define CODED_SECP521R1     {1,3,132,0,35}
835
            #define CODED_SECP521R1_SZ 5
836
        #else
837
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
838
            #define CODED_SECP521R1_SZ 5
839
        #endif
840
        #ifndef WOLFSSL_ECC_CURVE_STATIC
841
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
842
        #else
843
            #define ecc_oid_secp521r1 CODED_SECP521R1
844
        #endif
845
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
846
    #endif /* !NO_ECC_SECP */
847
#endif /* ECC521 */
848
849
850
/* This holds the key settings.
851
   ***MUST*** be organized by size from smallest to largest. */
852
853
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
854
    #undef ecc_sets
855
    #undef ecc_sets_count
856
#endif
857
858
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
859
static
860
#endif
861
const ecc_set_type ecc_sets[] = {
862
#ifdef ECC112
863
    #ifndef NO_ECC_SECP
864
    {
865
        14,                             /* size/bytes */
866
        ECC_SECP112R1,                  /* ID         */
867
        "SECP112R1",                    /* curve name */
868
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
869
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
870
        "659EF8BA043916EEDE8911702B22", /* B          */
871
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
872
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
873
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
874
        ecc_oid_secp112r1,              /* oid/oidSz  */
875
        ecc_oid_secp112r1_sz,
876
        ECC_SECP112R1_OID,              /* oid sum    */
877
        1,                              /* cofactor   */
878
    },
879
    #endif /* !NO_ECC_SECP */
880
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
881
    {
882
        14,                             /* size/bytes */
883
        ECC_SECP112R2,                  /* ID         */
884
        "SECP112R2",                    /* curve name */
885
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
886
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
887
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
888
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
889
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
890
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
891
        ecc_oid_secp112r2,              /* oid/oidSz  */
892
        ecc_oid_secp112r2_sz,
893
        ECC_SECP112R2_OID,              /* oid sum    */
894
        4,                              /* cofactor   */
895
    },
896
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
897
#endif /* ECC112 */
898
#ifdef ECC128
899
    #ifndef NO_ECC_SECP
900
    {
901
        16,                                 /* size/bytes */
902
        ECC_SECP128R1,                      /* ID         */
903
        "SECP128R1",                        /* curve name */
904
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
905
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
906
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
907
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
908
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
909
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
910
        ecc_oid_secp128r1,                  /* oid/oidSz  */
911
        ecc_oid_secp128r1_sz,
912
        ECC_SECP128R1_OID,                  /* oid sum    */
913
        1,                                  /* cofactor   */
914
    },
915
    #endif /* !NO_ECC_SECP */
916
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
917
    {
918
        16,                                 /* size/bytes */
919
        ECC_SECP128R2,                      /* ID         */
920
        "SECP128R2",                        /* curve name */
921
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
922
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
923
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
924
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
925
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
926
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
927
        ecc_oid_secp128r2,                  /* oid/oidSz  */
928
        ecc_oid_secp128r2_sz,
929
        ECC_SECP128R2_OID,                  /* oid sum    */
930
        4,                                  /* cofactor   */
931
    },
932
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
933
#endif /* ECC128 */
934
#ifdef ECC160
935
#ifndef FP_ECC
936
    #ifndef NO_ECC_SECP
937
    {
938
        20,                                         /* size/bytes */
939
        ECC_SECP160R1,                              /* ID         */
940
        "SECP160R1",                                /* curve name */
941
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
942
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
943
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
944
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
945
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
946
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
947
        ecc_oid_secp160r1,                          /* oid/oidSz  */
948
        ecc_oid_secp160r1_sz,
949
        ECC_SECP160R1_OID,                          /* oid sum    */
950
        1,                                          /* cofactor   */
951
    },
952
    #endif /* !NO_ECC_SECP */
953
    #ifdef HAVE_ECC_SECPR2
954
    {
955
        20,                                         /* size/bytes */
956
        ECC_SECP160R2,                              /* ID         */
957
        "SECP160R2",                                /* curve name */
958
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
959
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
960
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
961
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
962
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
963
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
964
        ecc_oid_secp160r2,                          /* oid/oidSz  */
965
        ecc_oid_secp160r2_sz,
966
        ECC_SECP160R2_OID,                          /* oid sum    */
967
        1,                                          /* cofactor   */
968
    },
969
    #endif /* HAVE_ECC_SECPR2 */
970
    #ifdef HAVE_ECC_KOBLITZ
971
    {
972
        20,                                         /* size/bytes */
973
        ECC_SECP160K1,                              /* ID         */
974
        "SECP160K1",                                /* curve name */
975
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
976
        "0000000000000000000000000000000000000000", /* A          */
977
        "0000000000000000000000000000000000000007", /* B          */
978
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
979
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
980
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
981
        ecc_oid_secp160k1,                          /* oid/oidSz  */
982
        ecc_oid_secp160k1_sz,
983
        ECC_SECP160K1_OID,                          /* oid sum    */
984
        1,                                          /* cofactor   */
985
    },
986
    #endif /* HAVE_ECC_KOBLITZ */
987
#endif /* !FP_ECC */
988
    #ifdef HAVE_ECC_BRAINPOOL
989
    {
990
        20,                                         /* size/bytes */
991
        ECC_BRAINPOOLP160R1,                        /* ID         */
992
        "BRAINPOOLP160R1",                          /* curve name */
993
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
994
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
995
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
996
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
997
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
998
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
999
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1000
        ecc_oid_brainpoolp160r1_sz,
1001
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1002
        1,                                          /* cofactor   */
1003
    },
1004
    #endif /* HAVE_ECC_BRAINPOOL */
1005
#endif /* ECC160 */
1006
#ifdef ECC192
1007
    #ifndef NO_ECC_SECP
1008
    {
1009
        24,                                                 /* size/bytes */
1010
        ECC_SECP192R1,                                      /* ID         */
1011
        "SECP192R1",                                        /* curve name */
1012
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1013
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1014
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1015
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1016
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1017
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1018
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1019
        ecc_oid_secp192r1_sz,
1020
        ECC_SECP192R1_OID,                                  /* oid sum    */
1021
        1,                                                  /* cofactor   */
1022
    },
1023
    #endif /* !NO_ECC_SECP */
1024
    #ifdef HAVE_ECC_SECPR2
1025
    {
1026
        24,                                                 /* size/bytes */
1027
        ECC_PRIME192V2,                                     /* ID         */
1028
        "PRIME192V2",                                       /* curve name */
1029
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1030
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1031
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1032
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1033
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1034
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1035
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1036
        ecc_oid_prime192v2_sz,
1037
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1038
        1,                                                  /* cofactor   */
1039
    },
1040
    #endif /* HAVE_ECC_SECPR2 */
1041
    #ifdef HAVE_ECC_SECPR3
1042
    {
1043
        24,                                                 /* size/bytes */
1044
        ECC_PRIME192V3,                                     /* ID         */
1045
        "PRIME192V3",                                       /* curve name */
1046
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1047
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1048
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1049
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1050
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1051
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1052
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1053
        ecc_oid_prime192v3_sz,
1054
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1055
        1,                                                  /* cofactor   */
1056
    },
1057
    #endif /* HAVE_ECC_SECPR3 */
1058
    #ifdef HAVE_ECC_KOBLITZ
1059
    {
1060
        24,                                                 /* size/bytes */
1061
        ECC_SECP192K1,                                      /* ID         */
1062
        "SECP192K1",                                        /* curve name */
1063
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1064
        "000000000000000000000000000000000000000000000000", /* A          */
1065
        "000000000000000000000000000000000000000000000003", /* B          */
1066
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1067
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1068
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1069
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1070
        ecc_oid_secp192k1_sz,
1071
        ECC_SECP192K1_OID,                                  /* oid sum    */
1072
        1,                                                  /* cofactor   */
1073
    },
1074
    #endif /* HAVE_ECC_KOBLITZ */
1075
    #ifdef HAVE_ECC_BRAINPOOL
1076
    {
1077
        24,                                                 /* size/bytes */
1078
        ECC_BRAINPOOLP192R1,                                /* ID         */
1079
        "BRAINPOOLP192R1",                                  /* curve name */
1080
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1081
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1082
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1083
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1084
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1085
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1086
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1087
        ecc_oid_brainpoolp192r1_sz,
1088
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1089
        1,                                                  /* cofactor   */
1090
    },
1091
    #endif /* HAVE_ECC_BRAINPOOL */
1092
#endif /* ECC192 */
1093
#ifdef ECC224
1094
    #ifndef NO_ECC_SECP
1095
    {
1096
        28,                                                         /* size/bytes */
1097
        ECC_SECP224R1,                                              /* ID         */
1098
        "SECP224R1",                                                /* curve name */
1099
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1100
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1101
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1102
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1103
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1104
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1105
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1106
        ecc_oid_secp224r1_sz,
1107
        ECC_SECP224R1_OID,                                          /* oid sum    */
1108
        1,                                                          /* cofactor   */
1109
    },
1110
    #endif /* !NO_ECC_SECP */
1111
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1112
    {
1113
        28,                                                         /* size/bytes */
1114
        ECC_SECP224K1,                                              /* ID         */
1115
        "SECP224K1",                                                /* curve name */
1116
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1117
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1118
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1119
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1120
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1121
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1122
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1123
        ecc_oid_secp224k1_sz,
1124
        ECC_SECP224K1_OID,                                          /* oid sum    */
1125
        1,                                                          /* cofactor   */
1126
    },
1127
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1128
    #ifdef HAVE_ECC_BRAINPOOL
1129
    {
1130
        28,                                                         /* size/bytes */
1131
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1132
        "BRAINPOOLP224R1",                                          /* curve name */
1133
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1134
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1135
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1136
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1137
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1138
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1139
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1140
        ecc_oid_brainpoolp224r1_sz,
1141
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1142
        1,                                                          /* cofactor   */
1143
    },
1144
    #endif /* HAVE_ECC_BRAINPOOL */
1145
#endif /* ECC224 */
1146
#ifdef ECC239
1147
    #ifndef NO_ECC_SECP
1148
    {
1149
        30,                                                             /* size/bytes */
1150
        ECC_PRIME239V1,                                                 /* ID         */
1151
        "PRIME239V1",                                                   /* curve name */
1152
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1153
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1154
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1155
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1156
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1157
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1158
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1159
        ecc_oid_prime239v1_sz,
1160
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1161
        1,                                                              /* cofactor   */
1162
    },
1163
    #endif /* !NO_ECC_SECP */
1164
    #ifdef HAVE_ECC_SECPR2
1165
    {
1166
        30,                                                             /* size/bytes */
1167
        ECC_PRIME239V2,                                                 /* ID         */
1168
        "PRIME239V2",                                                   /* curve name */
1169
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1170
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1171
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1172
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1173
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1174
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1175
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1176
        ecc_oid_prime239v2_sz,
1177
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1178
        1,                                                              /* cofactor   */
1179
    },
1180
    #endif /* HAVE_ECC_SECPR2 */
1181
    #ifdef HAVE_ECC_SECPR3
1182
    {
1183
        30,                                                             /* size/bytes */
1184
        ECC_PRIME239V3,                                                 /* ID         */
1185
        "PRIME239V3",                                                   /* curve name */
1186
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1187
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1188
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1189
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1190
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1191
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1192
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1193
        ecc_oid_prime239v3_sz,
1194
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1195
        1,                                                              /* cofactor   */
1196
    },
1197
    #endif /* HAVE_ECC_SECPR3 */
1198
#endif /* ECC239 */
1199
#ifdef ECC256
1200
    #ifndef NO_ECC_SECP
1201
    {
1202
        32,                                                                 /* size/bytes */
1203
        ECC_SECP256R1,                                                      /* ID         */
1204
        "SECP256R1",                                                        /* curve name */
1205
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1206
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1207
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1208
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1209
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1210
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1211
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1212
        ecc_oid_secp256r1_sz,
1213
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1214
        1,                                                                  /* cofactor   */
1215
    },
1216
    #endif /* !NO_ECC_SECP */
1217
    #ifdef HAVE_ECC_KOBLITZ
1218
    {
1219
        32,                                                                 /* size/bytes */
1220
        ECC_SECP256K1,                                                      /* ID         */
1221
        "SECP256K1",                                                        /* curve name */
1222
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1223
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1224
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1225
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1226
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1227
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1228
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1229
        ecc_oid_secp256k1_sz,
1230
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1231
        1,                                                                  /* cofactor   */
1232
    },
1233
    #endif /* HAVE_ECC_KOBLITZ */
1234
    #ifdef HAVE_ECC_BRAINPOOL
1235
    {
1236
        32,                                                                 /* size/bytes */
1237
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1238
        "BRAINPOOLP256R1",                                                  /* curve name */
1239
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1240
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1241
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1242
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1243
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1244
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1245
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1246
        ecc_oid_brainpoolp256r1_sz,
1247
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1248
        1,                                                                  /* cofactor   */
1249
    },
1250
    #endif /* HAVE_ECC_BRAINPOOL */
1251
#endif /* ECC256 */
1252
    #if defined(WOLFSSL_SM2)
1253
    {
1254
        32,                                                     /* size/bytes */
1255
        ECC_SM2P256V1,                                          /* ID         */
1256
        "SM2P256V1",                                            /* curve name */
1257
1258
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1259
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1260
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1261
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1262
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1263
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1264
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1265
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1266
        ecc_oid_sm2p256v1_sz,
1267
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1268
        1,                                                      /* cofactor   */
1269
    },
1270
    #endif /* WOLFSSL_SM2 */
1271
#ifdef ECC320
1272
    #ifdef HAVE_ECC_BRAINPOOL
1273
    {
1274
        40,                                                                                 /* size/bytes */
1275
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1276
        "BRAINPOOLP320R1",                                                                  /* curve name */
1277
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1278
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1279
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1280
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1281
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1282
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1283
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1284
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1285
        1,                                                                                  /* cofactor   */
1286
    },
1287
    #endif /* HAVE_ECC_BRAINPOOL */
1288
#endif /* ECC320 */
1289
#ifdef ECC384
1290
    #ifndef NO_ECC_SECP
1291
    {
1292
        48,                                                                                                 /* size/bytes */
1293
        ECC_SECP384R1,                                                                                      /* ID         */
1294
        "SECP384R1",                                                                                        /* curve name */
1295
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1296
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1297
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1298
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1299
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1300
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1301
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1302
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1303
        1,                                                                                                  /* cofactor   */
1304
    },
1305
    #endif /* !NO_ECC_SECP */
1306
    #ifdef HAVE_ECC_BRAINPOOL
1307
    {
1308
        48,                                                                                                 /* size/bytes */
1309
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1310
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1311
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1312
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1313
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1314
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1315
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1316
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1317
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1318
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1319
        1,                                                                                                  /* cofactor   */
1320
    },
1321
    #endif /* HAVE_ECC_BRAINPOOL */
1322
#endif /* ECC384 */
1323
#ifdef ECC512
1324
    #ifdef HAVE_ECC_BRAINPOOL
1325
    {
1326
        64,                                                                                                                                 /* size/bytes */
1327
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1328
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1329
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1330
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1331
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1332
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1333
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1334
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1335
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1336
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1337
        1,                                                                                                                                  /* cofactor   */
1338
    },
1339
    #endif /* HAVE_ECC_BRAINPOOL */
1340
#endif /* ECC512 */
1341
#ifdef ECC521
1342
    #ifndef NO_ECC_SECP
1343
    {
1344
        66,                                                                                                                                    /* size/bytes */
1345
        ECC_SECP521R1,                                                                                                                         /* ID         */
1346
        "SECP521R1",                                                                                                                           /* curve name */
1347
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1348
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1349
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1350
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1351
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1352
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1353
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1354
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1355
        1,                                                                                                                                     /* cofactor   */
1356
    },
1357
    #endif /* !NO_ECC_SECP */
1358
#endif /* ECC521 */
1359
#ifdef WOLFCRYPT_HAVE_SAKKE
1360
    {
1361
        128,
1362
        ECC_SAKKE_1,
1363
        "SAKKE1",
1364
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1365
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1366
        "0",
1367
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1368
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1369
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1370
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1371
            NULL, 0,
1372
        #else
1373
            {0}, 0,
1374
        #endif
1375
        0,
1376
        4,
1377
    },
1378
#endif
1379
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1380
    /* place holder for custom curve index for cache */
1381
    {
1382
        1, /* non-zero */
1383
        ECC_CURVE_CUSTOM,
1384
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1385
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1386
        #else
1387
            {0},{0},{0},{0},{0},{0},{0},{0},
1388
        #endif
1389
        0, 0, 0
1390
    },
1391
#endif
1392
    {
1393
        0,
1394
        ECC_CURVE_INVALID,
1395
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1396
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1397
        #else
1398
            {0},{0},{0},{0},{0},{0},{0},{0},
1399
        #endif
1400
        0, 0, 0
1401
    }
1402
};
1403
60.7k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1404
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1405
static
1406
#endif
1407
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1408
1409
175k
const ecc_set_type *wc_ecc_get_sets(void) {
1410
175k
    return ecc_sets;
1411
175k
}
1412
0
size_t wc_ecc_get_sets_count(void) {
1413
0
    return ecc_sets_count;
1414
0
}
1415
1416
#ifdef HAVE_OID_ENCODING
1417
    /* encoded OID cache */
1418
    typedef struct {
1419
        word32 oidSz;
1420
        byte oid[ECC_MAX_OID_LEN];
1421
    } oid_cache_t;
1422
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1423
1424
    static wolfSSL_Mutex ecc_oid_cache_lock
1425
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1426
#ifndef WOLFSSL_MUTEX_INITIALIZER
1427
    static volatile int eccOidLockInit = 0;
1428
#endif
1429
#endif /* HAVE_OID_ENCODING */
1430
1431
/* Forward declarations */
1432
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1433
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1434
#endif
1435
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1436
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1437
    mp_int* prime, mp_int* order);
1438
#endif
1439
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1440
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1441
    !defined(WOLFSSL_KCAPI_ECC)
1442
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1443
#endif
1444
1445
1446
#ifdef HAVE_COMP_KEY
1447
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1448
    !defined(WOLFSSL_CRYPTOCELL)
1449
1450
#ifndef WOLFSSL_SP_MATH
1451
#if !defined(SQRTMOD_USE_MOD_EXP)
1452
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1453
#endif
1454
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1455
#endif
1456
#endif
1457
#endif
1458
1459
1460
/* Curve Specs */
1461
typedef struct ecc_curve_spec {
1462
    const ecc_set_type* dp;
1463
1464
    mp_int* prime;
1465
    mp_int* Af;
1466
    #ifdef USE_ECC_B_PARAM
1467
        mp_int* Bf;
1468
    #endif
1469
    mp_int* order;
1470
    mp_int* Gx;
1471
    mp_int* Gy;
1472
1473
#ifdef ECC_CACHE_CURVE
1474
    mp_int prime_lcl;
1475
    mp_int Af_lcl;
1476
    #ifdef USE_ECC_B_PARAM
1477
        mp_int Bf_lcl;
1478
    #endif
1479
    mp_int order_lcl;
1480
    mp_int Gx_lcl;
1481
    mp_int Gy_lcl;
1482
#else
1483
#ifdef WOLFSSL_SP_MATH_ALL
1484
    unsigned char* spec_ints;
1485
#else
1486
    mp_int* spec_ints;
1487
#endif
1488
    word32 spec_count;
1489
    word32 spec_use;
1490
#endif
1491
1492
    byte load_mask;
1493
} ecc_curve_spec;
1494
1495
    #define ECC_CURVE_FIELD_NONE    0x00
1496
220k
    #define ECC_CURVE_FIELD_PRIME   0x01
1497
220k
    #define ECC_CURVE_FIELD_AF      0x02
1498
#ifdef USE_ECC_B_PARAM
1499
217k
    #define ECC_CURVE_FIELD_BF      0x04
1500
#endif
1501
202k
    #define ECC_CURVE_FIELD_ORDER   0x08
1502
168k
    #define ECC_CURVE_FIELD_GX      0x10
1503
168k
    #define ECC_CURVE_FIELD_GY      0x20
1504
#ifdef USE_ECC_B_PARAM
1505
4.59k
    #define ECC_CURVE_FIELD_ALL     0x3F
1506
    #define ECC_CURVE_FIELD_COUNT   6
1507
#else
1508
    #define ECC_CURVE_FIELD_ALL     0x3B
1509
    #define ECC_CURVE_FIELD_COUNT   5
1510
#endif
1511
1512
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1513
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1514
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1515
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1516
};
1517
1518
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1519
{
1520
    word32 up, down;
1521
    up = 0;
1522
    down = len - 1;
1523
    while (up < len)
1524
        outbuf[up++] = inbuf[down--];
1525
}
1526
1527
static int xil_mpi_import(mp_int *mpi,
1528
                          const byte *inbuf,
1529
                          word32 len,
1530
                          void* heap)
1531
{
1532
    int err;
1533
#ifdef WOLFSSL_SMALL_STACK
1534
    byte* buf = NULL;
1535
#else
1536
    byte buf[MAX_ECC_BYTES];
1537
1538
    if (len > MAX_ECC_BYTES)
1539
        return BUFFER_E;
1540
#endif
1541
1542
    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
1543
        return MEMORY_E);
1544
    buf_reverse(buf, inbuf, len);
1545
1546
    err = mp_read_unsigned_bin(mpi, buf, len);
1547
    ForceZero(buf, len);
1548
    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1549
    return err;
1550
}
1551
#endif
1552
1553
#ifdef ECC_CACHE_CURVE
1554
    /* cache (mp_int) of the curve parameters */
1555
    #ifdef WOLFSSL_NO_MALLOC
1556
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1557
    #else
1558
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1559
    #endif
1560
    #ifndef SINGLE_THREADED
1561
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1562
    #endif
1563
1564
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1565
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1566
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1567
#elif defined(WOLFSSL_SMALL_STACK)
1568
#ifdef WOLFSSL_SP_MATH_ALL
1569
    #define DECLARE_CURVE_SPECS(intcount)                               \
1570
        unsigned char* spec_ints = NULL;                                \
1571
        ecc_curve_spec curve_lcl;                                       \
1572
        ecc_curve_spec* curve = &curve_lcl;                             \
1573
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1574
        curve->spec_count = intcount
1575
1576
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1577
    do {                                                                \
1578
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1579
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1580
            DYNAMIC_TYPE_ECC);                                          \
1581
        if (spec_ints == NULL)                                          \
1582
            (err) = MEMORY_E;                                           \
1583
        else {                                                          \
1584
            curve->spec_ints = spec_ints;                               \
1585
            (err) = MP_OKAY;                                            \
1586
        }                                                               \
1587
    } while (0)
1588
#else
1589
    #define DECLARE_CURVE_SPECS(intcount)                               \
1590
11.1k
        mp_int* spec_ints = NULL;                                       \
1591
11.1k
        ecc_curve_spec curve_lcl;                                       \
1592
11.1k
        ecc_curve_spec* curve = &curve_lcl;                             \
1593
11.1k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1594
11.1k
        curve->spec_count = intcount
1595
1596
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1597
11.0k
    do {                                                                \
1598
11.0k
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1599
11.0k
                            DYNAMIC_TYPE_ECC);                          \
1600
11.0k
        if (spec_ints == NULL)                                          \
1601
11.0k
            (err) = MEMORY_E;                                           \
1602
11.0k
        else {                                                          \
1603
10.7k
            curve->spec_ints = spec_ints;                               \
1604
10.7k
            (err) = MP_OKAY;                                            \
1605
10.7k
        }                                                               \
1606
11.0k
    } while (0)
1607
#endif
1608
    #define FREE_CURVE_SPECS()                                          \
1609
11.0k
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1610
#else
1611
#ifdef WOLFSSL_SP_MATH_ALL
1612
    #define DECLARE_CURVE_SPECS(intcount)                               \
1613
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1614
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1615
        ecc_curve_spec curve_lcl;                                       \
1616
        ecc_curve_spec* curve = &curve_lcl;                             \
1617
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1618
        curve->spec_ints = spec_ints;                                   \
1619
        curve->spec_count = (intcount)
1620
#else
1621
    #define DECLARE_CURVE_SPECS(intcount)                               \
1622
        mp_int spec_ints[(intcount)];                                   \
1623
        ecc_curve_spec curve_lcl;                                       \
1624
        ecc_curve_spec* curve = &curve_lcl;                             \
1625
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1626
        curve->spec_ints = spec_ints;                                   \
1627
        curve->spec_count = (intcount)
1628
#endif
1629
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1630
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1631
#endif /* ECC_CACHE_CURVE */
1632
1633
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1634
    byte mask)
1635
253k
{
1636
253k
    if (item) {
1637
    #ifdef HAVE_WOLF_BIGINT
1638
        wc_bigint_free(&item->raw);
1639
    #endif
1640
253k
        mp_clear(item);
1641
253k
    }
1642
253k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1643
253k
}
1644
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1645
58.7k
{
1646
58.7k
    if (curve == NULL) {
1647
0
        return;
1648
0
    }
1649
1650
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1651
49.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1652
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1653
49.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1654
58.7k
#ifdef USE_ECC_B_PARAM
1655
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1656
48.4k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1657
58.7k
#endif
1658
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1659
41.8k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1660
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1661
26.1k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1662
58.7k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1663
26.1k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1664
1665
58.7k
    curve->load_mask = 0;
1666
58.7k
}
1667
1668
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1669
61.6k
{
1670
61.6k
    if (curve) {
1671
    #ifdef ECC_CACHE_CURVE
1672
        #ifdef WOLFSSL_CUSTOM_CURVES
1673
        /* only free custom curves (rest are globally cached) */
1674
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1675
            wc_ecc_curve_cache_free_spec(curve);
1676
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1677
        }
1678
        #endif
1679
    #else
1680
61.6k
        wc_ecc_curve_cache_free_spec(curve);
1681
61.6k
    #endif
1682
61.6k
    }
1683
61.6k
}
1684
1685
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1686
    mp_int** dst, byte mask)
1687
56.0k
{
1688
56.0k
    int err;
1689
1690
56.0k
#ifndef ECC_CACHE_CURVE
1691
    /* get mp_int from temp */
1692
56.0k
    if (curve->spec_use >= curve->spec_count) {
1693
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1694
0
        return ECC_BAD_ARG_E;
1695
0
    }
1696
#ifdef WOLFSSL_SP_MATH_ALL
1697
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1698
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1699
#else
1700
56.0k
    *dst = &curve->spec_ints[curve->spec_use++];
1701
56.0k
#endif
1702
56.0k
#endif
1703
1704
#ifdef WOLFSSL_SP_MATH_ALL
1705
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1706
#else
1707
56.0k
    err = mp_init(*dst);
1708
56.0k
#endif
1709
56.0k
    if (err == MP_OKAY) {
1710
56.0k
        curve->load_mask |= mask;
1711
1712
56.0k
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1713
1714
    #ifdef HAVE_WOLF_BIGINT
1715
        if (err == MP_OKAY)
1716
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1717
    #endif
1718
56.0k
    }
1719
56.0k
    return err;
1720
56.0k
}
1721
1722
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1723
    byte load_mask)
1724
57.0k
{
1725
57.0k
    int ret = 0;
1726
57.0k
    ecc_curve_spec* curve;
1727
57.0k
    byte load_items = 0; /* mask of items to load */
1728
#ifdef ECC_CACHE_CURVE
1729
    int x;
1730
#endif
1731
1732
57.0k
    if (dp == NULL || pCurve == NULL)
1733
0
        return BAD_FUNC_ARG;
1734
1735
#ifdef ECC_CACHE_CURVE
1736
    x = wc_ecc_get_curve_idx(dp->id);
1737
    if (x == ECC_CURVE_INVALID)
1738
        return ECC_BAD_ARG_E;
1739
1740
#if !defined(SINGLE_THREADED)
1741
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1742
    if (ret != 0) {
1743
        return ret;
1744
    }
1745
#endif
1746
1747
#ifdef WOLFSSL_NO_MALLOC
1748
    curve = &ecc_curve_spec_cache[x];
1749
#else
1750
    /* make sure cache has been allocated */
1751
    if (ecc_curve_spec_cache[x] == NULL
1752
    #ifdef WOLFSSL_CUSTOM_CURVES
1753
        || dp->id == ECC_CURVE_CUSTOM
1754
    #endif
1755
    ) {
1756
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1757
        if (curve == NULL) {
1758
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1759
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1760
        #endif
1761
            return MEMORY_E;
1762
        }
1763
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1764
1765
        /* set curve pointer to cache */
1766
    #ifdef WOLFSSL_CUSTOM_CURVES
1767
        if (dp->id != ECC_CURVE_CUSTOM)
1768
    #endif
1769
        {
1770
            ecc_curve_spec_cache[x] = curve;
1771
        }
1772
    }
1773
    else {
1774
        curve = ecc_curve_spec_cache[x];
1775
    }
1776
#endif /* WOLFSSL_NO_MALLOC */
1777
1778
    /* return new or cached curve */
1779
    *pCurve = curve;
1780
#else
1781
57.0k
    curve = *pCurve;
1782
57.0k
#endif /* ECC_CACHE_CURVE */
1783
1784
    /* make sure the curve is initialized */
1785
57.0k
    if (curve->dp != dp) {
1786
57.0k
        curve->load_mask = 0;
1787
1788
    #ifdef ECC_CACHE_CURVE
1789
        curve->prime = &curve->prime_lcl;
1790
        curve->Af = &curve->Af_lcl;
1791
        #ifdef USE_ECC_B_PARAM
1792
            curve->Bf = &curve->Bf_lcl;
1793
        #endif
1794
        curve->order = &curve->order_lcl;
1795
        curve->Gx = &curve->Gx_lcl;
1796
        curve->Gy = &curve->Gy_lcl;
1797
    #endif
1798
57.0k
    }
1799
57.0k
    curve->dp = dp; /* set dp info */
1800
1801
    /* determine items to load */
1802
57.0k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1803
57.0k
    curve->load_mask |= load_items;
1804
1805
    /* load items */
1806
57.0k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1807
49.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1808
49.8k
            ECC_CURVE_FIELD_PRIME);
1809
57.0k
    if (load_items & ECC_CURVE_FIELD_AF)
1810
49.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1811
49.8k
            ECC_CURVE_FIELD_AF);
1812
57.0k
#ifdef USE_ECC_B_PARAM
1813
57.0k
    if (load_items & ECC_CURVE_FIELD_BF)
1814
48.4k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1815
48.4k
            ECC_CURVE_FIELD_BF);
1816
57.0k
#endif
1817
57.0k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1818
41.8k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1819
41.8k
            ECC_CURVE_FIELD_ORDER);
1820
57.0k
    if (load_items & ECC_CURVE_FIELD_GX)
1821
26.1k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1822
26.1k
            ECC_CURVE_FIELD_GX);
1823
57.0k
    if (load_items & ECC_CURVE_FIELD_GY)
1824
26.1k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1825
26.1k
            ECC_CURVE_FIELD_GY);
1826
1827
    /* check for error */
1828
57.0k
    if (ret != 0) {
1829
121
        wc_ecc_curve_free(curve);
1830
121
        ret = MP_READ_E;
1831
121
    }
1832
1833
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1834
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1835
#endif
1836
1837
57.0k
    return ret;
1838
57.0k
}
1839
1840
#ifdef ECC_CACHE_CURVE
1841
int wc_ecc_curve_cache_init(void)
1842
{
1843
    int ret = 0;
1844
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1845
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1846
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1847
#endif
1848
    return ret;
1849
}
1850
1851
void wc_ecc_curve_cache_free(void)
1852
{
1853
    int x;
1854
1855
    /* free all ECC curve caches */
1856
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1857
    #ifdef WOLFSSL_NO_MALLOC
1858
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1859
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1860
    #else
1861
        if (ecc_curve_spec_cache[x]) {
1862
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1863
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1864
            ecc_curve_spec_cache[x] = NULL;
1865
        }
1866
    #endif /* WOLFSSL_NO_MALLOC */
1867
    }
1868
1869
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1870
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1871
    wc_FreeMutex(&ecc_curve_cache_mutex);
1872
#endif
1873
}
1874
#endif /* ECC_CACHE_CURVE */
1875
1876
1877
/* Retrieve the curve name for the ECC curve id.
1878
 *
1879
 * curve_id  The id of the curve.
1880
 * returns the name stored from the curve if available, otherwise NULL.
1881
 */
1882
const char* wc_ecc_get_name(int curve_id)
1883
9.51k
{
1884
9.51k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1885
9.51k
    if (curve_idx == ECC_CURVE_INVALID)
1886
0
        return NULL;
1887
9.51k
    return ecc_sets[curve_idx].name;
1888
9.51k
}
1889
1890
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1891
50.5k
{
1892
50.5k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1893
0
        return BAD_FUNC_ARG;
1894
0
    }
1895
1896
50.5k
    if (keysize > ECC_MAXSIZE) {
1897
777
        return ECC_BAD_ARG_E;
1898
777
    }
1899
1900
    /* handle custom case */
1901
49.7k
    if (key->idx != ECC_CUSTOM_IDX) {
1902
49.6k
        int x;
1903
1904
        /* default values */
1905
49.6k
        key->idx = 0;
1906
49.6k
        key->dp = NULL;
1907
1908
        /* find ecc_set based on curve_id or key size */
1909
846k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1910
846k
            if (curve_id > ECC_CURVE_DEF) {
1911
747k
                if (curve_id == ecc_sets[x].id)
1912
44.6k
                  break;
1913
747k
            }
1914
99.0k
            else if (keysize <= ecc_sets[x].size) {
1915
4.97k
                break;
1916
4.97k
            }
1917
846k
        }
1918
49.6k
        if (ecc_sets[x].size == 0) {
1919
17
            WOLFSSL_MSG("ECC Curve not found");
1920
17
            return ECC_CURVE_OID_E;
1921
17
        }
1922
1923
49.6k
        key->idx = x;
1924
49.6k
        key->dp  = &ecc_sets[x];
1925
49.6k
    }
1926
1927
49.7k
    return 0;
1928
49.7k
}
1929
1930
1931
#ifdef ALT_ECC_SIZE
1932
static void alt_fp_init(mp_int* a)
1933
{
1934
    a->size = FP_SIZE_ECC;
1935
    mp_zero(a);
1936
}
1937
#endif /* ALT_ECC_SIZE */
1938
1939
1940
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1941
    !defined(WOLFSSL_CRYPTOCELL) && \
1942
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
1943
      defined(WOLFSSL_IMXRT1170_CAAM))
1944
1945
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
1946
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
1947
                                     mp_int* modulus, mp_digit mp);
1948
1949
/**
1950
   Add two ECC points
1951
   P        The point to add
1952
   Q        The point to add
1953
   R        [out] The destination of the double
1954
   a        ECC curve parameter a
1955
   modulus  The modulus of the field the ECC curve is in
1956
   mp       The "b" value from montgomery_setup()
1957
   return   MP_OKAY on success
1958
*/
1959
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
1960
                                     mp_int* a, mp_int* modulus, mp_digit mp)
1961
889k
{
1962
889k
#if !defined(WOLFSSL_SP_MATH)
1963
889k
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1964
889k
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1965
#ifdef ALT_ECC_SIZE
1966
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1967
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1968
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
1969
#endif
1970
889k
   mp_int  *x, *y, *z;
1971
889k
   int     err;
1972
1973
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
1974
889k
   if (Q == R) {
1975
0
      ecc_point* tPt  = P;
1976
0
      P = Q;
1977
0
      Q = tPt;
1978
0
   }
1979
1980
889k
#ifdef WOLFSSL_SMALL_STACK
1981
#ifdef WOLFSSL_SMALL_STACK_CACHE
1982
   if (R->key != NULL) {
1983
       t1 = R->key->t1;
1984
       t2 = R->key->t2;
1985
#ifdef ALT_ECC_SIZE
1986
       rx = R->key->x;
1987
       ry = R->key->y;
1988
       rz = R->key->z;
1989
#endif
1990
   }
1991
   else
1992
#endif /* WOLFSSL_SMALL_STACK_CACHE */
1993
889k
#endif /* WOLFSSL_SMALL_STACK */
1994
889k
   {
1995
889k
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1996
889k
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
1997
   #ifdef MP_INT_SIZE_CHECK_NULL
1998
      if (t1 == NULL || t2 == NULL) {
1999
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2000
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2001
         return MEMORY_E;
2002
      }
2003
   #endif
2004
#ifdef ALT_ECC_SIZE
2005
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2006
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2007
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2008
   #ifdef MP_INT_SIZE_CHECK_NULL
2009
      if (rx == NULL || ry == NULL || rz == NULL) {
2010
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2011
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2012
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2013
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2014
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2015
         return MEMORY_E;
2016
      }
2017
   #endif
2018
#endif
2019
889k
   }
2020
2021
889k
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2022
889k
   if (err == MP_OKAY) {
2023
889k
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2024
889k
   }
2025
889k
   if (err != MP_OKAY) {
2026
0
#ifdef WOLFSSL_SMALL_STACK
2027
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2028
      if (R->key == NULL)
2029
   #endif
2030
0
#endif
2031
0
      {
2032
      #ifdef ALT_ECC_SIZE
2033
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2034
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2035
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2036
      #endif
2037
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2038
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2039
0
      }
2040
0
      return err;
2041
0
   }
2042
2043
   /* should we dbl instead? */
2044
889k
   if (err == MP_OKAY) {
2045
889k
#ifdef ECC_TIMING_RESISTANT
2046
889k
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2047
#else
2048
      err = mp_sub(modulus, Q->y, t1);
2049
#endif
2050
889k
   }
2051
889k
   if (err == MP_OKAY) {
2052
889k
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2053
2.53k
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2054
112
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2055
75
          mp_clear(t1);
2056
75
          mp_clear(t2);
2057
75
   #ifdef WOLFSSL_SMALL_STACK
2058
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2059
         if (R->key == NULL)
2060
      #endif
2061
75
   #endif
2062
75
         {
2063
         #ifdef ALT_ECC_SIZE
2064
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2065
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2066
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2067
         #endif
2068
75
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2069
75
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2070
75
         }
2071
75
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2072
75
      }
2073
889k
   }
2074
2075
889k
   if (err != MP_OKAY) {
2076
2
      goto done;
2077
2
   }
2078
2079
/* If use ALT_ECC_SIZE we need to use local stack variable since
2080
   ecc_point x,y,z is reduced size */
2081
#ifdef ALT_ECC_SIZE
2082
   /* Use local stack variable */
2083
   x = rx;
2084
   y = ry;
2085
   z = rz;
2086
2087
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2088
   if (err == MP_OKAY) {
2089
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2090
   }
2091
   if (err == MP_OKAY) {
2092
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2093
   }
2094
   if (err != MP_OKAY) {
2095
      goto done;
2096
   }
2097
#else
2098
   /* Use destination directly */
2099
889k
   x = R->x;
2100
889k
   y = R->y;
2101
889k
   z = R->z;
2102
889k
#endif
2103
2104
889k
   if (err == MP_OKAY)
2105
889k
       err = mp_copy(P->x, x);
2106
889k
   if (err == MP_OKAY)
2107
889k
       err = mp_copy(P->y, y);
2108
889k
   if (err == MP_OKAY)
2109
889k
       err = mp_copy(P->z, z);
2110
2111
   /* if Z is one then these are no-operations */
2112
889k
   if (err == MP_OKAY) {
2113
889k
       if (!mp_iszero(Q->z)) {
2114
           /* T1 = Z' * Z' */
2115
889k
           err = mp_sqr(Q->z, t1);
2116
889k
           if (err == MP_OKAY)
2117
889k
               err = mp_montgomery_reduce(t1, modulus, mp);
2118
2119
           /* X = X * T1 */
2120
889k
           if (err == MP_OKAY)
2121
889k
               err = mp_mul(t1, x, x);
2122
889k
           if (err == MP_OKAY)
2123
889k
               err = mp_montgomery_reduce(x, modulus, mp);
2124
2125
           /* T1 = Z' * T1 */
2126
889k
           if (err == MP_OKAY)
2127
889k
               err = mp_mul(Q->z, t1, t1);
2128
889k
           if (err == MP_OKAY)
2129
889k
               err = mp_montgomery_reduce(t1, modulus, mp);
2130
2131
           /* Y = Y * T1 */
2132
889k
           if (err == MP_OKAY)
2133
889k
               err = mp_mul(t1, y, y);
2134
889k
           if (err == MP_OKAY)
2135
889k
               err = mp_montgomery_reduce(y, modulus, mp);
2136
889k
       }
2137
889k
   }
2138
2139
   /* T1 = Z*Z */
2140
889k
   if (err == MP_OKAY)
2141
889k
       err = mp_sqr(z, t1);
2142
889k
   if (err == MP_OKAY)
2143
889k
       err = mp_montgomery_reduce(t1, modulus, mp);
2144
2145
   /* T2 = X' * T1 */
2146
889k
   if (err == MP_OKAY)
2147
889k
       err = mp_mul(Q->x, t1, t2);
2148
889k
   if (err == MP_OKAY)
2149
889k
       err = mp_montgomery_reduce(t2, modulus, mp);
2150
2151
   /* T1 = Z * T1 */
2152
889k
   if (err == MP_OKAY)
2153
889k
       err = mp_mul(z, t1, t1);
2154
889k
   if (err == MP_OKAY)
2155
889k
       err = mp_montgomery_reduce(t1, modulus, mp);
2156
2157
   /* T1 = Y' * T1 */
2158
889k
   if (err == MP_OKAY)
2159
889k
       err = mp_mul(Q->y, t1, t1);
2160
889k
   if (err == MP_OKAY)
2161
889k
       err = mp_montgomery_reduce(t1, modulus, mp);
2162
2163
   /* Y = Y - T1 */
2164
889k
   if (err == MP_OKAY)
2165
889k
       err = mp_submod_ct(y, t1, modulus, y);
2166
   /* T1 = 2T1 */
2167
889k
   if (err == MP_OKAY)
2168
889k
       err = mp_addmod_ct(t1, t1, modulus, t1);
2169
   /* T1 = Y + T1 */
2170
889k
   if (err == MP_OKAY)
2171
889k
       err = mp_addmod_ct(t1, y, modulus, t1);
2172
   /* X = X - T2 */
2173
889k
   if (err == MP_OKAY)
2174
889k
       err = mp_submod_ct(x, t2, modulus, x);
2175
   /* T2 = 2T2 */
2176
889k
   if (err == MP_OKAY)
2177
889k
       err = mp_addmod_ct(t2, t2, modulus, t2);
2178
   /* T2 = X + T2 */
2179
889k
   if (err == MP_OKAY)
2180
889k
       err = mp_addmod_ct(t2, x, modulus, t2);
2181
2182
889k
   if (err == MP_OKAY) {
2183
889k
       if (!mp_iszero(Q->z)) {
2184
           /* Z = Z * Z' */
2185
889k
           err = mp_mul(z, Q->z, z);
2186
889k
           if (err == MP_OKAY)
2187
889k
               err = mp_montgomery_reduce(z, modulus, mp);
2188
889k
       }
2189
889k
   }
2190
2191
   /* Z = Z * X */
2192
889k
   if (err == MP_OKAY)
2193
889k
       err = mp_mul(z, x, z);
2194
889k
   if (err == MP_OKAY)
2195
889k
       err = mp_montgomery_reduce(z, modulus, mp);
2196
2197
   /* T1 = T1 * X  */
2198
889k
   if (err == MP_OKAY)
2199
889k
       err = mp_mul(t1, x, t1);
2200
889k
   if (err == MP_OKAY)
2201
889k
       err = mp_montgomery_reduce(t1, modulus, mp);
2202
2203
   /* X = X * X */
2204
889k
   if (err == MP_OKAY)
2205
889k
       err = mp_sqr(x, x);
2206
889k
   if (err == MP_OKAY)
2207
889k
       err = mp_montgomery_reduce(x, modulus, mp);
2208
2209
   /* T2 = T2 * x */
2210
889k
   if (err == MP_OKAY)
2211
889k
       err = mp_mul(t2, x, t2);
2212
889k
   if (err == MP_OKAY)
2213
889k
       err = mp_montgomery_reduce(t2, modulus, mp);
2214
2215
   /* T1 = T1 * X  */
2216
889k
   if (err == MP_OKAY)
2217
889k
       err = mp_mul(t1, x, t1);
2218
889k
   if (err == MP_OKAY)
2219
889k
       err = mp_montgomery_reduce(t1, modulus, mp);
2220
2221
   /* X = Y*Y */
2222
889k
   if (err == MP_OKAY)
2223
889k
       err = mp_sqr(y, x);
2224
889k
   if (err == MP_OKAY)
2225
889k
       err = mp_montgomery_reduce(x, modulus, mp);
2226
2227
   /* X = X - T2 */
2228
889k
   if (err == MP_OKAY)
2229
889k
       err = mp_submod_ct(x, t2, modulus, x);
2230
   /* T2 = T2 - X */
2231
889k
   if (err == MP_OKAY)
2232
889k
       err = mp_submod_ct(t2, x, modulus, t2);
2233
   /* T2 = T2 - X */
2234
889k
   if (err == MP_OKAY)
2235
889k
       err = mp_submod_ct(t2, x, modulus, t2);
2236
   /* T2 = T2 * Y */
2237
889k
   if (err == MP_OKAY)
2238
889k
       err = mp_mul(t2, y, t2);
2239
889k
   if (err == MP_OKAY)
2240
889k
       err = mp_montgomery_reduce(t2, modulus, mp);
2241
2242
   /* Y = T2 - T1 */
2243
889k
   if (err == MP_OKAY)
2244
889k
       err = mp_submod_ct(t2, t1, modulus, y);
2245
   /* Y = Y/2 */
2246
889k
   if (err == MP_OKAY)
2247
889k
       err = mp_div_2_mod_ct(y, modulus, y);
2248
2249
#ifdef ALT_ECC_SIZE
2250
   if (err == MP_OKAY)
2251
       err = mp_copy(x, R->x);
2252
   if (err == MP_OKAY)
2253
       err = mp_copy(y, R->y);
2254
   if (err == MP_OKAY)
2255
       err = mp_copy(z, R->z);
2256
#endif
2257
2258
889k
done:
2259
2260
   /* clean up */
2261
889k
   mp_clear(t1);
2262
889k
   mp_clear(t2);
2263
889k
#ifdef WOLFSSL_SMALL_STACK
2264
#ifdef WOLFSSL_SMALL_STACK_CACHE
2265
   if (R->key == NULL)
2266
#endif
2267
889k
#endif
2268
889k
   {
2269
   #ifdef ALT_ECC_SIZE
2270
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2271
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2272
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2273
   #endif
2274
889k
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2275
889k
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2276
889k
   }
2277
2278
889k
   return err;
2279
#else
2280
    int modBits = mp_count_bits(modulus);
2281
2282
    (void)a;
2283
    (void)mp;
2284
2285
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2286
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2287
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2288
                                            R->x, R->y, R->z);
2289
    }
2290
#endif
2291
#ifndef WOLFSSL_SP_NO_256
2292
    if (modBits == 256) {
2293
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2294
                                         R->x, R->y, R->z);
2295
    }
2296
#endif
2297
#ifdef WOLFSSL_SP_384
2298
    if (modBits == 384) {
2299
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2300
                                         R->x, R->y, R->z);
2301
    }
2302
#endif
2303
#ifdef WOLFSSL_SP_521
2304
    if (modBits == 521) {
2305
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2306
                                         R->x, R->y, R->z);
2307
    }
2308
#endif
2309
    return ECC_BAD_ARG_E;
2310
#endif
2311
889k
}
2312
2313
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2314
                             mp_int* a, mp_int* modulus, mp_digit mp)
2315
1.48k
{
2316
1.48k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2317
0
        return ECC_BAD_ARG_E;
2318
0
    }
2319
2320
1.48k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2321
1.47k
        mp_cmp(P->y, modulus) != MP_LT ||
2322
1.46k
        mp_cmp(P->z, modulus) != MP_LT ||
2323
1.46k
        mp_cmp(Q->x, modulus) != MP_LT ||
2324
1.44k
        mp_cmp(Q->y, modulus) != MP_LT ||
2325
1.42k
        mp_cmp(Q->z, modulus) != MP_LT) {
2326
60
        return ECC_OUT_OF_RANGE_E;
2327
60
    }
2328
2329
1.42k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2330
1.48k
}
2331
2332
/* ### Point doubling in Jacobian coordinate system ###
2333
 *
2334
 * let us have a curve:                 y^2 = x^3 + a*x + b
2335
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2336
 *
2337
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2338
 * Xr = M^2 - 2*S
2339
 * Yr = M * (S - Xr) - 8*T
2340
 * Zr = 2 * Yp * Zp
2341
 *
2342
 * M = 3 * Xp^2 + a*Zp^4
2343
 * T = Yp^4
2344
 * S = 4 * Xp * Yp^2
2345
 *
2346
 * SPECIAL CASE: when a == 3 we can compute M as
2347
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2348
 */
2349
2350
/**
2351
   Double an ECC point
2352
   P   The point to double
2353
   R   [out] The destination of the double
2354
   a   ECC curve parameter a
2355
   modulus  The modulus of the field the ECC curve is in
2356
   mp       The "b" value from montgomery_setup()
2357
   return   MP_OKAY on success
2358
*/
2359
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2360
                                     mp_int* modulus, mp_digit mp)
2361
986k
{
2362
986k
#if !defined(WOLFSSL_SP_MATH)
2363
986k
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2364
986k
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2365
#ifdef ALT_ECC_SIZE
2366
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2367
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2368
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2369
#endif
2370
986k
   mp_int *x, *y, *z;
2371
986k
   int    err;
2372
2373
986k
#ifdef WOLFSSL_SMALL_STACK
2374
#ifdef WOLFSSL_SMALL_STACK_CACHE
2375
   if (R->key != NULL) {
2376
       t1 = R->key->t1;
2377
       t2 = R->key->t2;
2378
   #ifdef ALT_ECC_SIZE
2379
       rx = R->key->x;
2380
       ry = R->key->y;
2381
       rz = R->key->z;
2382
   #endif
2383
   }
2384
   else
2385
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2386
986k
#endif
2387
986k
   {
2388
986k
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2389
986k
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2390
   #ifdef MP_INT_SIZE_CHECK_NULL
2391
      if (t1 == NULL || t2 == NULL) {
2392
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2393
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2394
         return MEMORY_E;
2395
      }
2396
   #endif
2397
   #ifdef ALT_ECC_SIZE
2398
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2399
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2400
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2401
   #ifdef MP_INT_SIZE_CHECK_NULL
2402
      if (rx == NULL || ry == NULL || rz == NULL) {
2403
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2404
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2405
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2406
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2407
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2408
          return MEMORY_E;
2409
      }
2410
   #endif
2411
   #endif
2412
986k
   }
2413
2414
986k
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2415
986k
   if (err == MP_OKAY) {
2416
986k
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2417
986k
   }
2418
986k
   if (err != MP_OKAY) {
2419
0
#ifdef WOLFSSL_SMALL_STACK
2420
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2421
      if (R->key == NULL)
2422
   #endif
2423
0
#endif
2424
0
      {
2425
      #ifdef ALT_ECC_SIZE
2426
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2427
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2428
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2429
      #endif
2430
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2431
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2432
0
      }
2433
0
      return err;
2434
0
   }
2435
2436
/* If use ALT_ECC_SIZE we need to use local stack variable since
2437
   ecc_point x,y,z is reduced size */
2438
#ifdef ALT_ECC_SIZE
2439
   /* Use local stack variable */
2440
   x = rx;
2441
   y = ry;
2442
   z = rz;
2443
2444
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2445
   if (err == MP_OKAY) {
2446
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2447
   }
2448
   if (err == MP_OKAY) {
2449
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2450
   }
2451
   if (err != MP_OKAY) {
2452
#ifdef WOLFSSL_SMALL_STACK
2453
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2454
      if (R->key == NULL)
2455
   #endif
2456
#endif
2457
      {
2458
      #ifdef ALT_ECC_SIZE
2459
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2460
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2461
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2462
      #endif
2463
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2464
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2465
      }
2466
      return err;
2467
   }
2468
#else
2469
   /* Use destination directly */
2470
986k
   x = R->x;
2471
986k
   y = R->y;
2472
986k
   z = R->z;
2473
986k
#endif
2474
2475
986k
   if (err == MP_OKAY)
2476
986k
       err = mp_copy(P->x, x);
2477
986k
   if (err == MP_OKAY)
2478
986k
       err = mp_copy(P->y, y);
2479
986k
   if (err == MP_OKAY)
2480
986k
       err = mp_copy(P->z, z);
2481
2482
   /* T1 = Z * Z */
2483
986k
   if (err == MP_OKAY)
2484
986k
       err = mp_sqr(z, t1);
2485
986k
   if (err == MP_OKAY)
2486
986k
       err = mp_montgomery_reduce(t1, modulus, mp);
2487
2488
   /* Z = Y * Z */
2489
986k
   if (err == MP_OKAY)
2490
986k
       err = mp_mul(z, y, z);
2491
986k
   if (err == MP_OKAY)
2492
986k
       err = mp_montgomery_reduce(z, modulus, mp);
2493
2494
   /* Z = 2Z */
2495
986k
   if (err == MP_OKAY)
2496
986k
       err = mp_addmod_ct(z, z, modulus, z);
2497
2498
   /* Determine if curve "a" should be used in calc */
2499
986k
#ifdef WOLFSSL_CUSTOM_CURVES
2500
986k
   if (err == MP_OKAY) {
2501
      /* Use a and prime to determine if a == 3 */
2502
986k
      err = mp_submod(modulus, a, modulus, t2);
2503
986k
   }
2504
986k
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2505
      /* T2 = X * X */
2506
134k
      err = mp_sqr(x, t2);
2507
134k
      if (err == MP_OKAY)
2508
134k
          err = mp_montgomery_reduce(t2, modulus, mp);
2509
      /* T1 = T2 + T1 */
2510
134k
      if (err == MP_OKAY)
2511
134k
          err = mp_addmod_ct(t2, t2, modulus, t1);
2512
      /* T1 = T2 + T1 */
2513
134k
      if (err == MP_OKAY)
2514
134k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2515
134k
   }
2516
852k
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2517
      /* use "a" in calc */
2518
2519
      /* T2 = T1 * T1 */
2520
196k
      err = mp_sqr(t1, t2);
2521
196k
      if (err == MP_OKAY)
2522
196k
          err = mp_montgomery_reduce(t2, modulus, mp);
2523
      /* T1 = T2 * a */
2524
196k
      if (err == MP_OKAY)
2525
196k
          err = mp_mulmod(t2, a, modulus, t1);
2526
      /* T2 = X * X */
2527
196k
      if (err == MP_OKAY)
2528
196k
          err = mp_sqr(x, t2);
2529
196k
      if (err == MP_OKAY)
2530
196k
          err = mp_montgomery_reduce(t2, modulus, mp);
2531
      /* T1 = T2 + T1 */
2532
196k
      if (err == MP_OKAY)
2533
196k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2534
      /* T1 = T2 + T1 */
2535
196k
      if (err == MP_OKAY)
2536
196k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2537
      /* T1 = T2 + T1 */
2538
196k
      if (err == MP_OKAY)
2539
196k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2540
196k
   }
2541
655k
   else
2542
655k
#endif /* WOLFSSL_CUSTOM_CURVES */
2543
655k
   {
2544
      /* assumes "a" == 3 */
2545
655k
      (void)a;
2546
2547
      /* T2 = X - T1 */
2548
655k
      if (err == MP_OKAY)
2549
655k
          err = mp_submod_ct(x, t1, modulus, t2);
2550
      /* T1 = X + T1 */
2551
655k
      if (err == MP_OKAY)
2552
655k
          err = mp_addmod_ct(t1, x, modulus, t1);
2553
      /* T2 = T1 * T2 */
2554
655k
      if (err == MP_OKAY)
2555
655k
          err = mp_mul(t1, t2, t2);
2556
655k
      if (err == MP_OKAY)
2557
655k
          err = mp_montgomery_reduce(t2, modulus, mp);
2558
2559
      /* T1 = 2T2 */
2560
655k
      if (err == MP_OKAY)
2561
655k
          err = mp_addmod_ct(t2, t2, modulus, t1);
2562
      /* T1 = T1 + T2 */
2563
655k
      if (err == MP_OKAY)
2564
655k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2565
655k
   }
2566
2567
   /* Y = 2Y */
2568
986k
   if (err == MP_OKAY)
2569
986k
       err = mp_addmod_ct(y, y, modulus, y);
2570
   /* Y = Y * Y */
2571
986k
   if (err == MP_OKAY)
2572
986k
       err = mp_sqr(y, y);
2573
986k
   if (err == MP_OKAY)
2574
986k
       err = mp_montgomery_reduce(y, modulus, mp);
2575
2576
   /* T2 = Y * Y */
2577
986k
   if (err == MP_OKAY)
2578
986k
       err = mp_sqr(y, t2);
2579
986k
   if (err == MP_OKAY)
2580
986k
       err = mp_montgomery_reduce(t2, modulus, mp);
2581
2582
   /* T2 = T2/2 */
2583
986k
   if (err == MP_OKAY)
2584
986k
       err = mp_div_2_mod_ct(t2, modulus, t2);
2585
2586
   /* Y = Y * X */
2587
986k
   if (err == MP_OKAY)
2588
986k
       err = mp_mul(y, x, y);
2589
986k
   if (err == MP_OKAY)
2590
986k
       err = mp_montgomery_reduce(y, modulus, mp);
2591
2592
   /* X = T1 * T1 */
2593
986k
   if (err == MP_OKAY)
2594
986k
       err = mp_sqr(t1, x);
2595
986k
   if (err == MP_OKAY)
2596
986k
       err = mp_montgomery_reduce(x, modulus, mp);
2597
2598
   /* X = X - Y */
2599
986k
   if (err == MP_OKAY)
2600
986k
       err = mp_submod_ct(x, y, modulus, x);
2601
   /* X = X - Y */
2602
986k
   if (err == MP_OKAY)
2603
986k
       err = mp_submod_ct(x, y, modulus, x);
2604
2605
   /* Y = Y - X */
2606
986k
   if (err == MP_OKAY)
2607
986k
       err = mp_submod_ct(y, x, modulus, y);
2608
   /* Y = Y * T1 */
2609
986k
   if (err == MP_OKAY)
2610
986k
       err = mp_mul(y, t1, y);
2611
986k
   if (err == MP_OKAY)
2612
986k
       err = mp_montgomery_reduce(y, modulus, mp);
2613
2614
   /* Y = Y - T2 */
2615
986k
   if (err == MP_OKAY)
2616
986k
       err = mp_submod_ct(y, t2, modulus, y);
2617
2618
#ifdef ALT_ECC_SIZE
2619
   if (err == MP_OKAY)
2620
       err = mp_copy(x, R->x);
2621
   if (err == MP_OKAY)
2622
       err = mp_copy(y, R->y);
2623
   if (err == MP_OKAY)
2624
       err = mp_copy(z, R->z);
2625
#endif
2626
2627
   /* clean up */
2628
986k
   mp_clear(t1);
2629
986k
   mp_clear(t2);
2630
2631
986k
#ifdef WOLFSSL_SMALL_STACK
2632
#ifdef WOLFSSL_SMALL_STACK_CACHE
2633
   if (R->key == NULL)
2634
#endif
2635
986k
#endif
2636
986k
   {
2637
    #ifdef ALT_ECC_SIZE
2638
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2639
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2640
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2641
    #endif
2642
986k
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2643
986k
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2644
986k
    }
2645
2646
986k
   return err;
2647
#else
2648
    int modBits = mp_count_bits(modulus);
2649
2650
    (void)a;
2651
    (void)mp;
2652
2653
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2654
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2655
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2656
    }
2657
#endif
2658
#ifndef WOLFSSL_SP_NO_256
2659
    if (modBits == 256) {
2660
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2661
    }
2662
#endif
2663
#ifdef WOLFSSL_SP_384
2664
    if (modBits == 384) {
2665
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2666
    }
2667
#endif
2668
#ifdef WOLFSSL_SP_521
2669
    if (modBits == 521) {
2670
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2671
    }
2672
#endif
2673
    return ECC_BAD_ARG_E;
2674
#endif
2675
986k
}
2676
2677
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2678
                             mp_int* modulus, mp_digit mp)
2679
3.04k
{
2680
3.04k
    if (P == NULL || R == NULL || modulus == NULL)
2681
0
        return ECC_BAD_ARG_E;
2682
2683
3.04k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2684
3.02k
        mp_cmp(P->y, modulus) != MP_LT ||
2685
2.99k
        mp_cmp(P->z, modulus) != MP_LT) {
2686
43
        return ECC_OUT_OF_RANGE_E;
2687
43
    }
2688
2689
2.99k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2690
3.04k
}
2691
2692
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2693
    !defined(WOLFSSL_CRYPTOCELL)
2694
2695
2696
/**
2697
  Map a projective Jacobian point back to affine space
2698
  P        [in/out] The point to map
2699
  modulus  The modulus of the field the ECC curve is in
2700
  mp       The "b" value from montgomery_setup()
2701
  ct       Operation should be constant time.
2702
  return   MP_OKAY on success
2703
*/
2704
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2705
4.56k
{
2706
4.56k
   int err = MP_OKAY;
2707
4.56k
#if !defined(WOLFSSL_SP_MATH)
2708
4.56k
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2709
4.56k
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2710
#ifdef ALT_ECC_SIZE
2711
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2712
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2713
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2714
#endif
2715
4.56k
   mp_int *x, *y, *z;
2716
2717
4.56k
   (void)ct;
2718
2719
4.56k
   if (P == NULL || modulus == NULL)
2720
0
       return ECC_BAD_ARG_E;
2721
2722
   /* special case for point at infinity */
2723
4.56k
   if (mp_cmp_d(P->z, 0) == MP_EQ) {
2724
159
       err = mp_set(P->x, 0);
2725
159
       if (err == MP_OKAY)
2726
159
           err = mp_set(P->y, 0);
2727
159
       if (err == MP_OKAY)
2728
159
           err = mp_set(P->z, 1);
2729
159
       return err;
2730
159
   }
2731
2732
4.40k
#ifdef WOLFSSL_SMALL_STACK
2733
#ifdef WOLFSSL_SMALL_STACK_CACHE
2734
   if (P->key != NULL) {
2735
       t1 = P->key->t1;
2736
       t2 = P->key->t2;
2737
   #ifdef ALT_ECC_SIZE
2738
       rx = P->key->x;
2739
       ry = P->key->y;
2740
       rz = P->key->z;
2741
   #endif
2742
   }
2743
   else
2744
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2745
4.40k
#endif
2746
4.40k
   {
2747
4.40k
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2748
4.40k
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2749
   #ifdef MP_INT_SIZE_CHECK_NULL
2750
      if (t1 == NULL || t2 == NULL) {
2751
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2752
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2753
         return MEMORY_E;
2754
      }
2755
   #endif
2756
   #ifdef ALT_ECC_SIZE
2757
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2758
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2759
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2760
   #ifdef MP_INT_SIZE_CHECK_NULL
2761
      if (rx == NULL || ry == NULL || rz == NULL) {
2762
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2763
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2764
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2765
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2766
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2767
          return MEMORY_E;
2768
      }
2769
   #endif
2770
   #endif
2771
4.40k
   }
2772
2773
4.40k
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2774
4.40k
   if (err == MP_OKAY) {
2775
4.40k
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2776
4.40k
   }
2777
4.40k
   if (err != MP_OKAY) {
2778
0
#ifdef WOLFSSL_SMALL_STACK
2779
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2780
      if (P->key == NULL)
2781
   #endif
2782
0
#endif
2783
0
      {
2784
      #ifdef ALT_ECC_SIZE
2785
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2786
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2787
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2788
      #endif
2789
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2790
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2791
0
      }
2792
0
      return MEMORY_E;
2793
0
   }
2794
2795
#ifdef ALT_ECC_SIZE
2796
   /* Use local stack variable */
2797
   x = rx;
2798
   y = ry;
2799
   z = rz;
2800
2801
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2802
   if (err == MP_OKAY) {
2803
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2804
   }
2805
   if (err == MP_OKAY) {
2806
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2807
   }
2808
   if (err != MP_OKAY) {
2809
      goto done;
2810
   }
2811
2812
   if (err == MP_OKAY)
2813
      err = mp_copy(P->x, x);
2814
   if (err == MP_OKAY)
2815
      err = mp_copy(P->y, y);
2816
   if (err == MP_OKAY)
2817
      err = mp_copy(P->z, z);
2818
2819
   if (err != MP_OKAY) {
2820
      goto done;
2821
   }
2822
#else
2823
   /* Use destination directly */
2824
4.40k
   x = P->x;
2825
4.40k
   y = P->y;
2826
4.40k
   z = P->z;
2827
4.40k
#endif
2828
2829
   /* get 1/z */
2830
4.40k
   if (err == MP_OKAY) {
2831
#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2832
                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2833
       if (ct) {
2834
           err = mp_invmod_mont_ct(z, modulus, t1, mp);
2835
           if (err == MP_OKAY)
2836
               err = mp_montgomery_reduce(t1, modulus, mp);
2837
       }
2838
       else
2839
#endif
2840
4.40k
       {
2841
           /* first map z back to normal */
2842
4.40k
           err = mp_montgomery_reduce(z, modulus, mp);
2843
4.40k
           if (err == MP_OKAY)
2844
4.40k
               err = mp_invmod(z, modulus, t1);
2845
4.40k
       }
2846
4.40k
   }
2847
2848
   /* get 1/z^2 and 1/z^3 */
2849
4.40k
   if (err == MP_OKAY)
2850
4.39k
       err = mp_sqr(t1, t2);
2851
4.40k
   if (err == MP_OKAY)
2852
4.39k
       err = mp_mod(t2, modulus, t2);
2853
4.40k
   if (err == MP_OKAY)
2854
4.39k
       err = mp_mul(t1, t2, t1);
2855
4.40k
   if (err == MP_OKAY)
2856
4.39k
       err = mp_mod(t1, modulus, t1);
2857
2858
   /* multiply against x/y */
2859
4.40k
   if (err == MP_OKAY)
2860
4.39k
       err = mp_mul(x, t2, x);
2861
4.40k
   if (err == MP_OKAY)
2862
4.39k
       err = mp_montgomery_reduce(x, modulus, mp);
2863
4.40k
   if (err == MP_OKAY)
2864
4.39k
       err = mp_mul(y, t1, y);
2865
4.40k
   if (err == MP_OKAY)
2866
4.39k
       err = mp_montgomery_reduce(y, modulus, mp);
2867
2868
4.40k
   if (err == MP_OKAY)
2869
4.39k
       err = mp_set(z, 1);
2870
2871
#ifdef ALT_ECC_SIZE
2872
   /* return result */
2873
   if (err == MP_OKAY)
2874
      err = mp_copy(x, P->x);
2875
   if (err == MP_OKAY)
2876
      err = mp_copy(y, P->y);
2877
   if (err == MP_OKAY)
2878
      err = mp_copy(z, P->z);
2879
2880
done:
2881
#endif
2882
2883
   /* clean up */
2884
4.40k
   mp_clear(t1);
2885
4.40k
   mp_clear(t2);
2886
2887
4.40k
#ifdef WOLFSSL_SMALL_STACK
2888
#ifdef WOLFSSL_SMALL_STACK_CACHE
2889
   if (P->key == NULL)
2890
#endif
2891
4.40k
#endif
2892
4.40k
   {
2893
   #ifdef ALT_ECC_SIZE
2894
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2895
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2896
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2897
   #endif
2898
4.40k
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2899
4.40k
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2900
4.40k
   }
2901
2902
4.40k
   return err;
2903
   /* end !defined(WOLFSSL_SP_MATH) */
2904
2905
#else
2906
   /* begin defined(WOLFSSL_SP_MATH) */
2907
   if (P == NULL || modulus == NULL)
2908
       return ECC_BAD_ARG_E;
2909
2910
   (void)mp;
2911
   (void)ct;
2912
2913
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2914
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
2915
       err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
2916
   }
2917
#elif !defined(WOLFSSL_SP_NO_256)
2918
   if (mp_count_bits(modulus) == 256) {
2919
       err = sp_ecc_map_256(P->x, P->y, P->z);
2920
   }
2921
#elif defined(WOLFSSL_SP_384)
2922
   if (mp_count_bits(modulus) == 384) {
2923
       err = sp_ecc_map_384(P->x, P->y, P->z);
2924
   }
2925
#elif defined(WOLFSSL_SP_521)
2926
   if (mp_count_bits(modulus) == 521) {
2927
       err = sp_ecc_map_521(P->x, P->y, P->z);
2928
   }
2929
#else
2930
   err = ECC_BAD_ARG_E;
2931
#endif
2932
2933
   WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
2934
   return err;
2935
#endif /* WOLFSSL_SP_MATH */
2936
4.40k
}
2937
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
2938
2939
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
2940
18.5k
{
2941
18.5k
    return ecc_map_ex(P, modulus, mp, 0);
2942
18.5k
}
2943
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
2944
2945
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
2946
    !defined(WOLFSSL_CRYPTOCELL)
2947
#if !defined(WOLFSSL_SP_MATH)
2948
2949
#ifndef ECC_TIMING_RESISTANT
2950
2951
/* size of sliding window, don't change this! */
2952
#define WINSIZE  4
2953
#define M_POINTS 8
2954
2955
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
2956
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
2957
{
2958
   int      err = MP_OKAY;
2959
   int      i;
2960
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
2961
   int      bitcnt = 0, mode = 0, digidx = 0;
2962
   mp_digit buf;
2963
   int      infinity;
2964
2965
   (void)rng;
2966
2967
   /* calc the M tab, which holds kG for k==8..15 */
2968
   /* M[0] == 8G */
2969
   if (err == MP_OKAY)
2970
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
2971
   if (err == MP_OKAY)
2972
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2973
   if (err == MP_OKAY)
2974
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
2975
2976
   /* now find (8+k)G for k=1..7 */
2977
   if (err == MP_OKAY)
2978
       for (j = 9; j < 16; j++) {
2979
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
2980
                                                        modulus, mp, &infinity);
2981
           if (err != MP_OKAY) break;
2982
       }
2983
2984
   /* setup sliding window */
2985
   if (err == MP_OKAY) {
2986
       mode   = 0;
2987
       bitcnt = 1;
2988
       buf    = 0;
2989
       digidx = mp_get_digit_count(k) - 1;
2990
       bitcpy = bitbuf = 0;
2991
       first  = 1;
2992
2993
       /* perform ops */
2994
       for (;;) {
2995
           /* grab next digit as required */
2996
           if (--bitcnt == 0) {
2997
               if (digidx == -1) {
2998
                   break;
2999
               }
3000
               buf    = mp_get_digit(k, digidx);
3001
               bitcnt = (int) DIGIT_BIT;
3002
               --digidx;
3003
           }
3004
3005
           /* grab the next msb from the ltiplicand */
3006
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3007
           buf <<= 1;
3008
3009
           /* skip leading zero bits */
3010
           if (mode == 0 && i == 0)
3011
               continue;
3012
3013
           /* if the bit is zero and mode == 1 then we double */
3014
           if (mode == 1 && i == 0) {
3015
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3016
               if (err != MP_OKAY) break;
3017
               continue;
3018
           }
3019
3020
           /* else we add it to the window */
3021
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3022
           mode = 2;
3023
3024
           if (bitcpy == WINSIZE) {
3025
               /* if this is the first window we do a simple copy */
3026
               if (first == 1) {
3027
                   /* R = kG [k = first window] */
3028
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3029
                   if (err != MP_OKAY) break;
3030
3031
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3032
                   if (err != MP_OKAY) break;
3033
3034
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3035
                   first = 0;
3036
               } else {
3037
                   /* normal window */
3038
                   /* ok window is filled so double as required and add  */
3039
                   /* double first */
3040
                   for (j = 0; j < WINSIZE; j++) {
3041
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3042
                                                                            mp);
3043
                       if (err != MP_OKAY) break;
3044
                   }
3045
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3046
3047
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3048
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3049
                                                     a, modulus, mp, &infinity);
3050
               }
3051
               if (err != MP_OKAY) break;
3052
               /* empty window and reset */
3053
               bitcpy = bitbuf = 0;
3054
               mode = 1;
3055
           }
3056
       }
3057
   }
3058
3059
   /* if bits remain then double/add */
3060
   if (err == MP_OKAY) {
3061
       if (mode == 2 && bitcpy > 0) {
3062
           /* double then add */
3063
           for (j = 0; j < bitcpy; j++) {
3064
               /* only double if we have had at least one add first */
3065
               if (first == 0) {
3066
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3067
                   if (err != MP_OKAY) break;
3068
               }
3069
3070
               bitbuf <<= 1;
3071
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3072
                   if (first == 1) {
3073
                       /* first add, so copy */
3074
                       err = mp_copy(tG->x, R->x);
3075
                       if (err != MP_OKAY) break;
3076
3077
                       err = mp_copy(tG->y, R->y);
3078
                       if (err != MP_OKAY) break;
3079
3080
                       err = mp_copy(tG->z, R->z);
3081
                       if (err != MP_OKAY) break;
3082
                       first = 0;
3083
                   } else {
3084
                       /* then add */
3085
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3086
                                                                 mp, &infinity);
3087
                       if (err != MP_OKAY) break;
3088
                   }
3089
               }
3090
           }
3091
       }
3092
   }
3093
3094
   #undef WINSIZE
3095
3096
   return err;
3097
}
3098
3099
#else
3100
3101
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3102
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3103
34.1k
{
3104
34.1k
    int err = MP_OKAY;
3105
3106
34.1k
    err = mp_montgomery_calc_normalization(mu, modulus);
3107
    /* Generate random value to multiply into p->z. */
3108
34.1k
    if (err == MP_OKAY)
3109
34.1k
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3110
    /* Convert to montogmery form. */
3111
34.1k
    if (err == MP_OKAY)
3112
33.9k
        err = mp_mulmod(ty, mu, modulus, ty);
3113
    /* Multiply random value into p->z. */
3114
34.1k
    if (err == MP_OKAY)
3115
33.8k
        err = mp_mul(p->z, ty, p->z);
3116
34.1k
    if (err == MP_OKAY)
3117
33.8k
        err = mp_montgomery_reduce(p->z, modulus, mp);
3118
    /* Square random value for X (X' = X / Z^2). */
3119
34.1k
    if (err == MP_OKAY)
3120
33.8k
        err = mp_sqr(ty, tx);
3121
34.1k
    if (err == MP_OKAY)
3122
33.8k
        err = mp_montgomery_reduce(tx, modulus, mp);
3123
    /* Multiply square of random by random value for Y. */
3124
34.1k
    if (err == MP_OKAY)
3125
33.8k
        err = mp_mul(ty, tx, ty);
3126
34.1k
    if (err == MP_OKAY)
3127
33.8k
        err = mp_montgomery_reduce(ty, modulus, mp);
3128
    /* Multiply square into X. */
3129
34.1k
    if (err == MP_OKAY)
3130
33.8k
        err = mp_mul(p->x, tx, p->x);
3131
34.1k
    if (err == MP_OKAY)
3132
33.8k
        err = mp_montgomery_reduce(p->x, modulus, mp);
3133
    /* Multiply cube into Y (Y' = Y / Z^3). */
3134
34.1k
    if (err == MP_OKAY)
3135
33.8k
        err = mp_mul(p->y, ty, p->y);
3136
34.1k
    if (err == MP_OKAY)
3137
33.7k
        err = mp_montgomery_reduce(p->y, modulus, mp);
3138
3139
34.1k
    return err;
3140
34.1k
}
3141
3142
#ifndef WC_PROTECT_ENCRYPTED_MEM
3143
178k
#define M_POINTS 3
3144
3145
/* Joye double-add ladder.
3146
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3147
 * by Marc Joye (2007)
3148
 *
3149
 * Algorithm 1':
3150
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3151
 *   Output: Q = kP
3152
 *   1: R[0] = P; R[1] = P
3153
 *   2: for j = 1 to t-1 do
3154
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3155
 *   4: end for
3156
 *   5: b = k[0]; R[b] = R[b] - P
3157
 *   6: return R[0]
3158
 *
3159
 * Assumes: k < order.
3160
 */
3161
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3162
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3163
30.7k
{
3164
30.7k
    int      err = MP_OKAY;
3165
30.7k
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3166
30.7k
    int      i;
3167
30.7k
    int      j = 1;
3168
30.7k
    int      cnt = DIGIT_BIT;
3169
30.7k
    int      t = 0;
3170
30.7k
    mp_digit b;
3171
30.7k
    mp_digit v = 0;
3172
30.7k
    mp_int*  kt = R[2]->x;
3173
30.7k
#ifndef WC_NO_CACHE_RESISTANT
3174
    /* First bit always 1 (fix at end) and swap equals first bit */
3175
30.7k
    int      swap = 1;
3176
30.7k
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3177
30.7k
#endif
3178
30.7k
    int      infinity;
3179
3180
30.7k
#ifndef WC_NO_CACHE_RESISTANT
3181
30.7k
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3182
30.7k
    if (err == MP_OKAY)
3183
30.6k
        err = mp_init(tmp);
3184
30.7k
#endif
3185
3186
    /* Step 1: R[0] = P; R[1] = P */
3187
    /* R[0] = P */
3188
30.7k
    if (err == MP_OKAY)
3189
30.6k
        err = mp_copy(P->x, R[0]->x);
3190
30.7k
    if (err == MP_OKAY)
3191
30.6k
        err = mp_copy(P->y, R[0]->y);
3192
30.7k
    if (err == MP_OKAY)
3193
30.6k
        err = mp_copy(P->z, R[0]->z);
3194
3195
    /* R[1] = P */
3196
30.7k
    if (err == MP_OKAY)
3197
30.6k
        err = mp_copy(P->x, R[1]->x);
3198
30.7k
    if (err == MP_OKAY)
3199
30.6k
        err = mp_copy(P->y, R[1]->y);
3200
30.7k
    if (err == MP_OKAY)
3201
30.6k
        err = mp_copy(P->z, R[1]->z);
3202
3203
    /* Randomize z ordinates to obfuscate timing. */
3204
30.7k
    if ((err == MP_OKAY) && (rng != NULL))
3205
15.4k
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3206
30.7k
    if ((err == MP_OKAY) && (rng != NULL))
3207
15.2k
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3208
3209
30.7k
    if (err == MP_OKAY) {
3210
        /* Order could be one greater than the size of the modulus. */
3211
30.3k
        t = mp_count_bits(modulus) + 1;
3212
30.3k
        v = k->dp[0] >> 1;
3213
30.3k
        if (cnt > t) {
3214
0
            cnt = t;
3215
0
        }
3216
30.3k
        err = mp_copy(k, kt);
3217
30.3k
    }
3218
30.7k
    if (err == MP_OKAY) {
3219
30.3k
        err = mp_grow(kt, (int)modulus->used + 1);
3220
30.3k
    }
3221
    /* Step 2: for j = 1 to t-1 do */
3222
7.84M
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3223
7.81M
        if (--cnt == 0) {
3224
192k
            v = kt->dp[j++];
3225
192k
            cnt = DIGIT_BIT;
3226
192k
        }
3227
3228
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3229
7.81M
        b = v & 1;
3230
7.81M
        v >>= 1;
3231
#ifdef WC_NO_CACHE_RESISTANT
3232
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3233
        if (err == MP_OKAY) {
3234
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3235
                                                        modulus, mp, &infinity);
3236
        }
3237
#else
3238
        /* Swap R[0] and R[1] if other index is needed. */
3239
7.81M
        swap ^= (int)b;
3240
7.81M
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3241
7.81M
            tmp);
3242
7.81M
        if (err == MP_OKAY) {
3243
7.81M
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3244
7.81M
                tmp);
3245
7.81M
        }
3246
7.81M
        if (err == MP_OKAY) {
3247
7.81M
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3248
7.81M
                tmp);
3249
7.81M
        }
3250
7.81M
        swap = (int)b;
3251
3252
7.81M
        if (err == MP_OKAY)
3253
7.81M
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3254
7.81M
        if (err == MP_OKAY) {
3255
7.81M
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3256
7.81M
                                                                 mp, &infinity);
3257
7.81M
        }
3258
7.81M
#endif /* WC_NO_CACHE_RESISTANT */
3259
7.81M
    }
3260
    /* Step 4: end for */
3261
30.7k
#ifndef WC_NO_CACHE_RESISTANT
3262
    /* Swap back if last bit is 0. */
3263
30.7k
    swap ^= 1;
3264
30.7k
    if (err == MP_OKAY) {
3265
28.9k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3266
28.9k
            tmp);
3267
28.9k
    }
3268
30.7k
    if (err == MP_OKAY) {
3269
28.9k
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3270
28.9k
            tmp);
3271
28.9k
    }
3272
30.7k
    if (err == MP_OKAY) {
3273
28.9k
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3274
28.9k
            tmp);
3275
28.9k
    }
3276
30.7k
#endif
3277
3278
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3279
    /* R[2] = -P */
3280
30.7k
    if (err == MP_OKAY)
3281
28.9k
        err = mp_copy(P->x, R[2]->x);
3282
30.7k
    if (err == MP_OKAY)
3283
28.9k
        err = mp_sub(modulus, P->y, R[2]->y);
3284
30.7k
    if (err == MP_OKAY)
3285
28.9k
        err = mp_copy(P->z, R[2]->z);
3286
    /* Subtract point by adding negative. */
3287
30.7k
    if (err == MP_OKAY) {
3288
28.9k
        b = k->dp[0] & 1;
3289
#ifdef WC_NO_CACHE_RESISTANT
3290
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3291
                                                                     &infinity);
3292
#else
3293
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3294
28.9k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3295
28.9k
            tmp);
3296
28.9k
        if (err == MP_OKAY) {
3297
28.9k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3298
28.9k
                (int)b, tmp);
3299
28.9k
        }
3300
28.9k
        if (err == MP_OKAY) {
3301
28.9k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3302
28.9k
                (int)b, tmp);
3303
28.9k
        }
3304
28.9k
        if (err == MP_OKAY)
3305
28.9k
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3306
28.9k
                                                                 mp, &infinity);
3307
        /* Swap back if necessary. */
3308
28.9k
        if (err == MP_OKAY) {
3309
28.8k
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3310
28.8k
                (int)b, tmp);
3311
28.8k
        }
3312
28.9k
        if (err == MP_OKAY) {
3313
28.8k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3314
28.8k
                (int)b, tmp);
3315
28.8k
        }
3316
28.9k
        if (err == MP_OKAY) {
3317
28.8k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3318
28.8k
                (int)b, tmp);
3319
28.8k
        }
3320
28.9k
#endif
3321
28.9k
    }
3322
3323
    /* Step 6: return R[0] */
3324
30.7k
    if (err == MP_OKAY)
3325
28.8k
        err = mp_copy(R[0]->x, Q->x);
3326
30.7k
    if (err == MP_OKAY)
3327
28.8k
        err = mp_copy(R[0]->y, Q->y);
3328
30.7k
    if (err == MP_OKAY)
3329
28.8k
        err = mp_copy(R[0]->z, Q->z);
3330
3331
30.7k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3332
30.7k
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3333
30.7k
#endif
3334
3335
30.7k
    return err;
3336
30.7k
}
3337
3338
#else
3339
/* Number of points to allocate for use during scalar multiplication. */
3340
#define M_POINTS        5
3341
/* Last of the points is used as a temporary during calculations. */
3342
#define TMP_IDX         M_POINTS - 1
3343
3344
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3345
    int digits, int m)
3346
{
3347
    int i;
3348
3349
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3350
    /* Only using positive numbers in ECC operations. */
3351
    ra->sign = 0;
3352
    rb->sign = 0;
3353
#endif
3354
    /* Don't store 0 when mask is 0, it will be in a register. */
3355
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3356
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3357
    for (i = 0; i < digits; i++) {
3358
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3359
                    a->dp[i];
3360
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3361
                    b->dp[i];
3362
    }
3363
}
3364
3365
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3366
    ecc_point* b, int digits, int m)
3367
{
3368
    /* Conditionally swap each ordinate. */
3369
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3370
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3371
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3372
}
3373
3374
/* Joye double-add ladder.
3375
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3376
 * by Marc Joye (2007)
3377
 *
3378
 * Algorithm 1':
3379
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3380
 *   Output: Q = kP
3381
 *   1: R[0] = P; R[1] = P
3382
 *   2: for j = 1 to t-1 do
3383
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3384
 *   4: end for
3385
 *   5: b = k[0]; R[b] = R[b] - P
3386
 *   6: return R[0]
3387
 *
3388
 * Assumes: k < order.
3389
 */
3390
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3391
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3392
{
3393
    int          err = MP_OKAY;
3394
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3395
    int          i;
3396
    int          j = 1;
3397
    int          cnt;
3398
    int          t = 0;
3399
    mp_int*      kt = R[TMP_IDX]->x;
3400
    /* First bit always 1 (fix at end) and swap equals first bit */
3401
    register int swap = 1;
3402
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3403
    int          set = 0;
3404
    int          infinity;
3405
3406
    /* Step 1: R[0] = P; R[1] = P */
3407
    /* R[0] = P */
3408
    if (err == MP_OKAY)
3409
        err = mp_copy(P->x, R[0]->x);
3410
    if (err == MP_OKAY)
3411
        err = mp_copy(P->y, R[0]->y);
3412
    if (err == MP_OKAY)
3413
        err = mp_copy(P->z, R[0]->z);
3414
3415
    /* R[1] = P */
3416
    if (err == MP_OKAY)
3417
        err = mp_copy(P->x, R[1]->x);
3418
    if (err == MP_OKAY)
3419
        err = mp_copy(P->y, R[1]->y);
3420
    if (err == MP_OKAY)
3421
        err = mp_copy(P->z, R[1]->z);
3422
3423
    /* Randomize z ordinates to obfuscate timing. */
3424
    if ((err == MP_OKAY) && (rng != NULL))
3425
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3426
                           R[TMP_IDX]->y, kt);
3427
    if ((err == MP_OKAY) && (rng != NULL))
3428
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3429
                           R[TMP_IDX]->y, kt);
3430
3431
    if (err == MP_OKAY) {
3432
        /* Order could be one greater than the size of the modulus. */
3433
        t = mp_count_bits(modulus) + 1;
3434
        err = mp_copy(k, kt);
3435
    }
3436
    if (err == MP_OKAY) {
3437
        err = mp_grow(kt, modulus->used + 1);
3438
    }
3439
    /* Step 2: for j = 1 to t-1 do */
3440
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3441
        if (++cnt == DIGIT_BIT) {
3442
            j++;
3443
            cnt = 0;
3444
        }
3445
3446
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3447
        /* Swap R[0] and R[1] if other index is needed. */
3448
        /* Ensure 'swap' changes when shifted word is 0. */
3449
        swap += (kt->dp[j] >> cnt) + 2;
3450
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3451
                              R[set + 0], R[set + 1], modulus->used, swap);
3452
        /* Change to operate on set copied into. */
3453
        set = 2 - set;
3454
        /* Ensure 'swap' changes to a previously unseen value. */
3455
        swap += (kt->dp[j] >> cnt) + swap;
3456
3457
        /* R[0] = 2*R[0] */
3458
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3459
                                            mp);
3460
        if (err == MP_OKAY) {
3461
            /* R[0] = R[1] + R[0] */
3462
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3463
                                         R[set + 0], a, modulus, mp, &infinity);
3464
        }
3465
        /*  R[1]->z * 2 - same point. */
3466
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3467
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3468
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3469
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3470
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3471
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3472
    }
3473
    /* Step 4: end for */
3474
    /* Swap back if last bit is 0. */
3475
    /* Ensure 'swap' changes. */
3476
    swap += 1;
3477
    if (err == MP_OKAY) {
3478
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3479
                              R[set + 0], R[set + 1], modulus->used, swap);
3480
        set = 2 - set;
3481
    }
3482
3483
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3484
    /* R[TMP_IDX] = -P */
3485
    if (err == MP_OKAY)
3486
        err = mp_copy(P->x, R[TMP_IDX]->x);
3487
    if (err == MP_OKAY)
3488
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3489
    if (err == MP_OKAY)
3490
        err = mp_copy(P->z, R[TMP_IDX]->z);
3491
    /* Subtract point by adding negative. */
3492
    if (err == MP_OKAY) {
3493
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3494
         * Last bit of k->dp[0] is being used to make decision to swap.
3495
         */
3496
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3497
                              R[set + 0], R[set + 1], modulus->used,
3498
                              (int)k->dp[0]);
3499
        set = 2 - set;
3500
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3501
                                            a, modulus, mp, &infinity);
3502
        /* Swap back if necessary. */
3503
        if (err == MP_OKAY) {
3504
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3505
                                  R[set + 0], R[set + 1], modulus->used,
3506
                                  (int)k->dp[0]);
3507
            set = 2 - set;
3508
        }
3509
    }
3510
3511
    /* Step 6: return R[0] */
3512
    if (err == MP_OKAY)
3513
        err = mp_copy(R[set + 0]->x, Q->x);
3514
    if (err == MP_OKAY)
3515
        err = mp_copy(R[set + 0]->y, Q->y);
3516
    if (err == MP_OKAY)
3517
        err = mp_copy(R[set + 0]->z, Q->z);
3518
3519
    return err;
3520
}
3521
3522
#endif
3523
3524
#endif
3525
3526
/* Convert the point to montgomery form.
3527
 *
3528
 * @param  [in]   p        Point to convert.
3529
 * @param  [out]  r        Point in montgomery form.
3530
 * @param  [in]   modulus  Modulus of ordinates.
3531
 * @return  0 on success.
3532
 * @return  -ve on failure.
3533
 */
3534
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3535
                             void* heap)
3536
3.39k
{
3537
3.39k
   int err = MP_OKAY;
3538
3.39k
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3539
3540
3.39k
   (void)heap;
3541
3542
3.39k
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3543
#ifdef MP_INT_SIZE_CHECK_NULL
3544
   if (mu == NULL)
3545
       err = MEMORY_E;
3546
#endif
3547
3.39k
   if (err == MP_OKAY)
3548
3.39k
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3549
3.39k
   if (err == MP_OKAY) {
3550
3.39k
       err = mp_montgomery_calc_normalization(mu, modulus);
3551
3552
3.39k
       if (err == MP_OKAY) {
3553
3.38k
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3554
0
               err = mp_copy(p->x, r->x);
3555
0
               if (err == MP_OKAY)
3556
0
                   err = mp_copy(p->y, r->y);
3557
0
               if (err == MP_OKAY)
3558
0
                   err = mp_copy(p->z, r->z);
3559
0
           }
3560
3.38k
           else {
3561
3.38k
               err = mp_mulmod(p->x, mu, modulus, r->x);
3562
3.38k
               if (err == MP_OKAY)
3563
3.38k
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3564
3.38k
               if (err == MP_OKAY)
3565
3.37k
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3566
3.38k
           }
3567
3.38k
       }
3568
3569
3.39k
       mp_clear(mu);
3570
3.39k
   }
3571
3572
3.39k
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3573
3.39k
   return err;
3574
3.39k
}
3575
3576
#ifdef WOLFSSL_SMALL_STACK_CACHE
3577
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3578
{
3579
   int err = MP_OKAY;
3580
3581
   (void)heap;
3582
3583
   if (key == NULL) {
3584
       return ECC_BAD_ARG_E;
3585
   }
3586
3587
   XMEMSET(key, 0, sizeof(*key));
3588
3589
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3590
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3591
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3592
#ifdef ALT_ECC_SIZE
3593
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3594
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3595
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3596
#endif
3597
   if (key->t1 == NULL || key->t2 == NULL
3598
#ifdef ALT_ECC_SIZE
3599
      || key->x == NULL || key->y == NULL || key->z == NULL
3600
#endif
3601
   ) {
3602
       err = MEMORY_E;
3603
   }
3604
   if (err == 0) {
3605
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3606
   }
3607
   if (err == 0) {
3608
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3609
   }
3610
#ifdef ALT_ECC_SIZE
3611
   if (err == 0) {
3612
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3613
   }
3614
   if (err == 0) {
3615
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3616
   }
3617
   if (err == 0) {
3618
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3619
   }
3620
#endif
3621
#else
3622
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3623
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3624
#ifdef ALT_ECC_SIZE
3625
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3626
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3627
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3628
#endif
3629
   if (key->t1 == NULL || key->t2 == NULL
3630
#ifdef ALT_ECC_SIZE
3631
      || key->x == NULL || key->y == NULL || key->z == NULL
3632
#endif
3633
   ) {
3634
       err = MEMORY_E;
3635
   }
3636
#endif
3637
3638
   return err;
3639
}
3640
3641
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3642
{
3643
    (void)heap;
3644
3645
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3646
#ifdef ALT_ECC_SIZE
3647
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3648
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3649
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3650
#endif
3651
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3652
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3653
#else
3654
#ifdef ALT_ECC_SIZE
3655
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3656
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3657
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3658
#endif
3659
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3660
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3661
#endif
3662
}
3663
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3664
#endif /* !WOLFSSL_SP_MATH */
3665
3666
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3667
/**
3668
   Perform a point multiplication
3669
   k    The scalar to multiply by
3670
   G    The base point
3671
   R    [out] Destination for kG
3672
   a    ECC curve parameter a
3673
   modulus  The modulus of the field the ECC curve is in
3674
   map      Boolean whether to map back to affine or not
3675
                (1==map, 0 == leave in projective)
3676
   return MP_OKAY on success
3677
*/
3678
#ifdef FP_ECC
3679
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3680
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3681
                             void* heap)
3682
#else
3683
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3684
                     mp_int* modulus, int map, void* heap)
3685
#endif
3686
#if !defined(WOLFSSL_SP_MATH)
3687
10.1k
{
3688
10.1k
   ecc_point     *tG, *M[M_POINTS];
3689
#ifdef WOLFSSL_NO_MALLOC
3690
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3691
#endif
3692
10.1k
   int           i, err;
3693
#ifdef WOLFSSL_SMALL_STACK_CACHE
3694
   ecc_key       *key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3695
#endif
3696
10.1k
   mp_digit      mp;
3697
3698
   /* init variables */
3699
10.1k
   tG = NULL;
3700
10.1k
   XMEMSET(M, 0, sizeof(M));
3701
3702
10.1k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3703
0
       err = ECC_BAD_ARG_E;
3704
0
       goto exit;
3705
0
   }
3706
3707
   /* k can't have more bits than modulus count plus 1 */
3708
10.1k
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3709
256
       err = ECC_OUT_OF_RANGE_E;
3710
256
       goto exit;
3711
256
   }
3712
3713
#ifdef WOLFSSL_SMALL_STACK_CACHE
3714
   if (key == NULL) {
3715
       err = MP_MEM;
3716
       goto exit;
3717
   }
3718
   err = ecc_key_tmp_init(key, heap);
3719
   if (err != MP_OKAY)
3720
      goto exit;
3721
   R->key = key;
3722
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3723
3724
  /* alloc ram for window temps */
3725
39.5k
  for (i = 0; i < M_POINTS; i++) {
3726
  #ifdef WOLFSSL_NO_MALLOC
3727
      M[i] = &lcl_M[i];
3728
  #endif
3729
29.6k
      err = wc_ecc_new_point_ex(&M[i], heap);
3730
29.6k
      if (err != MP_OKAY) {
3731
105
         goto exit;
3732
105
      }
3733
#ifdef WOLFSSL_SMALL_STACK_CACHE
3734
      M[i]->key = key;
3735
#endif
3736
29.6k
  }
3737
3738
   /* make a copy of G in case R==G */
3739
#ifdef WOLFSSL_NO_MALLOC
3740
   tG = &lcl_tG;
3741
#endif
3742
9.83k
   err = wc_ecc_new_point_ex(&tG, heap);
3743
9.83k
   if (err != MP_OKAY) {
3744
27
       goto exit;
3745
27
   }
3746
9.81k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3747
32
       goto exit;
3748
32
   }
3749
3750
   /* init montgomery reduction */
3751
9.77k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3752
0
       goto exit;
3753
0
   }
3754
3755
#ifdef FP_ECC
3756
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3757
#else
3758
9.77k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3759
9.77k
#endif
3760
   /* map R back from projective space */
3761
9.77k
   if (err == MP_OKAY && map)
3762
9.51k
       err = ecc_map(R, modulus, mp);
3763
3764
10.1k
exit:
3765
3766
   /* done */
3767
10.1k
   wc_ecc_del_point_ex(tG, heap);
3768
40.7k
   for (i = 0; i < M_POINTS; i++) {
3769
30.5k
       wc_ecc_del_point_ex(M[i], heap);
3770
30.5k
   }
3771
3772
#ifdef WOLFSSL_SMALL_STACK_CACHE
3773
   if (key) {
3774
       if (R)
3775
           R->key = NULL;
3776
       if (err == MP_OKAY)
3777
           ecc_key_tmp_final(key, heap);
3778
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3779
   }
3780
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3781
3782
10.1k
   return err;
3783
9.77k
}
3784
#else
3785
{
3786
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3787
       return ECC_BAD_ARG_E;
3788
   }
3789
3790
   (void)a;
3791
3792
   /* For supported curves the order is the same length in bits as the modulus.
3793
    * Can't have more than order bits for the scalar.
3794
    */
3795
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3796
       return ECC_OUT_OF_RANGE_E;
3797
   }
3798
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3799
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3800
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3801
       return IS_POINT_E;
3802
   }
3803
3804
#ifdef WOLFSSL_HAVE_SP_ECC
3805
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3806
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3807
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3808
   }
3809
#endif
3810
#ifndef WOLFSSL_SP_NO_256
3811
   if (mp_count_bits(modulus) == 256) {
3812
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3813
   }
3814
#endif
3815
#ifdef WOLFSSL_SP_384
3816
   if (mp_count_bits(modulus) == 384) {
3817
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3818
   }
3819
#endif
3820
#ifdef WOLFSSL_SP_521
3821
   if (mp_count_bits(modulus) == 521) {
3822
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3823
   }
3824
#endif
3825
#else
3826
   (void)map;
3827
   (void)map;
3828
   (void)heap;
3829
#endif
3830
   return ECC_BAD_ARG_E;
3831
}
3832
#endif
3833
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3834
3835
#ifndef FP_ECC
3836
#if !defined(WOLFSSL_SP_MATH)
3837
#ifdef ECC_TIMING_RESISTANT
3838
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3839
   mp_int* modulus, mp_int* order)
3840
1.78k
{
3841
1.78k
    int err;
3842
1.78k
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3843
3844
1.78k
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3845
#ifdef MP_INT_SIZE_CHECK_NULL
3846
    if (t == NULL) {
3847
        err = MEMORY_E;
3848
    }
3849
    else
3850
#endif
3851
1.78k
    {
3852
1.78k
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3853
1.78k
    }
3854
1.78k
    if (err == MP_OKAY) {
3855
        /* Check for k == order - 1. Result will be 0 point which is not correct
3856
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3857
         * (with constant time implementation)
3858
         */
3859
1.78k
        err = mp_sub_d(order, 1, t);
3860
1.78k
        if (err == MP_OKAY) {
3861
1.78k
            int kIsMinusOne = (mp_cmp((mp_int*)k, t) == MP_EQ);
3862
1.78k
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3863
1.78k
            if (err == MP_OKAY) {
3864
1.78k
                err = mp_sub(modulus, tG->y, t);
3865
1.78k
            }
3866
1.78k
            if (err == MP_OKAY) {
3867
1.78k
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3868
1.78k
            }
3869
1.78k
            if (err == MP_OKAY) {
3870
1.78k
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3871
1.78k
            }
3872
1.78k
        }
3873
3874
1.78k
        mp_free(t);
3875
1.78k
    }
3876
3877
1.78k
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3878
1.78k
    return err;
3879
1.78k
}
3880
#endif /* ECC_TIMING_RESISTANT */
3881
#endif
3882
3883
/**
3884
   Perform a point multiplication
3885
   k    The scalar to multiply by
3886
   G    The base point
3887
   R    [out] Destination for kG
3888
   a    ECC curve parameter a
3889
   modulus  The modulus of the field the ECC curve is in
3890
   map      Boolean whether to map back to affine or not
3891
                (1==map, 0 == leave in projective)
3892
   return MP_OKAY on success
3893
*/
3894
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
3895
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3896
                      void* heap)
3897
#if !defined(WOLFSSL_SP_MATH)
3898
12.3k
{
3899
12.3k
   ecc_point     *tG, *M[M_POINTS];
3900
#ifdef WOLFSSL_NO_MALLOC
3901
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3902
#endif
3903
12.3k
   int           i, err;
3904
#ifdef WOLFSSL_SMALL_STACK_CACHE
3905
   ecc_key       *key = NULL;
3906
#endif
3907
12.3k
   mp_digit      mp;
3908
3909
12.3k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3910
0
      return ECC_BAD_ARG_E;
3911
0
   }
3912
3913
#ifdef HAVE_ECC_CDH
3914
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
3915
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
3916
          return ECC_OUT_OF_RANGE_E;
3917
      }
3918
   }
3919
   else
3920
#endif
3921
   /* k can't have more bits than order */
3922
12.3k
   if (mp_count_bits(k) > mp_count_bits(order)) {
3923
25
      WOLFSSL_MSG("Private key length is greater than order in bits.");
3924
25
      return ECC_OUT_OF_RANGE_E;
3925
25
   }
3926
3927
   /* init variables */
3928
12.3k
   tG = NULL;
3929
12.3k
   XMEMSET(M, 0, sizeof(M));
3930
3931
#ifdef WOLFSSL_SMALL_STACK_CACHE
3932
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3933
   if (key == NULL)
3934
       return MEMORY_E;
3935
   err = ecc_key_tmp_init(key, heap);
3936
   if (err != MP_OKAY)
3937
      goto exit;
3938
   R->key = key;
3939
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3940
3941
   /* alloc ram for window temps */
3942
49.1k
   for (i = 0; i < M_POINTS; i++) {
3943
   #ifdef WOLFSSL_NO_MALLOC
3944
      M[i] = &lcl_M[i];
3945
   #endif
3946
36.8k
      err = wc_ecc_new_point_ex(&M[i], heap);
3947
36.8k
      if (err != MP_OKAY) {
3948
92
         goto exit;
3949
92
      }
3950
#ifdef WOLFSSL_SMALL_STACK_CACHE
3951
      M[i]->key = key;
3952
#endif
3953
36.8k
  }
3954
3955
   /* make a copy of G in case R==G */
3956
#ifdef WOLFSSL_NO_MALLOC
3957
   tG = &lcl_tG;
3958
#endif
3959
12.2k
   err = wc_ecc_new_point_ex(&tG, heap);
3960
12.2k
   if (err != MP_OKAY) {
3961
21
       goto exit;
3962
21
   }
3963
12.2k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3964
80
       goto exit;
3965
80
   }
3966
3967
   /* init montgomery reduction */
3968
12.1k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3969
0
      goto exit;
3970
0
   }
3971
3972
12.1k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3973
12.1k
#ifdef ECC_TIMING_RESISTANT
3974
12.1k
   if (err == MP_OKAY) {
3975
11.9k
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
3976
11.9k
   }
3977
#else
3978
   (void)order;
3979
#endif
3980
   /* map R back from projective space */
3981
12.1k
   if (err == MP_OKAY && map)
3982
0
      err = ecc_map(R, modulus, mp);
3983
3984
12.3k
exit:
3985
3986
   /* done */
3987
12.3k
   wc_ecc_del_point_ex(tG, heap);
3988
49.3k
   for (i = 0; i < M_POINTS; i++) {
3989
37.0k
      wc_ecc_del_point_ex(M[i], heap);
3990
37.0k
   }
3991
#ifdef WOLFSSL_SMALL_STACK_CACHE
3992
   R->key = NULL;
3993
   ecc_key_tmp_final(key, heap);
3994
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
3995
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3996
3997
12.3k
   return err;
3998
12.1k
}
3999
#else
4000
{
4001
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4002
       return ECC_BAD_ARG_E;
4003
   }
4004
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4005
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4006
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4007
       return IS_POINT_E;
4008
   }
4009
4010
   (void)a;
4011
   (void)order;
4012
   (void)rng;
4013
4014
#ifdef WOLFSSL_HAVE_SP_ECC
4015
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4016
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4017
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4018
   }
4019
#endif
4020
#ifndef WOLFSSL_SP_NO_256
4021
   if (mp_count_bits(modulus) == 256) {
4022
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4023
   }
4024
#endif
4025
#ifdef WOLFSSL_SP_384
4026
   if (mp_count_bits(modulus) == 384) {
4027
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4028
   }
4029
#endif
4030
#ifdef WOLFSSL_SP_521
4031
   if (mp_count_bits(modulus) == 521) {
4032
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4033
   }
4034
#endif
4035
#else
4036
   (void)map;
4037
   (void)heap;
4038
#endif
4039
   return ECC_BAD_ARG_E;
4040
}
4041
#endif /* !WOLFSSL_SP_MATH */
4042
#endif /* !FP_ECC */
4043
4044
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4045
4046
/** ECC Fixed Point mulmod global
4047
    k        The multiplicand
4048
    G        Base point to multiply
4049
    R        [out] Destination of product
4050
    a        ECC curve parameter a
4051
    modulus  The modulus for the curve
4052
    map      [boolean] If non-zero maps the point back to affine coordinates,
4053
             otherwise it's left in jacobian-montgomery form
4054
    return MP_OKAY if successful
4055
*/
4056
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4057
                  mp_int* modulus, int map)
4058
0
{
4059
0
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4060
0
        mp_zero(R->x);
4061
0
        mp_zero(R->y);
4062
0
        mp_set(R->z, 1);
4063
0
        return MP_OKAY;
4064
0
    }
4065
0
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4066
0
}
4067
4068
#endif
4069
4070
/**
4071
 * Allocate a new ECC point (if one not provided)
4072
 * use a heap hint when creating new ecc_point
4073
 * @return 0 on success
4074
 * @return BAD_FUNC_ARG for invalid arguments
4075
 * @return MEMORY_E on failure to allocate memory
4076
*/
4077
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4078
290k
{
4079
290k
   int err = MP_OKAY;
4080
290k
   ecc_point* p;
4081
4082
290k
   if (point == NULL) {
4083
0
       return BAD_FUNC_ARG;
4084
0
   }
4085
4086
290k
   p = *point;
4087
290k
   if (p == NULL) {
4088
290k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4089
290k
   }
4090
290k
   if (p == NULL) {
4091
1.47k
      return MEMORY_E;
4092
1.47k
   }
4093
288k
   XMEMSET(p, 0, sizeof(ecc_point));
4094
4095
288k
   if (*point == NULL)
4096
288k
       p->isAllocated = 1;
4097
4098
288k
#ifndef ALT_ECC_SIZE
4099
288k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4100
288k
   if (err != MP_OKAY) {
4101
0
      WOLFSSL_MSG("mp_init_multi failed.");
4102
0
      if (p->isAllocated)
4103
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4104
0
      p = NULL;
4105
0
   }
4106
#else
4107
   p->x = (mp_int*)&p->xyz[0];
4108
   p->y = (mp_int*)&p->xyz[1];
4109
   p->z = (mp_int*)&p->xyz[2];
4110
   alt_fp_init(p->x);
4111
   alt_fp_init(p->y);
4112
   alt_fp_init(p->z);
4113
#endif
4114
4115
288k
   *point = p;
4116
288k
   (void)heap;
4117
288k
   return err;
4118
290k
} /* wc_ecc_new_point_ex */
4119
4120
ecc_point* wc_ecc_new_point_h(void* heap)
4121
31.5k
{
4122
31.5k
    ecc_point* p = NULL;
4123
31.5k
    (void)wc_ecc_new_point_ex(&p, heap);
4124
31.5k
    return p;
4125
31.5k
}
4126
4127
ecc_point* wc_ecc_new_point(void)
4128
11.4k
{
4129
11.4k
   ecc_point* p = NULL;
4130
11.4k
   (void)wc_ecc_new_point_ex(&p, NULL);
4131
11.4k
   return p;
4132
11.4k
}
4133
4134
/** Free an ECC point from memory
4135
  p   The point to free
4136
*/
4137
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4138
326k
{
4139
326k
   if (p != NULL) {
4140
288k
      mp_clear(p->x);
4141
288k
      mp_clear(p->y);
4142
288k
      mp_clear(p->z);
4143
288k
      if (p->isAllocated)
4144
288k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4145
288k
   }
4146
326k
   (void)heap;
4147
326k
}
4148
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4149
374
{
4150
374
   wc_ecc_del_point_ex(p, heap);
4151
374
}
4152
void wc_ecc_del_point(ecc_point* p)
4153
77.3k
{
4154
77.3k
    wc_ecc_del_point_ex(p, NULL);
4155
77.3k
}
4156
4157
void wc_ecc_forcezero_point(ecc_point* p)
4158
0
{
4159
0
    if (p != NULL) {
4160
0
        mp_forcezero(p->x);
4161
0
        mp_forcezero(p->y);
4162
0
        mp_forcezero(p->z);
4163
0
    }
4164
0
}
4165
4166
4167
/** Copy the value of a point to an other one
4168
  p    The point to copy
4169
  r    The created point
4170
*/
4171
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4172
867k
{
4173
867k
    int ret;
4174
4175
    /* prevents null arguments */
4176
867k
    if (p == NULL || r == NULL)
4177
0
        return ECC_BAD_ARG_E;
4178
4179
867k
    ret = mp_copy(p->x, r->x);
4180
867k
    if (ret != MP_OKAY)
4181
3
        return ret;
4182
867k
    ret = mp_copy(p->y, r->y);
4183
867k
    if (ret != MP_OKAY)
4184
2
        return ret;
4185
867k
    ret = mp_copy(p->z, r->z);
4186
867k
    if (ret != MP_OKAY)
4187
2
        return ret;
4188
4189
867k
    return MP_OKAY;
4190
867k
}
4191
4192
/** Compare the value of a point with an other one
4193
 a    The point to compare
4194
 b    The other point to compare
4195
4196
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4197
 */
4198
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4199
1.57k
{
4200
1.57k
    int ret;
4201
4202
    /* prevents null arguments */
4203
1.57k
    if (a == NULL || b == NULL)
4204
0
        return BAD_FUNC_ARG;
4205
4206
1.57k
    ret = mp_cmp(a->x, b->x);
4207
1.57k
    if (ret != MP_EQ)
4208
934
        return ret;
4209
641
    ret = mp_cmp(a->y, b->y);
4210
641
    if (ret != MP_EQ)
4211
212
        return ret;
4212
429
    ret = mp_cmp(a->z, b->z);
4213
429
    if (ret != MP_EQ)
4214
49
        return ret;
4215
4216
380
    return MP_EQ;
4217
429
}
4218
4219
4220
/** Returns whether an ECC idx is valid or not
4221
  n      The idx number to check
4222
  return 1 if valid, 0 if not
4223
*/
4224
int wc_ecc_is_valid_idx(int n)
4225
40.5k
{
4226
40.5k
   int x;
4227
4228
40.5k
   if (n >= (int)ECC_SET_COUNT)
4229
0
       return 0;
4230
4231
1.07M
   for (x = 0; ecc_sets[x].size != 0; x++)
4232
1.03M
       ;
4233
   /* -1 is a valid index --- indicating that the domain params
4234
      were supplied by the user */
4235
40.5k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4236
40.5k
      return 1;
4237
40.5k
   }
4238
4239
0
   return 0;
4240
40.5k
}
4241
4242
int wc_ecc_get_curve_idx(int curve_id)
4243
31.0k
{
4244
31.0k
    int curve_idx;
4245
510k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4246
510k
        if (curve_id == ecc_sets[curve_idx].id)
4247
31.0k
            break;
4248
510k
    }
4249
31.0k
    if (ecc_sets[curve_idx].size == 0) {
4250
0
        return ECC_CURVE_INVALID;
4251
0
    }
4252
31.0k
    return curve_idx;
4253
31.0k
}
4254
4255
int wc_ecc_get_curve_id(int curve_idx)
4256
1.68k
{
4257
1.68k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4258
1.68k
        return ecc_sets[curve_idx].id;
4259
1.68k
    }
4260
0
    return ECC_CURVE_INVALID;
4261
1.68k
}
4262
4263
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4264
 *
4265
 * id      curve id, from ecc_curve_id enum in ecc.h
4266
 * return  curve size, from ecc_sets[] on success, negative on error
4267
 */
4268
int wc_ecc_get_curve_size_from_id(int curve_id)
4269
1.81k
{
4270
1.81k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4271
1.81k
    if (curve_idx == ECC_CURVE_INVALID)
4272
0
        return ECC_BAD_ARG_E;
4273
1.81k
    return ecc_sets[curve_idx].size;
4274
1.81k
}
4275
4276
/* Returns the curve index that corresponds to a given curve name in
4277
 * ecc_sets[] of ecc.c
4278
 *
4279
 * name    curve name, from ecc_sets[].name in ecc.c
4280
 * return  curve index in ecc_sets[] on success, negative on error
4281
 */
4282
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4283
0
{
4284
0
    int curve_idx;
4285
4286
0
    if (curveName == NULL)
4287
0
        return BAD_FUNC_ARG;
4288
4289
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4290
0
        if (
4291
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4292
0
            ecc_sets[curve_idx].name &&
4293
0
        #endif
4294
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4295
0
            break;
4296
0
        }
4297
0
    }
4298
0
    if (ecc_sets[curve_idx].size == 0) {
4299
0
        WOLFSSL_MSG("ecc_set curve name not found");
4300
0
        return ECC_CURVE_INVALID;
4301
0
    }
4302
0
    return curve_idx;
4303
0
}
4304
4305
/* Returns the curve size that corresponds to a given curve name,
4306
 * as listed in ecc_sets[] of ecc.c.
4307
 *
4308
 * name    curve name, from ecc_sets[].name in ecc.c
4309
 * return  curve size, from ecc_sets[] on success, negative on error
4310
 */
4311
int wc_ecc_get_curve_size_from_name(const char* curveName)
4312
0
{
4313
0
    int curve_idx;
4314
4315
0
    if (curveName == NULL)
4316
0
        return BAD_FUNC_ARG;
4317
4318
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4319
0
    if (curve_idx < 0)
4320
0
        return curve_idx;
4321
4322
0
    return ecc_sets[curve_idx].size;
4323
0
}
4324
4325
/* Returns the curve id that corresponds to a given curve name,
4326
 * as listed in ecc_sets[] of ecc.c.
4327
 *
4328
 * name   curve name, from ecc_sets[].name in ecc.c
4329
 * return curve id, from ecc_sets[] on success, negative on error
4330
 */
4331
int wc_ecc_get_curve_id_from_name(const char* curveName)
4332
0
{
4333
0
    int curve_idx;
4334
4335
0
    if (curveName == NULL)
4336
0
        return BAD_FUNC_ARG;
4337
4338
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4339
0
    if (curve_idx < 0)
4340
0
        return curve_idx;
4341
4342
0
    return ecc_sets[curve_idx].id;
4343
0
}
4344
4345
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4346
 * parameter for equality.
4347
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4348
 * Returns MP_EQ on success, negative on error */
4349
static int wc_ecc_cmp_param(const char* curveParam,
4350
                            const byte* param, word32 paramSz, int encType)
4351
0
{
4352
0
    int err = MP_OKAY;
4353
0
#ifdef WOLFSSL_SMALL_STACK
4354
0
    mp_int* a = NULL;
4355
0
    mp_int* b = NULL;
4356
#else
4357
    mp_int  a[1], b[1];
4358
#endif
4359
4360
0
    if (param == NULL || curveParam == NULL)
4361
0
        return BAD_FUNC_ARG;
4362
4363
0
    if (encType == WC_TYPE_HEX_STR) {
4364
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4365
0
            return -1;
4366
0
        return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1;
4367
0
    }
4368
4369
0
#ifdef WOLFSSL_SMALL_STACK
4370
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4371
0
    if (a == NULL)
4372
0
        return MEMORY_E;
4373
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4374
0
    if (b == NULL) {
4375
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4376
0
        return MEMORY_E;
4377
0
    }
4378
0
#endif
4379
4380
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4381
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4382
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4383
0
        return err;
4384
0
    }
4385
4386
0
    if (err == MP_OKAY) {
4387
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4388
0
    }
4389
0
    if (err == MP_OKAY)
4390
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4391
4392
0
    if (err == MP_OKAY) {
4393
0
        if (mp_cmp(a, b) != MP_EQ) {
4394
0
            err = -1;
4395
0
        } else {
4396
0
            err = MP_EQ;
4397
0
        }
4398
0
    }
4399
4400
0
    mp_clear(a);
4401
0
    mp_clear(b);
4402
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4403
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4404
4405
0
    return err;
4406
0
}
4407
4408
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4409
 * curve parameters.
4410
 *
4411
 * fieldSize  the field size in bits
4412
 * prime      prime of the finite field
4413
 * primeSz    size of prime in octets
4414
 * Af         first coefficient a of the curve
4415
 * AfSz       size of Af in octets
4416
 * Bf         second coefficient b of the curve
4417
 * BfSz       size of Bf in octets
4418
 * order      curve order
4419
 * orderSz    size of curve in octets
4420
 * Gx         affine x coordinate of base point
4421
 * GxSz       size of Gx in octets
4422
 * Gy         affine y coordinate of base point
4423
 * GySz       size of Gy in octets
4424
 * cofactor   curve cofactor
4425
 *
4426
 * return curve id, from ecc_sets[] on success, negative on error
4427
 */
4428
int wc_ecc_get_curve_id_from_params(int fieldSize,
4429
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4430
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4431
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4432
0
{
4433
0
    int idx;
4434
0
    int curveSz;
4435
4436
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4437
0
        Gx == NULL || Gy == NULL)
4438
0
        return BAD_FUNC_ARG;
4439
4440
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4441
4442
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4443
0
        if (curveSz == ecc_sets[idx].size) {
4444
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4445
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4446
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4447
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4448
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4449
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4450
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4451
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4452
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4453
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4454
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4455
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4456
0
                (cofactor == ecc_sets[idx].cofactor)) {
4457
0
                    break;
4458
0
            }
4459
0
        }
4460
0
    }
4461
4462
0
    if (ecc_sets[idx].size == 0)
4463
0
        return ECC_CURVE_INVALID;
4464
4465
0
    return ecc_sets[idx].id;
4466
0
}
4467
4468
/* Returns the curve id in ecc_sets[] that corresponds
4469
 * to a given domain parameters pointer.
4470
 *
4471
 * dp   domain parameters pointer
4472
 *
4473
 * return curve id, from ecc_sets[] on success, negative on error
4474
 */
4475
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4476
0
{
4477
0
    int idx;
4478
4479
0
    if (dp == NULL
4480
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4481
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4482
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4483
0
    #endif
4484
0
    ) {
4485
0
        return BAD_FUNC_ARG;
4486
0
    }
4487
4488
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4489
0
        if (dp->size == ecc_sets[idx].size) {
4490
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4491
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4492
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4493
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4494
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4495
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4496
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4497
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4498
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4499
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4500
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4501
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4502
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4503
0
                    break;
4504
0
            }
4505
0
        }
4506
0
    }
4507
4508
0
    if (ecc_sets[idx].size == 0)
4509
0
        return ECC_CURVE_INVALID;
4510
4511
0
    return ecc_sets[idx].id;
4512
0
}
4513
4514
/* Returns the curve id that corresponds to a given OID,
4515
 * as listed in ecc_sets[] of ecc.c.
4516
 *
4517
 * oid   OID, from ecc_sets[].name in ecc.c
4518
 * len   OID len, from ecc_sets[].name in ecc.c
4519
 * return curve id, from ecc_sets[] on success, negative on error
4520
 */
4521
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4522
0
{
4523
0
    int curve_idx;
4524
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4525
    int ret;
4526
    #ifdef HAVE_OID_DECODING
4527
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4528
    #else
4529
    byte  decOid[MAX_OID_SZ];
4530
    #endif
4531
    word32 decOidSz;
4532
#endif
4533
4534
0
    if (oid == NULL)
4535
0
        return BAD_FUNC_ARG;
4536
4537
#ifdef HAVE_OID_DECODING
4538
    decOidSz = (word32)sizeof(decOid);
4539
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4540
    if (ret != 0) {
4541
        return ret;
4542
    }
4543
#endif
4544
4545
0
    if (len == 0) {
4546
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4547
0
        WOLFSSL_MSG("zero oidSz");
4548
0
        return ECC_CURVE_INVALID;
4549
0
    }
4550
4551
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4552
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4553
        decOidSz = (word32)sizeof(decOid);
4554
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4555
            decOid, &decOidSz);
4556
        if (ret != 0) {
4557
            continue;
4558
        }
4559
    #endif
4560
4561
0
        if (
4562
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4563
0
            ecc_sets[curve_idx].oid &&
4564
0
        #endif
4565
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4566
            decOidSz == len &&
4567
                XMEMCMP(decOid, oid, len) == 0
4568
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4569
            /* We double because decOidSz is a count of word16 elements. */
4570
            ecc_sets[curve_idx].oidSz == decOidSz &&
4571
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4572
        #else
4573
0
            ecc_sets[curve_idx].oidSz == len &&
4574
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4575
0
        #endif
4576
0
        ) {
4577
0
            break;
4578
0
        }
4579
0
    }
4580
0
    if (ecc_sets[curve_idx].size == 0) {
4581
0
        WOLFSSL_MSG("ecc_set curve name not found");
4582
0
        return ECC_CURVE_INVALID;
4583
0
    }
4584
4585
0
    return ecc_sets[curve_idx].id;
4586
0
}
4587
4588
/* Get curve parameters using curve index */
4589
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4590
20.1k
{
4591
20.1k
    const ecc_set_type* ecc_set = NULL;
4592
4593
20.1k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4594
20.1k
        ecc_set = &ecc_sets[curve_idx];
4595
20.1k
    }
4596
20.1k
    return ecc_set;
4597
20.1k
}
4598
4599
4600
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4601
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4602
{
4603
   if (key == NULL || mp == NULL)
4604
      return BAD_FUNC_ARG;
4605
   if (*mp == NULL) {
4606
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4607
      if (*mp == NULL) {
4608
         return MEMORY_E;
4609
      }
4610
      XMEMSET(*mp, 0, sizeof(mp_int));
4611
   }
4612
   return 0;
4613
}
4614
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4615
{
4616
   if (key && mp && *mp) {
4617
      mp_clear(*mp);
4618
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4619
      *mp = NULL;
4620
   }
4621
}
4622
4623
static int wc_ecc_alloc_async(ecc_key* key)
4624
{
4625
    int err = wc_ecc_alloc_mpint(key, &key->r);
4626
    if (err == 0)
4627
        err = wc_ecc_alloc_mpint(key, &key->s);
4628
    return err;
4629
}
4630
4631
static void wc_ecc_free_async(ecc_key* key)
4632
{
4633
    wc_ecc_free_mpint(key, &key->r);
4634
    wc_ecc_free_mpint(key, &key->s);
4635
#ifdef HAVE_CAVIUM_V
4636
    wc_ecc_free_mpint(key, &key->e);
4637
    wc_ecc_free_mpint(key, &key->signK);
4638
#endif /* HAVE_CAVIUM_V */
4639
}
4640
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4641
4642
4643
#ifdef HAVE_ECC_DHE
4644
/**
4645
  Create an ECC shared secret between two keys
4646
  private_key      The private ECC key (heap hint based off of private key)
4647
  public_key       The public key
4648
  out              [out] Destination of the shared secret
4649
                         Conforms to EC-DH from ANSI X9.63
4650
  outlen           [in/out] The max size and resulting size of the shared secret
4651
  return           MP_OKAY if successful
4652
*/
4653
WOLFSSL_ABI
4654
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4655
                      word32* outlen)
4656
1.58k
{
4657
1.58k
   int err = 0;
4658
4659
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4660
   !defined(WOLFSSL_ATECC608A)
4661
   CRYS_ECDH_TempData_t tempBuff;
4662
#endif
4663
4664
1.58k
   (void)err;
4665
4666
1.58k
   if (private_key == NULL || public_key == NULL || out == NULL ||
4667
1.58k
                                                            outlen == NULL) {
4668
0
       return BAD_FUNC_ARG;
4669
0
   }
4670
4671
1.58k
#ifdef WOLF_CRYPTO_CB
4672
1.58k
    #ifndef WOLF_CRYPTO_CB_FIND
4673
1.58k
    if (private_key->devId != INVALID_DEVID)
4674
0
    #endif
4675
0
    {
4676
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4677
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4678
0
            return err;
4679
        /* fall-through when unavailable */
4680
0
    }
4681
1.58k
#endif
4682
4683
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4684
    return NO_VALID_DEVID;
4685
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4686
   /* type valid? */
4687
1.58k
   if (private_key->type != ECC_PRIVATEKEY &&
4688
391
           private_key->type != ECC_PRIVATEKEY_ONLY) {
4689
0
      return ECC_BAD_ARG_E;
4690
0
   }
4691
4692
   /* Verify domain params supplied */
4693
1.58k
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4694
1.58k
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4695
0
      return ECC_BAD_ARG_E;
4696
0
   }
4697
4698
   /* Verify curve id matches */
4699
1.58k
   if (private_key->dp->id != public_key->dp->id) {
4700
0
      return ECC_BAD_ARG_E;
4701
0
   }
4702
4703
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
4704
   /* For SECP256R1 use hardware */
4705
   if (private_key->dp->id == ECC_SECP256R1) {
4706
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4707
       *outlen = private_key->dp->size;
4708
   }
4709
   else {
4710
      err = NOT_COMPILED_IN;
4711
   }
4712
#elif defined(WOLFSSL_CRYPTOCELL)
4713
4714
    /* generate a secret*/
4715
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4716
                            &private_key->ctx.privKey,
4717
                            out,
4718
                            (uint32_t*)outlen,
4719
                            &tempBuff);
4720
4721
    if (err != SA_SILIB_RET_OK){
4722
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4723
        return err;
4724
    }
4725
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4726
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4727
#elif defined(WOLFSSL_KCAPI_ECC)
4728
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4729
#elif defined(WOLFSSL_SE050)
4730
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4731
#else
4732
1.58k
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4733
1.58k
#endif /* WOLFSSL_ATECC508A */
4734
1.58k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4735
4736
1.58k
   return err;
4737
1.58k
}
4738
4739
4740
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4741
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4742
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4743
4744
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4745
                               byte* out, word32* outlen)
4746
216
{
4747
216
    int err = MP_OKAY;
4748
216
    mp_int* k = ecc_get_k(private_key);
4749
#ifdef HAVE_ECC_CDH
4750
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
4751
#endif
4752
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4753
    defined(WC_ECC_NONBLOCK_ONLY)
4754
    ecc_nb_ctx_t nb_ctx;
4755
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4756
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4757
4758
#ifdef HAVE_ECC_CDH
4759
    /* if cofactor flag has been set */
4760
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4761
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4762
        /* only perform cofactor calc if not equal to 1 */
4763
        if (cofactor != 1) {
4764
#ifdef WOLFSSL_SMALL_STACK
4765
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4766
                return MEMORY_E;
4767
#endif
4768
            k = k_lcl;
4769
            if (mp_init(k) != MP_OKAY) {
4770
                err = MEMORY_E;
4771
                goto errout;
4772
            }
4773
            /* multiply cofactor times private key "k" */
4774
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4775
            if (err != MP_OKAY)
4776
                goto errout;
4777
        }
4778
    }
4779
#endif
4780
4781
#ifdef WOLFSSL_HAVE_SP_ECC
4782
4783
#ifndef WOLFSSL_SP_NO_256
4784
    if (private_key->idx != ECC_CUSTOM_IDX &&
4785
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4786
    #ifndef WC_ECC_NONBLOCK
4787
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4788
    #else
4789
        if (private_key->nb_ctx) {
4790
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4791
                                           point, out, outlen,
4792
                                           private_key->heap);
4793
        }
4794
        else {
4795
        #ifdef WC_ECC_NONBLOCK_ONLY
4796
            do { /* perform blocking call to non-blocking function */
4797
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4798
                                               outlen, private_key->heap);
4799
            } while (err == FP_WOULDBLOCK);
4800
        #else
4801
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4802
                                        private_key->heap);
4803
        #endif /* WC_ECC_NONBLOCK_ONLY */
4804
        }
4805
    #endif /* !WC_ECC_NONBLOCK */
4806
    }
4807
    else
4808
#endif /* ! WOLFSSL_SP_NO_256 */
4809
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4810
    if (private_key->idx != ECC_CUSTOM_IDX &&
4811
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4812
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4813
                                                             private_key->heap);
4814
    }
4815
    else
4816
#endif
4817
#ifdef WOLFSSL_SP_384
4818
    if (private_key->idx != ECC_CUSTOM_IDX &&
4819
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4820
    #ifndef WC_ECC_NONBLOCK
4821
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4822
    #else
4823
        if (private_key->nb_ctx) {
4824
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4825
                                           point, out, outlen,
4826
                                           private_key->heap);
4827
        }
4828
        else {
4829
        #ifdef WC_ECC_NONBLOCK_ONLY
4830
            do { /* perform blocking call to non-blocking function */
4831
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4832
                                               outlen, private_key->heap);
4833
            } while (err == FP_WOULDBLOCK);
4834
        #else
4835
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4836
                                        private_key->heap);
4837
        #endif /* WC_ECC_NONBLOCK_ONLY */
4838
        }
4839
    #endif /* !WC_ECC_NONBLOCK */
4840
    }
4841
    else
4842
#endif /* WOLFSSL_SP_384 */
4843
#ifdef WOLFSSL_SP_521
4844
    if (private_key->idx != ECC_CUSTOM_IDX &&
4845
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4846
    #ifndef WC_ECC_NONBLOCK
4847
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4848
    #else
4849
        if (private_key->nb_ctx) {
4850
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4851
                                           point, out, outlen,
4852
                                           private_key->heap);
4853
        }
4854
        else {
4855
        #ifdef WC_ECC_NONBLOCK_ONLY
4856
            do { /* perform blocking call to non-blocking function */
4857
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4858
                                               outlen, private_key->heap);
4859
            } while (err == FP_WOULDBLOCK);
4860
        #else
4861
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4862
                                        private_key->heap);
4863
        #endif /* WC_ECC_NONBLOCK_ONLY */
4864
        }
4865
    #endif /* !WC_ECC_NONBLOCK */
4866
    }
4867
    else
4868
#endif /* WOLFSSL_SP_521 */
4869
#else
4870
216
    (void)point;
4871
216
    (void)out;
4872
216
    (void)outlen;
4873
216
    (void)k;
4874
216
#endif
4875
#if defined(WOLFSSL_SP_MATH)
4876
    {
4877
        err = WC_KEY_SIZE_E;
4878
        goto errout;
4879
    }
4880
#else
4881
216
    {
4882
216
        ecc_point* result = NULL;
4883
        #ifdef WOLFSSL_NO_MALLOC
4884
        ecc_point  lcl_result;
4885
        #endif
4886
216
        int x = 0;
4887
216
        mp_digit mp = 0;
4888
216
        DECLARE_CURVE_SPECS(3);
4889
4890
        /* load curve info */
4891
216
        ALLOC_CURVE_SPECS(3, err);
4892
216
        if (err == MP_OKAY) {
4893
216
            err = wc_ecc_curve_load(private_key->dp, &curve,
4894
216
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4895
216
                 ECC_CURVE_FIELD_ORDER));
4896
216
        }
4897
4898
216
        if (err != MP_OKAY) {
4899
0
            FREE_CURVE_SPECS();
4900
0
            goto errout;
4901
0
        }
4902
4903
        /* make new point */
4904
    #ifdef WOLFSSL_NO_MALLOC
4905
        result = &lcl_result;
4906
    #endif
4907
216
        err = wc_ecc_new_point_ex(&result, private_key->heap);
4908
216
        if (err != MP_OKAY) {
4909
0
            wc_ecc_curve_free(curve);
4910
0
            FREE_CURVE_SPECS();
4911
0
            goto errout;
4912
0
        }
4913
4914
216
#ifdef ECC_TIMING_RESISTANT
4915
216
        if (private_key->rng == NULL) {
4916
0
            err = MISSING_RNG_E;
4917
0
        }
4918
216
#endif
4919
4920
216
        if (err == MP_OKAY) {
4921
            /* Map in a separate call as this should be constant time */
4922
216
#ifdef ECC_TIMING_RESISTANT
4923
216
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4924
216
                                              curve->order, private_key->rng, 0,
4925
216
                                              private_key->heap);
4926
#else
4927
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
4928
                                      curve->order, NULL, 0, private_key->heap);
4929
#endif
4930
216
        }
4931
216
        if (err == MP_OKAY) {
4932
        #ifdef WOLFSSL_CHECK_MEM_ZERO
4933
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
4934
                result->x);
4935
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
4936
                result->y);
4937
        #endif
4938
206
            err = mp_montgomery_setup(curve->prime, &mp);
4939
206
        }
4940
216
        if (err == MP_OKAY) {
4941
            /* Use constant time map if compiled in */
4942
206
            err = ecc_map_ex(result, curve->prime, mp, 1);
4943
206
        }
4944
216
        if (err == MP_OKAY) {
4945
206
            x = mp_unsigned_bin_size(curve->prime);
4946
206
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
4947
0
                err = BUFFER_E;
4948
0
            }
4949
206
        }
4950
4951
216
        if (err == MP_OKAY) {
4952
206
            XMEMSET(out, 0, (size_t)x);
4953
206
            err = mp_to_unsigned_bin(result->x, out +
4954
206
                                     (x - mp_unsigned_bin_size(result->x)));
4955
206
        }
4956
216
        *outlen = (word32)x;
4957
4958
216
        mp_forcezero(result->x);
4959
216
        mp_forcezero(result->y);
4960
216
        wc_ecc_del_point_ex(result, private_key->heap);
4961
4962
216
        wc_ecc_curve_free(curve);
4963
216
        FREE_CURVE_SPECS();
4964
216
    }
4965
0
#endif
4966
4967
216
  errout:
4968
4969
#ifdef HAVE_ECC_CDH
4970
    if (k == k_lcl)
4971
        mp_clear(k);
4972
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
4973
#endif
4974
4975
216
    return err;
4976
216
}
4977
4978
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4979
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
4980
            ecc_point* point, byte* out, word32 *outlen)
4981
{
4982
    int err = 0;
4983
4984
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
4985
    DECLARE_CURVE_SPECS(3);
4986
4987
    /* load curve info */
4988
    ALLOC_CURVE_SPECS(3, err);
4989
    if (err == MP_OKAY) {
4990
        err = wc_ecc_curve_load(private_key->dp, &curve,
4991
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
4992
             ECC_CURVE_FIELD_ORDER));
4993
    }
4994
4995
    if (err != MP_OKAY) {
4996
        FREE_CURVE_SPECS();
4997
        return err;
4998
    }
4999
5000
    if (private_key->dp
5001
    #ifdef WOLFSSL_CUSTOM_CURVES
5002
        && private_key->dp->id != ECC_CURVE_CUSTOM
5003
    #endif
5004
    #ifdef HAVE_CAVIUM_V
5005
        /* verify the curve is supported by hardware */
5006
        && NitroxEccIsCurveSupported(private_key)
5007
    #endif
5008
    ) {
5009
        word32 keySz = private_key->dp->size;
5010
5011
        /* sync public key x/y */
5012
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5013
            &ecc_get_k(private_key)->raw, keySz);
5014
        if (err == MP_OKAY)
5015
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5016
        if (err == MP_OKAY)
5017
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5018
    #ifdef HAVE_CAVIUM_V
5019
        /* allocate buffer for output */
5020
        if (err == MP_OKAY)
5021
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5022
        if (err == MP_OKAY)
5023
            err = wc_bigint_alloc(&private_key->e->raw,
5024
                NitroxEccGetSize(private_key)*2);
5025
        if (err == MP_OKAY)
5026
            err = NitroxEcdh(private_key,
5027
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5028
                private_key->e->raw.buf, &private_key->e->raw.len,
5029
                &curve->prime->raw);
5030
    #else
5031
        if (err == MP_OKAY)
5032
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5033
        if (err == MP_OKAY)
5034
            err = IntelQaEcdh(&private_key->asyncDev,
5035
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5036
                out, outlen,
5037
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5038
                private_key->dp->cofactor);
5039
    #endif
5040
    }
5041
    else
5042
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5043
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5044
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5045
        sw->eccSharedSec.private_key = private_key;
5046
        sw->eccSharedSec.public_point = point;
5047
        sw->eccSharedSec.out = out;
5048
        sw->eccSharedSec.outLen = outlen;
5049
        err = WC_PENDING_E;
5050
    }
5051
    else
5052
#endif
5053
    {
5054
        /* use sync in other cases */
5055
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5056
    }
5057
5058
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5059
        private_key->state++;
5060
    }
5061
5062
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5063
    wc_ecc_curve_free(curve);
5064
    FREE_CURVE_SPECS();
5065
#endif
5066
5067
    return err;
5068
}
5069
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5070
5071
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5072
/**
5073
 Create an ECC shared secret between private key and public point
5074
 private_key      The private ECC key (heap hint based on private key)
5075
 point            The point to use (public key)
5076
 out              [out] Destination of the shared secret
5077
                        Conforms to EC-DH from ANSI X9.63
5078
 outlen           [in/out] The max size and resulting size of the shared secret
5079
 return           MP_OKAY if successful
5080
*/
5081
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5082
                            byte* out, word32 *outlen)
5083
1.58k
{
5084
1.58k
    int err;
5085
5086
1.58k
    if (private_key == NULL || point == NULL || out == NULL ||
5087
1.58k
                                                            outlen == NULL) {
5088
0
        return BAD_FUNC_ARG;
5089
0
    }
5090
5091
    /* type valid? */
5092
1.58k
    if (private_key->type != ECC_PRIVATEKEY &&
5093
391
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5094
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5095
0
        return ECC_BAD_ARG_E;
5096
0
    }
5097
5098
    /* Verify domain params supplied */
5099
1.58k
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5100
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5101
0
        return ECC_BAD_ARG_E;
5102
0
    }
5103
5104
1.58k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5105
5106
1.58k
    switch (private_key->state) {
5107
1.58k
        case ECC_STATE_NONE:
5108
1.58k
        case ECC_STATE_SHARED_SEC_GEN:
5109
1.58k
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5110
5111
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5112
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5113
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5114
                    out, outlen);
5115
            }
5116
            else
5117
        #endif
5118
1.58k
            {
5119
1.58k
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5120
1.58k
                    out, outlen);
5121
1.58k
            }
5122
1.58k
            if (err < 0) {
5123
101
                break;
5124
101
            }
5125
1.48k
            FALL_THROUGH;
5126
5127
1.48k
        case ECC_STATE_SHARED_SEC_RES:
5128
1.48k
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5129
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5130
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5131
            #ifdef HAVE_CAVIUM_V
5132
                /* verify the curve is supported by hardware */
5133
                if (NitroxEccIsCurveSupported(private_key)) {
5134
                    /* copy output */
5135
                    *outlen = private_key->dp->size;
5136
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5137
                }
5138
            #endif /* HAVE_CAVIUM_V */
5139
            }
5140
        #endif /* WOLFSSL_ASYNC_CRYPT */
5141
1.48k
            err = 0;
5142
1.48k
            break;
5143
5144
0
        default:
5145
0
            err = BAD_STATE_E;
5146
1.58k
    } /* switch */
5147
5148
1.58k
    RESTORE_VECTOR_REGISTERS();
5149
5150
    /* if async pending then return and skip done cleanup below */
5151
1.58k
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5152
0
        return err;
5153
0
    }
5154
5155
    /* cleanup */
5156
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5157
    wc_ecc_free_async(private_key);
5158
#endif
5159
1.58k
    private_key->state = ECC_STATE_NONE;
5160
5161
1.58k
    return err;
5162
1.58k
}
5163
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5164
#elif defined(WOLFSSL_KCAPI_ECC)
5165
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5166
                            byte* out, word32 *outlen)
5167
{
5168
    int err;
5169
    ecc_key public_key;
5170
5171
    err = wc_ecc_init_ex(&public_key, private_key->heap, INVALID_DEVID);
5172
    if (err == MP_OKAY) {
5173
        #if FIPS_VERSION3_GE(6,0,0)
5174
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5175
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5176
         * keysize here when relying on default selection */
5177
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5178
            if (private_key->dp->size == 0 &&
5179
                (private_key->dp->id == ECC_SECP256R1 ||
5180
                private_key->dp->id == ECC_SECP224R1 ||
5181
                private_key->dp->id == ECC_SECP384R1 ||
5182
                private_key->dp->id == ECC_SECP521R1)) {
5183
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5184
                err = 0;
5185
            } else {
5186
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5187
                err = ECC_CURVE_OID_E;
5188
            }
5189
        }
5190
        if (err == 0) { /* FIPS specific check */
5191
        #endif
5192
        err = wc_ecc_set_curve(&public_key, private_key->dp->size,
5193
                               private_key->dp->id);
5194
        if (err == MP_OKAY) {
5195
            err = mp_copy(point->x, public_key.pubkey.x);
5196
        }
5197
        #if FIPS_VERSION3_GE(6,0,0)
5198
        } /* end FIPS specific check */
5199
        #endif
5200
        if (err == MP_OKAY) {
5201
            err = mp_copy(point->y, public_key.pubkey.y);
5202
        }
5203
        if (err == MP_OKAY) {
5204
            err = wc_ecc_shared_secret(private_key, &public_key, out, outlen);
5205
        }
5206
5207
        wc_ecc_free(&public_key);
5208
    }
5209
5210
    return err;
5211
}
5212
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5213
#endif /* HAVE_ECC_DHE */
5214
5215
#ifdef USE_ECC_B_PARAM
5216
/* Checks if a point p lies on the curve with index curve_idx */
5217
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5218
3.20k
{
5219
3.20k
    int err = MP_OKAY;
5220
3.20k
    DECLARE_CURVE_SPECS(3);
5221
5222
3.20k
    if (p == NULL)
5223
0
        return BAD_FUNC_ARG;
5224
5225
    /* is the IDX valid ?  */
5226
3.20k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5227
0
       return ECC_BAD_ARG_E;
5228
0
    }
5229
5230
3.20k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5231
5232
3.20k
    ALLOC_CURVE_SPECS(3, err);
5233
3.20k
    if (err == MP_OKAY) {
5234
2.99k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5235
2.99k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5236
2.99k
                                ECC_CURVE_FIELD_BF);
5237
2.99k
    }
5238
5239
3.20k
    if (err == MP_OKAY) {
5240
2.97k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5241
2.97k
    }
5242
5243
3.20k
    wc_ecc_curve_free(curve);
5244
3.20k
    FREE_CURVE_SPECS();
5245
5246
3.20k
    RESTORE_VECTOR_REGISTERS();
5247
5248
3.20k
    return err;
5249
3.20k
}
5250
#endif /* USE_ECC_B_PARAM */
5251
5252
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5253
    !defined(WOLFSSL_CRYPTOCELL) && \
5254
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5255
      defined(WOLFSSL_IMXRT1170_CAAM))
5256
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5257
int wc_ecc_point_is_at_infinity(ecc_point* p)
5258
2.96k
{
5259
2.96k
    if (p == NULL)
5260
0
        return BAD_FUNC_ARG;
5261
2.96k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5262
1.24k
        return 1;
5263
5264
1.72k
    return 0;
5265
2.96k
}
5266
#endif
5267
5268
/* generate random and ensure its greater than 0 and less than order */
5269
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5270
2.71k
{
5271
2.71k
#ifndef WC_NO_RNG
5272
2.71k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5273
2.71k
    int err;
5274
2.71k
    byte buf[ECC_MAXSIZE_GEN];
5275
5276
2.71k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5277
2.71k
                                                                order == NULL) {
5278
0
        return BAD_FUNC_ARG;
5279
0
    }
5280
5281
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5282
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5283
2.71k
    size += 8;
5284
5285
    /* make up random string */
5286
2.71k
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5287
#ifdef WOLFSSL_CHECK_MEM_ZERO
5288
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5289
#endif
5290
5291
    /* load random buffer data into k */
5292
2.71k
    if (err == 0)
5293
2.69k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5294
5295
    /* the key should be smaller than the order of base point */
5296
2.71k
    if (err == MP_OKAY) {
5297
2.69k
        if (mp_cmp(k, order) != MP_LT) {
5298
2.68k
            err = mp_mod(k, order, k);
5299
2.68k
        }
5300
2.69k
    }
5301
5302
    /* quick sanity check to make sure we're not dealing with a 0 key */
5303
2.71k
    if (err == MP_OKAY) {
5304
2.68k
        if (mp_iszero(k) == MP_YES)
5305
2
          err = MP_ZERO_E;
5306
2.68k
    }
5307
5308
2.71k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5309
#ifdef WOLFSSL_CHECK_MEM_ZERO
5310
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5311
#endif
5312
5313
2.71k
    return err;
5314
#else
5315
    int err;
5316
    byte buf[ECC_MAXSIZE_GEN];
5317
    int bits;
5318
5319
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5320
            (k == NULL) || (order == NULL)) {
5321
        return BAD_FUNC_ARG;
5322
    }
5323
5324
    /* Get actual bit count of order. */
5325
    bits = mp_count_bits(order);
5326
    size = (bits + 7) >> 3;
5327
5328
    /* generate number in range of order through rejection sampling. */
5329
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5330
    do {
5331
        /* A.2.2 step 3: make up random string */
5332
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5333
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5334
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5335
    #endif
5336
        /* Generated multiple of 8 bits but now make it size of order. */
5337
        if ((bits & 0x7) > 0) {
5338
            buf[0] &= (1 << (bits & 0x7)) - 1;
5339
        }
5340
5341
        /* A.2.2 step 4: convert to integer. */
5342
        /* A.4.2 step 3: Convert the bit string to integer x. */
5343
        if (err == 0) {
5344
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5345
        }
5346
5347
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5348
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5349
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5350
            break;
5351
        }
5352
    }
5353
    while (err == MP_OKAY);
5354
5355
    ForceZero(buf, ECC_MAXSIZE_GEN);
5356
#ifdef WOLFSSL_CHECK_MEM_ZERO
5357
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5358
#endif
5359
5360
    return err;
5361
#endif
5362
#else
5363
    (void)rng;
5364
    (void)size;
5365
    (void)k;
5366
    (void)order;
5367
    return NOT_COMPILED_IN;
5368
#endif /* !WC_NO_RNG */
5369
2.71k
}
5370
5371
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5372
44.4k
{
5373
    /* make sure required key variables are reset */
5374
44.4k
    key->state = ECC_STATE_NONE;
5375
44.4k
}
5376
5377
5378
/* create the public ECC key from a private key
5379
 *
5380
 * key     an initialized private key to generate public part from
5381
 * curve   [in]curve for key, cannot be NULL
5382
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5383
 *         is cached in key instead.
5384
 *
5385
 * Note this function is local to the file because of the argument type
5386
 *      ecc_curve_spec. Having this argument allows for not having to load the
5387
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5388
 * For async the results are placed directly into pubOut, so this function
5389
 *      does not need to be called again
5390
 *
5391
 * returns MP_OKAY on success
5392
 */
5393
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5394
        ecc_point* pubOut, WC_RNG* rng)
5395
1.77k
{
5396
1.77k
    int err = MP_OKAY;
5397
1.77k
#ifdef HAVE_ECC_MAKE_PUB
5398
1.77k
    ecc_point* pub;
5399
1.77k
#endif /* HAVE_ECC_MAKE_PUB */
5400
5401
1.77k
    (void)rng;
5402
5403
1.77k
    if (key == NULL) {
5404
0
        return BAD_FUNC_ARG;
5405
0
    }
5406
5407
1.77k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
5408
5409
1.77k
#ifdef HAVE_ECC_MAKE_PUB
5410
    /* if ecc_point passed in then use it as output for public key point */
5411
1.77k
    if (pubOut != NULL) {
5412
637
        pub = pubOut;
5413
637
    }
5414
1.13k
    else {
5415
        /* caching public key making it a ECC_PRIVATEKEY instead of
5416
           ECC_PRIVATEKEY_ONLY */
5417
1.13k
        pub = &key->pubkey;
5418
1.13k
        key->type = ECC_PRIVATEKEY_ONLY;
5419
1.13k
    }
5420
5421
1.77k
    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
5422
1.77k
            mp_isneg(ecc_get_k(key)) ||
5423
1.77k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
5424
38
        err = ECC_PRIV_KEY_E;
5425
38
    }
5426
5427
1.77k
    if (err == MP_OKAY) {
5428
1.73k
    #ifndef ALT_ECC_SIZE
5429
1.73k
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5430
    #else
5431
        pub->x = (mp_int*)&pub->xyz[0];
5432
        pub->y = (mp_int*)&pub->xyz[1];
5433
        pub->z = (mp_int*)&pub->xyz[2];
5434
        alt_fp_init(pub->x);
5435
        alt_fp_init(pub->y);
5436
        alt_fp_init(pub->z);
5437
    #endif
5438
1.73k
    }
5439
5440
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5441
    defined(HAVE_INTEL_QA)
5442
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5443
        word32 keySz = key->dp->size;
5444
        /* sync private key to raw */
5445
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5446
        if (err == MP_OKAY) {
5447
            err = IntelQaEccPointMul(&key->asyncDev,
5448
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5449
                &curve->Gx->raw, &curve->Gy->raw,
5450
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5451
                key->dp->cofactor);
5452
        }
5453
    }
5454
    else
5455
#endif
5456
1.77k
    { /* BEGIN: Software Crypto */
5457
#ifdef WOLFSSL_HAVE_SP_ECC
5458
    /* Single-Precision Math (optimized for specific curves) */
5459
    if (err != MP_OKAY) {
5460
    }
5461
    else
5462
#ifndef WOLFSSL_SP_NO_256
5463
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5464
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5465
    }
5466
    else
5467
#endif /* WOLFSSL_SP_NO_256 */
5468
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5469
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5470
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5471
    }
5472
    else
5473
#endif
5474
#ifdef WOLFSSL_SP_384
5475
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5476
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5477
    }
5478
    else
5479
#endif
5480
#ifdef WOLFSSL_SP_521
5481
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5482
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5483
    }
5484
    else
5485
#endif
5486
#endif /* WOLFSSL_HAVE_SP_ECC */
5487
5488
#if defined(WOLFSSL_SP_MATH)
5489
        err = WC_KEY_SIZE_E;
5490
#else
5491
1.77k
    if (err == MP_OKAY) {
5492
        /* Multi-Precision Math: compute public curve */
5493
1.73k
        mp_digit mp = 0;
5494
1.73k
        ecc_point* base = NULL;
5495
    #ifdef WOLFSSL_NO_MALLOC
5496
        ecc_point  lcl_base;
5497
        base = &lcl_base;
5498
    #endif
5499
1.73k
        err = wc_ecc_new_point_ex(&base, key->heap);
5500
5501
        /* read in the x/y for this key */
5502
1.73k
        if (err == MP_OKAY)
5503
1.72k
            err = mp_copy(curve->Gx, base->x);
5504
1.73k
        if (err == MP_OKAY)
5505
1.72k
            err = mp_copy(curve->Gy, base->y);
5506
1.73k
        if (err == MP_OKAY)
5507
1.71k
            err = mp_montgomery_setup(curve->prime, &mp);
5508
1.73k
        if (err == MP_OKAY)
5509
1.71k
            err = mp_set(base->z, 1);
5510
5511
        /* make the public key */
5512
1.73k
        if (err == MP_OKAY) {
5513
            /* Map in a separate call as this should be constant time */
5514
1.71k
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5515
1.71k
                                 curve->prime, curve->order, rng, 0, key->heap);
5516
1.71k
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5517
24
               err = MEMORY_E;
5518
24
            }
5519
1.71k
        }
5520
1.73k
        if (err == MP_OKAY) {
5521
            /* Use constant time map if compiled in */
5522
1.67k
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5523
1.67k
        }
5524
5525
1.73k
        wc_ecc_del_point_ex(base, key->heap);
5526
1.73k
    }
5527
1.77k
#endif /* WOLFSSL_SP_MATH */
5528
1.77k
    } /* END: Software Crypto */
5529
5530
1.77k
    if (err != MP_OKAY
5531
    #ifdef WOLFSSL_ASYNC_CRYPT
5532
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5533
    #endif
5534
1.77k
    ) {
5535
        /* clean up if failed */
5536
98
    #ifndef ALT_ECC_SIZE
5537
98
        mp_clear(pub->x);
5538
98
        mp_clear(pub->y);
5539
98
        mp_clear(pub->z);
5540
98
    #endif
5541
98
    }
5542
5543
#else
5544
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5545
    (void)curve;
5546
    err = NOT_COMPILED_IN;
5547
#endif /* HAVE_ECC_MAKE_PUB */
5548
5549
    /* change key state if public part is cached */
5550
1.77k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5551
1.13k
        key->type = ECC_PRIVATEKEY;
5552
1.13k
    }
5553
5554
1.77k
    RESTORE_VECTOR_REGISTERS();
5555
5556
1.77k
    return err;
5557
1.77k
}
5558
5559
5560
/* create the public ECC key from a private key
5561
 *
5562
 * key     an initialized private key to generate public part from
5563
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5564
 *         is cached in key instead.
5565
 *
5566
 *
5567
 * returns MP_OKAY on success
5568
 */
5569
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5570
3.90k
{
5571
3.90k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5572
5573
3.90k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5574
3.90k
}
5575
5576
/* create the public ECC key from a private key - mask timing use random z
5577
 *
5578
 * key     an initialized private key to generate public part from
5579
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5580
 *         is cached in key instead.
5581
 *
5582
 *
5583
 * returns MP_OKAY on success
5584
 */
5585
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5586
1.75k
{
5587
1.75k
    int err = MP_OKAY;
5588
1.75k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5589
5590
1.75k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5591
5592
1.75k
    if (key == NULL) {
5593
0
        return BAD_FUNC_ARG;
5594
0
    }
5595
5596
    /* load curve info */
5597
1.75k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5598
1.75k
    if (err == MP_OKAY) {
5599
1.69k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5600
1.69k
    }
5601
1.75k
    if (err == MP_OKAY) {
5602
1.69k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5603
1.69k
    }
5604
5605
1.75k
    wc_ecc_curve_free(curve);
5606
1.75k
    FREE_CURVE_SPECS();
5607
5608
1.75k
    return err;
5609
1.75k
}
5610
5611
5612
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5613
        int curve_id, int flags)
5614
1.31k
{
5615
1.31k
    int err = 0;
5616
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5617
    !defined(WOLFSSL_ATECC608A)
5618
    const CRYS_ECPKI_Domain_t*  pDomain;
5619
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5620
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5621
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5622
    word32 raw_size = 0;
5623
#endif
5624
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5625
    defined(WC_ECC_NONBLOCK_ONLY)
5626
    ecc_nb_ctx_t nb_ctx;
5627
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5628
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5629
5630
1.31k
    if (key == NULL || rng == NULL) {
5631
0
        return BAD_FUNC_ARG;
5632
0
    }
5633
5634
    /* make sure required variables are reset */
5635
1.31k
    wc_ecc_reset(key);
5636
5637
    #if FIPS_VERSION3_GE(6,0,0)
5638
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5639
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5640
     * keysize here when relying on default selection */
5641
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5642
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5643
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5644
             curve_id == ECC_SECP521R1)) {
5645
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5646
            err = 0;
5647
        } else {
5648
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5649
            err = ECC_CURVE_OID_E;
5650
        }
5651
    }
5652
    if (err == 0) { /* FIPS specific check */
5653
    #endif
5654
1.31k
    err = wc_ecc_set_curve(key, keysize, curve_id);
5655
1.31k
    if (err != 0) {
5656
0
        return err;
5657
0
    }
5658
    #if FIPS_VERSION3_GE(6,0,0)
5659
    } /* end FIPS specific check */
5660
    #endif
5661
1.31k
    key->flags = (byte)flags;
5662
5663
1.31k
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5664
1.31k
    #ifndef WOLF_CRYPTO_CB_FIND
5665
1.31k
    if (key->devId != INVALID_DEVID)
5666
0
    #endif
5667
0
    {
5668
0
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5669
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5670
0
            return err;
5671
        /* fall-through when unavailable */
5672
0
    }
5673
1.31k
#endif
5674
5675
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5676
    return NO_VALID_DEVID;
5677
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5678
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5679
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5680
    #ifdef HAVE_CAVIUM
5681
        /* TODO: Not implemented */
5682
    #elif defined(HAVE_INTEL_QA)
5683
        /* Implemented in ecc_make_pub_ex for the pub calc */
5684
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5685
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5686
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5687
            sw->eccMake.rng = rng;
5688
            sw->eccMake.key = key;
5689
            sw->eccMake.size = keysize;
5690
            sw->eccMake.curve_id = curve_id;
5691
            return WC_PENDING_E;
5692
        }
5693
    #endif
5694
    }
5695
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5696
5697
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
5698
   if (key->dp->id == ECC_SECP256R1) {
5699
       key->type = ECC_PRIVATEKEY;
5700
       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5701
       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
5702
5703
       /* populate key->pubkey */
5704
       if (err == 0
5705
       #ifdef ALT_ECC_SIZE
5706
          && key->pubkey.x
5707
       #endif
5708
       ) {
5709
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5710
                                      ECC_MAX_CRYPTO_HW_SIZE);
5711
       }
5712
       if (err == 0
5713
       #ifdef ALT_ECC_SIZE
5714
          && key->pubkey.y
5715
       #endif
5716
       ) {
5717
           err = mp_read_unsigned_bin(key->pubkey.y,
5718
                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
5719
                                      ECC_MAX_CRYPTO_HW_SIZE);
5720
       }
5721
   }
5722
   else {
5723
      err = NOT_COMPILED_IN;
5724
   }
5725
#elif defined(WOLFSSL_SE050)
5726
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5727
    key->type = ECC_PRIVATEKEY;
5728
#elif defined(WOLFSSL_CRYPTOCELL)
5729
5730
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5731
    raw_size = (word32)(key->dp->size)*2 + 1;
5732
5733
    /* generate first key pair */
5734
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5735
                                wc_rndGenVectFunc,
5736
                                pDomain,
5737
                                &key->ctx.privKey,
5738
                                &key->ctx.pubKey,
5739
                                &tempBuff,
5740
                                &fipsCtx);
5741
5742
    if (err != SA_SILIB_RET_OK){
5743
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5744
        return err;
5745
    }
5746
    key->type = ECC_PRIVATEKEY;
5747
5748
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5749
                                   CRYS_EC_PointUncompressed,
5750
                                   &ucompressed_key[0],
5751
                                   (uint32_t*)&raw_size);
5752
5753
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5754
        err = mp_read_unsigned_bin(key->pubkey.x,
5755
                                   &ucompressed_key[1], key->dp->size);
5756
        if (err == MP_OKAY) {
5757
            err = mp_read_unsigned_bin(key->pubkey.y,
5758
                            &ucompressed_key[1+key->dp->size],key->dp->size);
5759
        }
5760
    }
5761
    raw_size = key->dp->size;
5762
    if (err == MP_OKAY) {
5763
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
5764
                                       ucompressed_key,
5765
                                       (uint32_t*)&raw_size);
5766
    }
5767
5768
    if (err == SA_SILIB_RET_OK) {
5769
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
5770
#ifdef WOLFSSL_ECC_BLIND_K
5771
        if (err == MP_OKAY) {
5772
            err = ecc_blind_k_rng(key, rng);
5773
        }
5774
#endif
5775
    }
5776
5777
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5778
    return silabs_ecc_make_key(key, keysize);
5779
#elif defined(WOLFSSL_KCAPI_ECC)
5780
5781
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
5782
    (void)rng;
5783
5784
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
5785
    if (xil_curve_type[key->dp->id] == 0)
5786
        return ECC_CURVE_OID_E;
5787
5788
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
5789
    if (err)
5790
        return err;
5791
    /* Make sure that private key is max. 521 bits */
5792
    if (key->dp->size == 66)
5793
        key->privKey[65] &= 0x1U;
5794
5795
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
5796
5797
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5798
                                        2 * key->dp->size);
5799
5800
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
5801
                                      xil_curve_type[key->dp->id],
5802
                                      XIL_CAST_U64(key->privKey),
5803
                                      XIL_CAST_U64(key->keyRaw));
5804
    if (err != XST_SUCCESS) {
5805
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
5806
        err = WC_HW_E;
5807
    }
5808
5809
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
5810
                                        2 * key->dp->size);
5811
5812
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
5813
    if (err == 0)
5814
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
5815
                                          xil_curve_type[key->dp->id],
5816
                                          XIL_CAST_U64(key->keyRaw));
5817
#endif
5818
5819
    if (err == 0)
5820
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
5821
                             key->heap);
5822
    if (err == 0)
5823
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
5824
                             key->dp->size, key->heap);
5825
    if (err == 0)
5826
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
5827
                             key->heap);
5828
#ifdef WOLFSSL_ECC_BLIND_K
5829
    if (err == 0)
5830
        err = ecc_blind_k_rng(key, rng);
5831
#endif
5832
    if (err == 0)
5833
        err = mp_set(key->pubkey.z, 1);
5834
    if (err) {
5835
        key->privKey = NULL;
5836
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
5837
        return err;
5838
    }
5839
5840
    key->type = ECC_PRIVATEKEY;
5841
5842
#else
5843
5844
#ifdef WOLFSSL_HAVE_SP_ECC
5845
5846
#ifndef WOLFSSL_SP_NO_256
5847
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5848
    #ifndef WC_ECC_NONBLOCK
5849
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5850
    #else
5851
        if (key->nb_ctx) {
5852
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5853
                                         &key->pubkey, key->heap);
5854
        }
5855
        else {
5856
        #ifdef WC_ECC_NONBLOCK_ONLY
5857
            do { /* perform blocking call to non-blocking function */
5858
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
5859
                                             &key->pubkey, key->heap);
5860
            } while (err == FP_WOULDBLOCK);
5861
        #else
5862
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
5863
        #endif /* WC_ECC_NONBLOCK_ONLY */
5864
        }
5865
    #endif /* !WC_ECC_NONBLOCK */
5866
5867
        if (err == MP_OKAY) {
5868
            key->type = ECC_PRIVATEKEY;
5869
        }
5870
    }
5871
    else
5872
#endif /* !WOLFSSL_SP_NO_256 */
5873
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5874
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5875
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
5876
        if (err == MP_OKAY) {
5877
            key->type = ECC_PRIVATEKEY;
5878
        }
5879
    }
5880
    else
5881
#endif
5882
#ifdef WOLFSSL_SP_384
5883
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5884
    #ifndef WC_ECC_NONBLOCK
5885
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5886
    #else
5887
        if (key->nb_ctx) {
5888
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5889
                                         &key->pubkey, key->heap);
5890
        }
5891
        else {
5892
        #ifdef WC_ECC_NONBLOCK_ONLY
5893
            do { /* perform blocking call to non-blocking function */
5894
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
5895
                                             &key->pubkey, key->heap);
5896
            } while (err == FP_WOULDBLOCK);
5897
        #else
5898
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
5899
        #endif /* WC_ECC_NONBLOCK_ONLY */
5900
        }
5901
    #endif /* !WC_ECC_NONBLOCK */
5902
5903
        if (err == MP_OKAY) {
5904
            key->type = ECC_PRIVATEKEY;
5905
        }
5906
    }
5907
    else
5908
#endif /* WOLFSSL_SP_384 */
5909
#ifdef WOLFSSL_SP_521
5910
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5911
    #ifndef WC_ECC_NONBLOCK
5912
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5913
    #else
5914
        if (key->nb_ctx) {
5915
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
5916
                                         &key->pubkey, key->heap);
5917
        }
5918
        else {
5919
        #ifdef WC_ECC_NONBLOCK_ONLY
5920
            do { /* perform blocking call to non-blocking function */
5921
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
5922
                                             &key->pubkey, key->heap);
5923
            } while (err == FP_WOULDBLOCK);
5924
        #else
5925
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
5926
        #endif /* WC_ECC_NONBLOCK_ONLY */
5927
        }
5928
    #endif /* !WC_ECC_NONBLOCK */
5929
5930
        if (err == MP_OKAY) {
5931
            key->type = ECC_PRIVATEKEY;
5932
        }
5933
    }
5934
    else
5935
#endif /* WOLFSSL_SP_521 */
5936
#endif /* WOLFSSL_HAVE_SP_ECC */
5937
5938
1.31k
   { /* software key gen */
5939
#if defined(WOLFSSL_SP_MATH)
5940
        err = WC_KEY_SIZE_E;
5941
#else
5942
1.31k
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5943
5944
        /* setup the key variables */
5945
1.31k
#ifndef ALT_ECC_SIZE
5946
1.31k
        err = mp_init(key->k);
5947
#else
5948
        err = 0;
5949
        key->k = (mp_int*)key->ka;
5950
        alt_fp_init(key->k);
5951
#endif
5952
5953
        /* load curve info */
5954
1.31k
        if (err == MP_OKAY) {
5955
1.31k
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5956
1.31k
            if (err != MP_OKAY) {
5957
38
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
5958
38
            }
5959
1.31k
        }
5960
5961
1.31k
        if (err == MP_OKAY) {
5962
1.27k
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5963
1.27k
            if (err != MP_OKAY) {
5964
34
                WOLFSSL_MSG("wc_ecc_curve_load failed");
5965
34
            }
5966
1.27k
        }
5967
5968
        /* generate k */
5969
1.31k
        if (err == MP_OKAY) {
5970
1.24k
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
5971
1.24k
            if (err != MP_OKAY) {
5972
65
                WOLFSSL_MSG("wc_ecc_gen_k failed");
5973
65
            }
5974
1.24k
        }
5975
5976
        /* generate public key from k */
5977
1.31k
        if (err == MP_OKAY) {
5978
1.17k
            err = ecc_make_pub_ex(key, curve, NULL, rng);
5979
1.17k
            if (err != MP_OKAY) {
5980
119
                WOLFSSL_MSG("ecc_make_pub_ex failed");
5981
119
            }
5982
1.17k
        }
5983
5984
1.31k
        if (err == MP_OKAY
5985
        #ifdef WOLFSSL_ASYNC_CRYPT
5986
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
5987
        #endif
5988
1.31k
        ) {
5989
1.05k
            key->type = ECC_PRIVATEKEY;
5990
1.05k
        }
5991
256
        else {
5992
            /* cleanup these on failure case only */
5993
256
            mp_forcezero(key->k);
5994
256
        }
5995
5996
        /* cleanup allocations */
5997
1.31k
        wc_ecc_curve_free(curve);
5998
1.31k
        FREE_CURVE_SPECS();
5999
1.31k
#endif /* WOLFSSL_SP_MATH */
6000
1.31k
    }
6001
6002
#ifdef HAVE_WOLF_BIGINT
6003
    if (err == MP_OKAY)
6004
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6005
    if (err == MP_OKAY)
6006
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6007
    if (err == MP_OKAY)
6008
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6009
    if (err == MP_OKAY)
6010
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6011
#endif
6012
6013
#ifdef WOLFSSL_ECC_BLIND_K
6014
    if (err == MP_OKAY)
6015
        err = ecc_blind_k_rng(key, rng);
6016
#endif
6017
6018
1.31k
#endif /* HAVE_ECC_MAKE_PUB */
6019
6020
1.31k
    return err;
6021
1.31k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6022
1.31k
}
6023
6024
6025
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6026
                        int flags)
6027
13.9k
{
6028
13.9k
    int err;
6029
6030
13.9k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
6031
6032
13.9k
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6033
6034
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6035
    !defined(WOLFSSL_KCAPI_ECC)
6036
    if (err == MP_OKAY) {
6037
        err = _ecc_validate_public_key(key, 0, 0);
6038
    }
6039
    if (err == MP_OKAY
6040
#if defined(WOLF_CRYPTO_CB)
6041
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6042
        && key->devId == INVALID_DEVID
6043
#endif
6044
        ) {
6045
        err = _ecc_pairwise_consistency_test(key, rng);
6046
    }
6047
#endif
6048
6049
13.9k
    RESTORE_VECTOR_REGISTERS();
6050
6051
13.9k
    return err;
6052
13.9k
}
6053
6054
WOLFSSL_ABI
6055
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6056
13.9k
{
6057
13.9k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6058
13.9k
}
6059
6060
#ifdef ECC_DUMP_OID
6061
/* Optional dump of encoded OID for adding new curves */
6062
static int mOidDumpDone;
6063
static void wc_ecc_dump_oids(void)
6064
{
6065
    int x;
6066
6067
    if (mOidDumpDone) {
6068
        return;
6069
    }
6070
6071
    /* find matching OID sum (based on encoded value) */
6072
    for (x = 0; ecc_sets[x].size != 0; x++) {
6073
        int i;
6074
        byte* oid;
6075
        word32 oidSz, sum = 0;
6076
6077
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6078
6079
    #ifdef HAVE_OID_ENCODING
6080
        byte oidEnc[ECC_MAX_OID_LEN];
6081
6082
        oid = oidEnc;
6083
        oidSz = ECC_MAX_OID_LEN;
6084
6085
        printf("OID: ");
6086
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6087
            printf("%d.", ecc_sets[x].oid[i]);
6088
        }
6089
        printf("\n");
6090
6091
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6092
    #else
6093
        oid = (byte*)ecc_sets[x].oid;
6094
        oidSz = ecc_sets[x].oidSz;
6095
    #endif
6096
6097
        printf("OID Encoded: ");
6098
        for (i = 0; i < (int)oidSz; i++) {
6099
            printf("0x%02X,", oid[i]);
6100
        }
6101
        printf("\n");
6102
6103
        for (i = 0; i < (int)oidSz; i++) {
6104
            sum += oid[i];
6105
        }
6106
        printf("Sum: %u\n", sum);
6107
6108
        /* validate sum */
6109
        if (ecc_sets[x].oidSum != sum) {
6110
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6111
        }
6112
    }
6113
    mOidDumpDone = 1;
6114
}
6115
#endif /* ECC_DUMP_OID */
6116
6117
6118
WOLFSSL_ABI
6119
ecc_key* wc_ecc_key_new(void* heap)
6120
31.7k
{
6121
31.7k
    int devId = INVALID_DEVID;
6122
31.7k
    ecc_key* key;
6123
6124
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6125
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6126
    devId = WOLFSSL_CAAM_DEVID;
6127
#endif
6128
31.7k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6129
31.7k
    if (key) {
6130
27.7k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6131
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6132
0
            key = NULL;
6133
0
        }
6134
27.7k
    }
6135
6136
31.7k
    return key;
6137
31.7k
}
6138
6139
6140
WOLFSSL_ABI
6141
void wc_ecc_key_free(ecc_key* key)
6142
81.9k
{
6143
81.9k
    if (key) {
6144
27.7k
        void* heap = key->heap;
6145
6146
27.7k
        wc_ecc_free(key);
6147
27.7k
        ForceZero(key, sizeof(ecc_key));
6148
27.7k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6149
27.7k
        (void)heap;
6150
27.7k
    }
6151
81.9k
}
6152
6153
6154
/**
6155
 Make a new ECC key
6156
 rng          An active RNG state
6157
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6158
 key          [out] Destination of the newly created key
6159
 return       MP_OKAY if successful,
6160
 upon error all allocated memory will be freed
6161
 */
6162
WOLFSSL_ABI
6163
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6164
0
{
6165
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6166
0
}
6167
6168
/* Setup dynamic pointers if using normal math for proper freeing */
6169
WOLFSSL_ABI
6170
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6171
52.5k
{
6172
52.5k
    int ret      = 0;
6173
6174
52.5k
    if (key == NULL) {
6175
0
        return BAD_FUNC_ARG;
6176
0
    }
6177
6178
#ifdef ECC_DUMP_OID
6179
    wc_ecc_dump_oids();
6180
#endif
6181
6182
52.5k
    XMEMSET(key, 0, sizeof(ecc_key));
6183
52.5k
    key->state = ECC_STATE_NONE;
6184
6185
52.5k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6186
52.5k
    key->devId = devId;
6187
#else
6188
    (void)devId;
6189
#endif
6190
6191
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6192
    key->slot = ATECC_INVALID_SLOT;
6193
#else
6194
#if defined(WOLFSSL_KCAPI_ECC)
6195
    key->handle = NULL;
6196
#endif
6197
#ifdef ALT_ECC_SIZE
6198
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6199
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6200
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6201
    alt_fp_init(key->pubkey.x);
6202
    alt_fp_init(key->pubkey.y);
6203
    alt_fp_init(key->pubkey.z);
6204
    key->k = (mp_int*)key->ka;
6205
    alt_fp_init(key->k);
6206
#ifdef WOLFSSL_ECC_BLIND_K
6207
    key->kb = (mp_int*)key->kba;
6208
    key->ku = (mp_int*)key->kia;
6209
    alt_fp_init(key->kb);
6210
    alt_fp_init(key->ku);
6211
#endif
6212
#else
6213
52.5k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6214
52.5k
#ifndef WOLFSSL_ECC_BLIND_K
6215
52.5k
                                                                      NULL, NULL
6216
#else
6217
                                                                key->kb, key->ku
6218
#endif
6219
52.5k
                        );
6220
52.5k
    if (ret != MP_OKAY) {
6221
0
        return MEMORY_E;
6222
0
    }
6223
52.5k
#endif /* ALT_ECC_SIZE */
6224
#ifdef WOLFSSL_ECC_BLIND_K
6225
    mp_forcezero(key->kb);
6226
#endif
6227
52.5k
#endif /* WOLFSSL_ATECC508A */
6228
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6229
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6230
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6231
     defined(WOLFSSL_NO_MALLOC)
6232
    ret = mp_init(key->sign_k);
6233
    if (ret != MP_OKAY) {
6234
        return MEMORY_E;
6235
    }
6236
#endif
6237
6238
#ifdef WOLFSSL_HEAP_TEST
6239
    (void)heap;
6240
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6241
#else
6242
52.5k
    key->heap = heap;
6243
52.5k
#endif
6244
6245
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6246
    #ifdef WOLF_CRYPTO_CB
6247
    /* prefer crypto callback */
6248
    if (key->devId != INVALID_DEVID)
6249
    #endif
6250
    {
6251
        /* handle as async */
6252
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6253
                                                        key->heap, devId);
6254
    }
6255
    if (ret != 0)
6256
        return ret;
6257
#endif
6258
6259
#if defined(WOLFSSL_DSP)
6260
    key->handle = -1;
6261
#endif
6262
6263
#ifdef WOLFSSL_SE050
6264
    key->keyId = 0;
6265
    key->keyIdSet = 0;
6266
#endif
6267
6268
#ifdef WOLFSSL_CHECK_MEM_ZERO
6269
    mp_memzero_add("ECC k", key->k);
6270
#ifdef WOLFSSL_ECC_BLIND_K
6271
    mp_memzero_add("ECC kb", key->kb);
6272
    mp_memzero_add("ECC ku", key->ku);
6273
#endif
6274
#endif
6275
6276
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6277
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6278
6279
    if (wc_InitXsecure(&(key->xSec))) {
6280
        WOLFSSL_MSG("Can't initialize Xsecure");
6281
        return WC_HW_E;
6282
    }
6283
#endif
6284
6285
52.5k
    return ret;
6286
52.5k
}
6287
6288
WOLFSSL_ABI
6289
int wc_ecc_init(ecc_key* key)
6290
1.78k
{
6291
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6292
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6293
#else
6294
1.78k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6295
1.78k
#endif
6296
1.78k
}
6297
6298
#ifdef WOLF_PRIVATE_KEY_ID
6299
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6300
                   int devId)
6301
0
{
6302
0
    int ret = 0;
6303
#ifdef WOLFSSL_SE050
6304
    /* SE050 TLS users store a word32 at id, need to cast back */
6305
    word32* keyPtr = NULL;
6306
#endif
6307
6308
0
    if (key == NULL)
6309
0
        ret = BAD_FUNC_ARG;
6310
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6311
0
        ret = BUFFER_E;
6312
0
    if (ret == 0)
6313
0
        ret = wc_ecc_init_ex(key, heap, devId);
6314
0
    if (ret == 0 && id != NULL && len != 0) {
6315
0
        XMEMCPY(key->id, id, (size_t)len);
6316
0
        key->idLen = len;
6317
    #ifdef WOLFSSL_SE050
6318
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6319
        if (len == (int)sizeof(word32)) {
6320
            keyPtr = (word32*)key->id;
6321
            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
6322
        }
6323
    #endif
6324
0
    }
6325
6326
0
    return ret;
6327
0
}
6328
6329
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6330
0
{
6331
0
    int ret = 0;
6332
0
    int labelLen = 0;
6333
6334
0
    if (key == NULL || label == NULL)
6335
0
        ret = BAD_FUNC_ARG;
6336
0
    if (ret == 0) {
6337
0
        labelLen = (int)XSTRLEN(label);
6338
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6339
0
            ret = BUFFER_E;
6340
0
    }
6341
0
    if (ret == 0)
6342
0
        ret = wc_ecc_init_ex(key, heap, devId);
6343
0
    if (ret == 0) {
6344
0
        XMEMCPY(key->label, label, (size_t)labelLen);
6345
0
        key->labelLen = labelLen;
6346
0
    }
6347
6348
0
    return ret;
6349
0
}
6350
#endif /* WOLF_PRIVATE_KEY_ID */
6351
6352
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6353
389
{
6354
389
    if (key == NULL) {
6355
0
        return BAD_FUNC_ARG;
6356
0
    }
6357
389
    key->flags |= flags;
6358
389
    return 0;
6359
389
}
6360
6361
6362
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6363
{
6364
    int err = MP_OKAY;
6365
    int orderBits;
6366
    DECLARE_CURVE_SPECS(1);
6367
6368
    ALLOC_CURVE_SPECS(1, err);
6369
    if (err == MP_OKAY) {
6370
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6371
    }
6372
6373
    if (err != 0) {
6374
       FREE_CURVE_SPECS();
6375
       return err;
6376
    }
6377
    orderBits = mp_count_bits(curve->order);
6378
6379
    wc_ecc_curve_free(curve);
6380
    FREE_CURVE_SPECS();
6381
    return orderBits;
6382
}
6383
6384
#ifdef HAVE_ECC_SIGN
6385
6386
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6387
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6388
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6389
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6390
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6391
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6392
    ecc_key* key)
6393
{
6394
    int err;
6395
#ifdef PLUTON_CRYPTO_ECC
6396
    if (key->devId != INVALID_DEVID) /* use hardware */
6397
#endif
6398
    {
6399
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6400
        !defined(WOLFSSL_ATECC608A)
6401
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6402
        word32 raw_sig_size = *outlen;
6403
        word32 msgLenInBytes = inlen;
6404
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6405
    #endif
6406
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6407
#ifdef WOLFSSL_SMALL_STACK
6408
        byte* K = NULL;
6409
        byte* incopy = NULL;
6410
#else
6411
        byte K[MAX_ECC_BYTES] = {0};
6412
        byte incopy[MAX_ECC_BYTES] = {0};
6413
#endif
6414
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6415
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6416
        word32 Ksize;
6417
#endif
6418
#endif
6419
        word32 keysize = (word32)key->dp->size;
6420
    #ifdef PLUTON_CRYPTO_ECC
6421
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6422
    #endif
6423
6424
    #ifndef WOLFSSL_KCAPI_ECC
6425
        /* Check args */
6426
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6427
            return ECC_BAD_ARG_E;
6428
        }
6429
    #endif
6430
6431
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
6432
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6433
        err = atmel_ecc_sign(key->slot, in, out);
6434
        if (err != 0) {
6435
           return err;
6436
        }
6437
    #elif defined(PLUTON_CRYPTO_ECC)
6438
        {
6439
            /* if the input is larger than curve order, we must truncate */
6440
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6441
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6442
            }
6443
6444
            /* perform ECC sign */
6445
            word32 raw_sig_size = *outlen;
6446
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6447
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6448
               return BAD_COND_E;
6449
            }
6450
        }
6451
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6452
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6453
        if (err != 0) {
6454
               return WC_HW_E;
6455
        }
6456
    #elif defined(WOLFSSL_CRYPTOCELL)
6457
        /* truncate if hash is longer than key size */
6458
        if (msgLenInBytes > keysize) {
6459
            msgLenInBytes = keysize;
6460
        }
6461
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6462
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6463
            (void)cc310_hashModeECC(keysize);
6464
            /* Ignoring returned value */
6465
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6466
6467
        }
6468
6469
        /* create signature from an input buffer using a private key*/
6470
        err = CRYS_ECDSA_Sign(&wc_rndState,
6471
                               wc_rndGenVectFunc,
6472
                               &sigCtxTemp,
6473
                               &key->ctx.privKey,
6474
                               hash_mode,
6475
                               (byte*)in,
6476
                               msgLenInBytes,
6477
                               out,
6478
                               (uint32_t*)&raw_sig_size);
6479
6480
        if (err != SA_SILIB_RET_OK){
6481
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6482
            return err;
6483
        }
6484
    #elif defined(WOLFSSL_KCAPI_ECC)
6485
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6486
        if (err != MP_OKAY) {
6487
            return err;
6488
        }
6489
        (void)rng;
6490
    #elif defined(WOLFSSL_SE050)
6491
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6492
        if (err != MP_OKAY) {
6493
            return err;
6494
        }
6495
        (void)rng;
6496
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6497
6498
#ifdef WOLFSSL_SMALL_STACK
6499
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6500
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6501
        if (K == NULL || incopy == NULL) {
6502
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6503
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6504
            return MEMORY_E;
6505
        }
6506
#else
6507
        if (inlen > sizeof(incopy))
6508
            return ECC_BAD_ARG_E;
6509
#endif
6510
6511
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6512
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6513
        err = deterministic_sign_helper(in, inlen, key);
6514
        if (err)
6515
            return err;
6516
        Ksize = mp_unsigned_bin_size(key->sign_k);
6517
        if (Ksize > keysize) {
6518
            err = BUFFER_E;
6519
            goto error_out;
6520
        }
6521
        err = mp_to_unsigned_bin(key->sign_k, K);
6522
        if (err)
6523
            goto error_out;
6524
        mp_reverse(K, Ksize);
6525
#else
6526
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6527
        if (err)
6528
            goto error_out;
6529
        /* Make sure that K is max. 521 bits */
6530
        if (keysize == 66)
6531
            K[65] &= 0x1;
6532
#endif
6533
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6534
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6535
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6536
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6537
6538
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6539
6540
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6541
                                           xil_curve_type[key->dp->id],
6542
                                           XIL_CAST_U64(incopy), keysize,
6543
                                           XIL_CAST_U64(key->privKey),
6544
                                           XIL_CAST_U64(K),
6545
                                           XIL_CAST_U64(out));
6546
        if (err) {
6547
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6548
            err = WC_HW_E;
6549
        }
6550
6551
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6552
        mp_reverse(&out[0], keysize);
6553
        mp_reverse(&out[keysize], keysize);
6554
6555
error_out:
6556
        ForceZero(K, MAX_ECC_BYTES);
6557
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6558
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6559
        if (err) {
6560
            ForceZero(out, keysize * 2);
6561
            return err;
6562
        }
6563
    #endif /* HW-specific #if-#elif chain */
6564
6565
    #ifndef WOLFSSL_SE050
6566
        /* Load R and S, SE050 does this in port layer */
6567
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6568
        if (err != MP_OKAY) {
6569
            return err;
6570
        }
6571
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6572
        if (err != MP_OKAY) {
6573
            return err;
6574
        }
6575
    #endif
6576
6577
        /* Check for zeros */
6578
        if (mp_iszero(r) || mp_iszero(s)) {
6579
            return MP_ZERO_E;
6580
        }
6581
    }
6582
#ifdef PLUTON_CRYPTO_ECC
6583
    else {
6584
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6585
    }
6586
#endif
6587
    (void)rng;
6588
6589
    return err;
6590
}
6591
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6592
6593
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6594
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6595
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6596
{
6597
    int err;
6598
    mp_int *r = NULL, *s = NULL;
6599
6600
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6601
                                                                rng == NULL) {
6602
        return ECC_BAD_ARG_E;
6603
    }
6604
6605
    err = wc_ecc_alloc_async(key);
6606
    if (err != 0) {
6607
        return err;
6608
    }
6609
    r = key->r;
6610
    s = key->s;
6611
6612
    switch (key->state) {
6613
        case ECC_STATE_NONE:
6614
        case ECC_STATE_SIGN_DO:
6615
            key->state = ECC_STATE_SIGN_DO;
6616
6617
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6618
                break;
6619
            }
6620
6621
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6622
            if (err < 0) {
6623
                break;
6624
            }
6625
6626
            FALL_THROUGH;
6627
6628
        case ECC_STATE_SIGN_ENCODE:
6629
            key->state = ECC_STATE_SIGN_ENCODE;
6630
6631
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6632
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6633
                    DECLARE_CURVE_SPECS(1);
6634
                    ALLOC_CURVE_SPECS(1, err);
6635
                    if (err != MP_OKAY) {
6636
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6637
                        break;
6638
                    }
6639
6640
                    /* get curve order */
6641
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6642
                #endif
6643
6644
                #ifdef HAVE_CAVIUM_V
6645
                    /* Nitrox requires r and s in sep buffer, so split it */
6646
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6647
                #endif
6648
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6649
                    /* only do this if not software, since it overwrites result */
6650
                    wc_bigint_to_mp(&r->raw, r);
6651
                    wc_bigint_to_mp(&s->raw, s);
6652
6653
                /* if using a curve with cofactor != 1 then reduce by mod order */
6654
                #ifdef HAVE_ECC_CDH
6655
                    /* if r is not less than order than reduce */
6656
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6657
                        err = mp_mod(r, curve->order, r);
6658
                    }
6659
                    wc_ecc_curve_free(curve);
6660
                    FREE_CURVE_SPECS();
6661
                #endif
6662
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6663
            }
6664
6665
            /* encoded with DSA header */
6666
            if (err == 0) {
6667
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6668
            }
6669
6670
            /* done with R/S */
6671
            mp_clear(r);
6672
            mp_clear(s);
6673
            break;
6674
6675
        default:
6676
            err = BAD_STATE_E;
6677
            break;
6678
    }
6679
6680
    /* if async pending then return and skip done cleanup below */
6681
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6682
        key->state++;
6683
        return err;
6684
    }
6685
6686
    /* cleanup */
6687
    wc_ecc_free_async(key);
6688
    key->state = ECC_STATE_NONE;
6689
6690
    return err;
6691
}
6692
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6693
6694
/**
6695
 Sign a message digest
6696
 in        The message digest to sign
6697
 inlen     The length of the digest
6698
 out       [out] The destination for the signature
6699
 outlen    [in/out] The max size and resulting size of the signature
6700
 key       A private ECC key
6701
 return    MP_OKAY if successful
6702
 */
6703
WOLFSSL_ABI
6704
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6705
                     WC_RNG* rng, ecc_key* key)
6706
395
{
6707
395
    int err;
6708
395
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6709
395
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6710
395
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6711
395
#endif
6712
#ifdef NO_ASN
6713
    word32 keySz;
6714
#endif
6715
6716
395
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
6717
40
        return ECC_BAD_ARG_E;
6718
40
    }
6719
355
    if (inlen > WC_MAX_DIGEST_SIZE) {
6720
11
        return BAD_LENGTH_E;
6721
11
    }
6722
6723
344
#ifdef WOLF_CRYPTO_CB
6724
344
    #ifndef WOLF_CRYPTO_CB_FIND
6725
344
    if (key->devId != INVALID_DEVID)
6726
0
    #endif
6727
0
    {
6728
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
6729
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6730
0
            return err;
6731
        /* fall-through when unavailable */
6732
0
    }
6733
344
#endif
6734
6735
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6736
    (void)rng;
6737
    (void)inlen;
6738
    (void)s;
6739
    (void)r;
6740
    (void)err;
6741
    return NO_VALID_DEVID;
6742
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6743
344
    if (rng == NULL) {
6744
0
        WOLFSSL_MSG("ECC sign RNG missing");
6745
0
        return ECC_BAD_ARG_E;
6746
0
    }
6747
6748
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6749
    /* handle async cases */
6750
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
6751
#else
6752
6753
344
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6754
    #ifdef MP_INT_SIZE_CHECK_NULL
6755
    if (r == NULL)
6756
        return MEMORY_E;
6757
    #endif
6758
344
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6759
    #ifdef MP_INT_SIZE_CHECK_NULL
6760
    if (s == NULL) {
6761
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6762
        return MEMORY_E;
6763
    }
6764
    #endif
6765
6766
344
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6767
344
    if (err != 0) {
6768
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6769
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6770
0
        return err;
6771
0
    }
6772
344
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6773
344
    if (err != 0) {
6774
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6775
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6776
0
        return err;
6777
0
    }
6778
6779
/* hardware crypto */
6780
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6781
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6782
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6783
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6784
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
6785
#else
6786
344
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6787
344
#endif
6788
344
    if (err < 0) {
6789
3
        mp_clear(r);
6790
3
        mp_clear(s);
6791
3
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6792
3
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6793
3
        return err;
6794
3
    }
6795
6796
341
#ifndef NO_ASN
6797
    /* encoded with DSA header */
6798
341
    err = StoreECC_DSA_Sig(out, outlen, r, s);
6799
#else
6800
    /* No support for DSA ASN.1 header.
6801
     * Signature will be r+s directly. */
6802
    keySz = 0;
6803
    if (key->dp != NULL) {
6804
        keySz = (word32)key->dp->size;
6805
    }
6806
    if (keySz <= 0) {
6807
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
6808
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
6809
    }
6810
    *outlen = keySz * 2;
6811
6812
    /* Export signature into r,s */
6813
    mp_to_unsigned_bin_len(r, out, keySz);
6814
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
6815
#endif /* !NO_ASN */
6816
6817
    /* cleanup */
6818
341
    mp_clear(r);
6819
341
    mp_clear(s);
6820
6821
341
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
6822
341
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
6823
341
#endif /* WOLFSSL_ASYNC_CRYPT */
6824
341
    return err;
6825
344
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6826
344
}
6827
6828
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6829
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6830
/* returns MP_OKAY on success */
6831
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
6832
{
6833
    int err = MP_OKAY;
6834
    DECLARE_CURVE_SPECS(1);
6835
    ALLOC_CURVE_SPECS(1, err);
6836
6837
    /* get curve order */
6838
    if (err == MP_OKAY) {
6839
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6840
    }
6841
6842
    if (err == MP_OKAY) {
6843
    #ifndef WOLFSSL_NO_MALLOC
6844
        /* if key->sign_k is NULL then create a buffer for the mp_int
6845
         * if not NULL then assume the user correctly set deterministic flag and
6846
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
6847
        if (key->sign_k == NULL) {
6848
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
6849
                                                            DYNAMIC_TYPE_ECC);
6850
            if (key->sign_k != NULL) {
6851
                err = mp_init(key->sign_k);
6852
                if (err != MP_OKAY) {
6853
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6854
                    key->sign_k = NULL;
6855
                }
6856
            }
6857
        }
6858
        if (key->sign_k != NULL) {
6859
            if (wc_ecc_gen_deterministic_k(in, inlen,
6860
                        key->hashType, ecc_get_k(key), key->sign_k,
6861
                        curve->order, key->heap) != 0) {
6862
                mp_free(key->sign_k);
6863
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6864
                key->sign_k = NULL;
6865
                err = ECC_PRIV_KEY_E;
6866
            }
6867
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6868
            else {
6869
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
6870
            }
6871
        #endif
6872
        }
6873
        else {
6874
            err = MEMORY_E;
6875
        }
6876
    #else
6877
        key->sign_k_set = 0;
6878
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
6879
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
6880
            err = ECC_PRIV_KEY_E;
6881
        }
6882
        else {
6883
            key->sign_k_set = 1;
6884
        }
6885
    #endif
6886
    }
6887
6888
    wc_ecc_curve_free(curve);
6889
    FREE_CURVE_SPECS();
6890
    return err;
6891
}
6892
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
6893
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
6894
6895
#if defined(WOLFSSL_STM32_PKA)
6896
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
6897
                     ecc_key* key, mp_int *r, mp_int *s)
6898
{
6899
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6900
}
6901
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
6902
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
6903
#ifndef WOLFSSL_SP_MATH
6904
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
6905
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
6906
                            mp_int* s)
6907
344
{
6908
344
    int err = MP_OKAY;
6909
344
    int loop_check = 0;
6910
344
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
6911
6912
344
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
6913
#ifdef MP_INT_SIZE_CHECK_NULL
6914
    if (b == NULL)
6915
        err = MEMORY_E;
6916
#endif
6917
6918
344
    if (err == MP_OKAY) {
6919
344
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
6920
344
    }
6921
6922
344
#ifdef WOLFSSL_CUSTOM_CURVES
6923
    /* if custom curve, apply params to pubkey */
6924
344
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
6925
0
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
6926
0
    }
6927
344
#endif
6928
6929
344
    if (err == MP_OKAY) {
6930
        /* Generate blinding value - non-zero value. */
6931
344
        do {
6932
344
            if (++loop_check > 64) {
6933
0
                 err = RNG_FAILURE_E;
6934
0
                 break;
6935
0
            }
6936
6937
344
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
6938
344
        }
6939
344
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
6940
344
        loop_check = 0;
6941
344
    }
6942
#ifdef WOLFSSL_CHECK_MEM_ZERO
6943
    if (err == MP_OKAY) {
6944
        mp_memzero_add("ecc_sign_hash_sw b", b);
6945
    }
6946
#endif
6947
6948
347
    for (; err == MP_OKAY;) {
6949
347
        if (++loop_check > 64) {
6950
3
             err = RNG_FAILURE_E;
6951
3
             break;
6952
3
        }
6953
344
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6954
344
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6955
344
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6956
344
#ifndef WOLFSSL_NO_MALLOC
6957
344
        if (key->sign_k != NULL)
6958
#else
6959
        if (key->sign_k_set)
6960
#endif
6961
149
        {
6962
149
            if (loop_check > 1) {
6963
0
               err = RNG_FAILURE_E;
6964
0
               break;
6965
0
            }
6966
6967
            /* use provided sign_k */
6968
149
            err = mp_copy(key->sign_k, pubkey->k);
6969
149
            if (err != MP_OKAY) break;
6970
6971
            /* free sign_k, so only used once */
6972
149
            mp_forcezero(key->sign_k);
6973
149
#ifndef WOLFSSL_NO_MALLOC
6974
149
            mp_free(key->sign_k);
6975
149
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
6976
149
            key->sign_k = NULL;
6977
#else
6978
            key->sign_k_set = 0;
6979
#endif
6980
149
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
6981
149
            loop_check = 64;
6982
149
    #endif
6983
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6984
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6985
            if (key->deterministic == 1) {
6986
                /* sign_k generated earlier in function for SP calls.
6987
                 * Only go through the loop once and fail if error */
6988
                loop_check = 64;
6989
            }
6990
    #endif
6991
6992
            /* compute public key based on provided "k" */
6993
149
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
6994
149
        }
6995
195
        else
6996
195
#endif
6997
195
        {
6998
195
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
6999
195
                    WC_ECC_FLAG_NONE);
7000
195
        }
7001
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7002
        if (err == MP_OKAY) {
7003
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7004
        }
7005
    #endif
7006
    #ifdef WOLFSSL_ASYNC_CRYPT
7007
        /* for async do blocking wait here */
7008
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7009
    #endif
7010
344
        if (err != MP_OKAY) break;
7011
7012
        /* find r = x1 mod n */
7013
344
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7014
344
        if (err != MP_OKAY) break;
7015
7016
344
        if (mp_iszero(r) == MP_NO) {
7017
344
            mp_int* kp = ecc_get_k(pubkey);
7018
344
            mp_int* ep = kp;
7019
344
            mp_int* x  = ecc_get_k(key);
7020
7021
            /* Blind after getting. */
7022
344
            ecc_blind_k(key, b);
7023
7024
            /* find s = (e + xr)/k
7025
                      = b.(e/k.b + x.r/k.b) */
7026
7027
            /* k' = k.b */
7028
344
            err = mp_mulmod(kp, b, curve->order, kp);
7029
344
            if (err != MP_OKAY) break;
7030
7031
            /* k' = 1/k.b
7032
                  = 1/k' */
7033
344
            err = mp_invmod(kp, curve->order, kp);
7034
344
            if (err != MP_OKAY) break;
7035
7036
            /* s = x.r */
7037
344
            err = mp_mulmod(x, r, curve->order, s);
7038
344
            if (err != MP_OKAY) break;
7039
7040
            /* s = x.r/k.b
7041
                 = k'.s */
7042
344
            err = mp_mulmod(kp, s, curve->order, s);
7043
344
            if (err != MP_OKAY) break;
7044
7045
            /* e' = e/k.b
7046
                  = e.k' */
7047
344
            err = mp_mulmod(kp, e, curve->order, ep);
7048
344
            if (err != MP_OKAY) break;
7049
7050
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7051
                 = e' + s */
7052
344
            err = mp_addmod_ct(ep, s, curve->order, s);
7053
344
            if (err != MP_OKAY) break;
7054
7055
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7056
                 = b.s */
7057
344
            err = mp_mulmod(s, b, curve->order, s);
7058
344
            if (err != MP_OKAY) break;
7059
7060
344
            if (mp_iszero(s) == MP_NO) {
7061
                /* sign successful */
7062
341
                break;
7063
341
            }
7064
344
         }
7065
3
     #ifndef ALT_ECC_SIZE
7066
3
         mp_clear(pubkey->pubkey.x);
7067
3
         mp_clear(pubkey->pubkey.y);
7068
3
         mp_clear(pubkey->pubkey.z);
7069
3
     #endif
7070
3
         mp_forcezero(pubkey->k);
7071
3
    }
7072
344
    mp_forcezero(b);
7073
344
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7074
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7075
    mp_memzero_check(b);
7076
#endif
7077
7078
344
    return err;
7079
344
}
7080
#endif
7081
7082
#ifdef WOLFSSL_HAVE_SP_ECC
7083
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7084
    ecc_key* key, mp_int *r, mp_int *s)
7085
{
7086
    if (key->idx != ECC_CUSTOM_IDX) {
7087
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7088
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7089
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7090
        mp_int* sign_k = key->sign_k;
7091
    #else
7092
        mp_int* sign_k = NULL;
7093
    #endif
7094
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7095
        /* perform blocking call to non-blocking function */
7096
        ecc_nb_ctx_t nb_ctx;
7097
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7098
    #endif
7099
    #ifndef WOLFSSL_SP_NO_256
7100
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7101
        #ifdef WC_ECC_NONBLOCK
7102
            #ifdef WC_ECC_NONBLOCK_ONLY
7103
            int err;
7104
            #endif
7105
            if (key->nb_ctx) {
7106
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7107
                    ecc_get_k(key), r, s, sign_k, key->heap);
7108
            }
7109
            #ifdef WC_ECC_NONBLOCK_ONLY
7110
            do { /* perform blocking call to non-blocking function */
7111
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7112
                    ecc_get_k(key), r, s, sign_k, key->heap);
7113
            } while (err == FP_WOULDBLOCK);
7114
            return err;
7115
            #endif
7116
        #endif /* WC_ECC_NONBLOCK */
7117
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7118
            {
7119
                int ret;
7120
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7121
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7122
                                      sign_k, key->heap);
7123
                RESTORE_VECTOR_REGISTERS();
7124
                return ret;
7125
            }
7126
        #endif
7127
        }
7128
    #endif
7129
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7130
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7131
            int ret;
7132
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
7133
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7134
                                      sign_k, key->heap);
7135
            RESTORE_VECTOR_REGISTERS();
7136
            return ret;
7137
        }
7138
    #endif
7139
    #ifdef WOLFSSL_SP_384
7140
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7141
        #ifdef WC_ECC_NONBLOCK
7142
            #ifdef WC_ECC_NONBLOCK_ONLY
7143
            int err;
7144
            #endif
7145
            if (key->nb_ctx) {
7146
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7147
                    ecc_get_k(key), r, s, sign_k, key->heap);
7148
            }
7149
            #ifdef WC_ECC_NONBLOCK_ONLY
7150
            do { /* perform blocking call to non-blocking function */
7151
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7152
                    ecc_get_k(key), r, s, sign_k, key->heap);
7153
            } while (err == FP_WOULDBLOCK);
7154
            return err;
7155
            #endif
7156
        #endif /* WC_ECC_NONBLOCK */
7157
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7158
            {
7159
                int ret;
7160
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7161
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7162
                                      sign_k, key->heap);
7163
                RESTORE_VECTOR_REGISTERS();
7164
                return ret;
7165
            }
7166
        #endif
7167
        }
7168
    #endif
7169
    #ifdef WOLFSSL_SP_521
7170
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7171
        #ifdef WC_ECC_NONBLOCK
7172
            #ifdef WC_ECC_NONBLOCK_ONLY
7173
            int err;
7174
            #endif
7175
            if (key->nb_ctx) {
7176
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7177
                    ecc_get_k(key), r, s, sign_k, key->heap);
7178
            }
7179
            #ifdef WC_ECC_NONBLOCK_ONLY
7180
            do { /* perform blocking call to non-blocking function */
7181
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7182
                    ecc_get_k(key), r, s, sign_k, key->heap);
7183
            } while (err == FP_WOULDBLOCK);
7184
            return err;
7185
            #endif
7186
        #endif /* WC_ECC_NONBLOCK */
7187
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7188
            {
7189
                int ret;
7190
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
7191
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7192
                                      sign_k, key->heap);
7193
                RESTORE_VECTOR_REGISTERS();
7194
                return ret;
7195
            }
7196
        #endif
7197
        }
7198
    #endif
7199
        (void)sign_k;
7200
    }
7201
7202
    /* SP doesn't support curve. */
7203
    return WC_KEY_SIZE_E;
7204
}
7205
#endif
7206
7207
/**
7208
  Sign a message digest
7209
  in        The message digest to sign
7210
  inlen     The length of the digest
7211
  key       A private ECC key
7212
  r         [out] The destination for r component of the signature
7213
  s         [out] The destination for s component of the signature
7214
  return    MP_OKAY if successful
7215
*/
7216
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7217
                     ecc_key* key, mp_int *r, mp_int *s)
7218
344
{
7219
344
   int    err = 0;
7220
344
#if !defined(WOLFSSL_SP_MATH)
7221
344
   mp_int* e;
7222
344
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7223
344
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7224
344
#endif
7225
7226
344
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7227
344
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7228
344
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7229
344
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7230
344
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7231
344
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7232
#else
7233
   DECLARE_CURVE_SPECS(1);
7234
#endif
7235
344
#endif /* !WOLFSSL_SP_MATH */
7236
7237
344
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7238
0
       return ECC_BAD_ARG_E;
7239
0
   }
7240
7241
   /* is this a private key? */
7242
344
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7243
0
      return ECC_BAD_ARG_E;
7244
0
   }
7245
7246
   /* is the IDX valid ?  */
7247
344
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7248
0
      return ECC_BAD_ARG_E;
7249
0
   }
7250
7251
#if defined(WOLFSSL_SP_MATH)
7252
    if (key->idx == ECC_CUSTOM_IDX || (1
7253
    #ifndef WOLFSSL_SP_NO_256
7254
         && ecc_sets[key->idx].id != ECC_SECP256R1
7255
    #endif
7256
    #ifdef WOLFSSL_SP_SM2
7257
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7258
    #endif
7259
    #ifdef WOLFSSL_SP_384
7260
         && ecc_sets[key->idx].id != ECC_SECP384R1
7261
    #endif
7262
    #ifdef WOLFSSL_SP_521
7263
         && ecc_sets[key->idx].id != ECC_SECP521R1
7264
    #endif
7265
        )) {
7266
        return WC_KEY_SIZE_E;
7267
    }
7268
#endif
7269
7270
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7271
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7272
    /* generate deterministic 'k' value to be used either with SP or normal */
7273
    if (key->deterministic == 1) {
7274
        if (deterministic_sign_helper(in, inlen, key)) {
7275
            WOLFSSL_MSG("Error generating deterministic k to sign");
7276
            return ECC_PRIV_KEY_E;
7277
        }
7278
    }
7279
#endif
7280
7281
7282
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7283
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7284
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7285
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7286
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7287
            sw->eccSign.in = in;
7288
            sw->eccSign.inSz = inlen;
7289
            sw->eccSign.rng = rng;
7290
            sw->eccSign.key = key;
7291
            sw->eccSign.r = r;
7292
            sw->eccSign.s = s;
7293
            return WC_PENDING_E;
7294
        }
7295
    }
7296
#endif
7297
7298
#if defined(WOLFSSL_HAVE_SP_ECC)
7299
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7300
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7301
       return err;
7302
   }
7303
#else
7304
344
   (void)inlen;
7305
344
#endif
7306
7307
344
#if !defined(WOLFSSL_SP_MATH)
7308
7309
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7310
   err = wc_ecc_alloc_mpint(key, &key->e);
7311
   if (err != 0) {
7312
      return err;
7313
   }
7314
   e = key->e;
7315
#else
7316
344
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7317
#ifdef MP_INT_SIZE_CHECK_NULL
7318
   if (e_lcl == NULL) {
7319
      return MEMORY_E;
7320
   }
7321
#endif
7322
344
   e = e_lcl;
7323
344
#endif
7324
7325
   /* get the hash and load it as a bignum into 'e' */
7326
   /* init the bignums */
7327
344
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7328
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7329
0
      return err;
7330
0
   }
7331
7332
   /* load curve info */
7333
344
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7334
344
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7335
344
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7336
344
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7337
344
    if (err == MP_OKAY)
7338
344
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7339
#else
7340
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7341
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7342
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7343
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7344
        if (err == MP_OKAY)
7345
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7346
    }
7347
    else
7348
    #endif
7349
    {
7350
        ALLOC_CURVE_SPECS(1, err);
7351
        if (err == MP_OKAY)
7352
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7353
    }
7354
#endif
7355
7356
   /* load digest into e */
7357
344
   if (err == MP_OKAY) {
7358
       /* we may need to truncate if hash is longer than key size */
7359
344
       word32 orderBits = (word32)mp_count_bits(curve->order);
7360
7361
       /* truncate down to byte size, may be all that's needed */
7362
344
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7363
31
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7364
344
       err = mp_read_unsigned_bin(e, in, inlen);
7365
7366
       /* may still need bit truncation too */
7367
344
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7368
28
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7369
344
   }
7370
7371
   /* make up a key and export the public copy */
7372
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7373
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7374
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7375
   #ifdef HAVE_CAVIUM_V
7376
       if (NitroxEccIsCurveSupported(key))
7377
   #endif
7378
       {
7379
           word32 keySz = key->dp->size;
7380
           mp_int* k;
7381
       #ifdef HAVE_CAVIUM_V
7382
           err = wc_ecc_alloc_mpint(key, &key->signK);
7383
           if (err != 0)
7384
              return err;
7385
           k = key->signK;
7386
       #else
7387
           mp_int k_lcl;
7388
           k = &k_lcl;
7389
       #endif
7390
7391
           err = mp_init(k);
7392
7393
            /* make sure r and s are allocated */
7394
       #ifdef HAVE_CAVIUM_V
7395
           /* Nitrox V needs single buffer for R and S */
7396
           if (err == MP_OKAY)
7397
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7398
           /* Nitrox V only needs Prime and Order */
7399
           if (err == MP_OKAY)
7400
               err = wc_ecc_curve_load(key->dp, &curve,
7401
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7402
       #else
7403
           if (err == MP_OKAY)
7404
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7405
           if (err == MP_OKAY)
7406
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7407
       #endif
7408
           if (err == MP_OKAY)
7409
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7410
7411
           /* load e and k */
7412
           if (err == MP_OKAY)
7413
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7414
           if (err == MP_OKAY)
7415
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7416
                  keySz);
7417
           if (err == MP_OKAY)
7418
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7419
           if (err == MP_OKAY)
7420
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7421
7422
       #ifdef HAVE_CAVIUM_V
7423
           if (err == MP_OKAY)
7424
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7425
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7426
                  &curve->order->raw);
7427
       #else
7428
           if (err == MP_OKAY)
7429
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7430
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7431
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7432
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7433
       #endif
7434
7435
       #ifndef HAVE_CAVIUM_V
7436
           mp_clear(e);
7437
           mp_clear(k);
7438
       #endif
7439
           wc_ecc_curve_free(curve);
7440
           FREE_CURVE_SPECS();
7441
7442
           return err;
7443
       }
7444
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7445
   }
7446
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7447
7448
344
   if (err == MP_OKAY) {
7449
344
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7450
7451
344
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7452
344
           err=MEMORY_E);
7453
344
       if (WC_VAR_OK(pubkey))
7454
344
       {
7455
       /* don't use async for key, since we don't support async return here */
7456
344
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7457
344
           if (err == MP_OKAY) {
7458
344
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7459
344
              wc_ecc_free(pubkey);
7460
344
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7461
344
           }
7462
344
       }
7463
344
   }
7464
7465
344
   mp_clear(e);
7466
344
   wc_ecc_curve_free(curve);
7467
344
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7468
344
   FREE_CURVE_SPECS();
7469
344
#endif /* !WOLFSSL_SP_MATH */
7470
7471
344
   return err;
7472
344
}
7473
7474
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7475
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7476
/* helper function to do HMAC operations
7477
 * returns 0 on success and updates "out" buffer
7478
 */
7479
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7480
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7481
        byte* out, enum wc_HashType hashType, void* heap)
7482
{
7483
    Hmac hmac;
7484
    int  ret, init;
7485
7486
    ret = init = wc_HmacInit(&hmac, heap, INVALID_DEVID);
7487
    if (ret == 0)
7488
        ret = wc_HmacSetKey(&hmac, (int)hashType, K, KSz);
7489
7490
    if (ret == 0)
7491
        ret = wc_HmacUpdate(&hmac, V, VSz);
7492
7493
    if (ret == 0 && oct != NULL)
7494
        ret = wc_HmacUpdate(&hmac, oct, 1);
7495
7496
    if (ret == 0)
7497
        ret = wc_HmacUpdate(&hmac, x, xSz);
7498
7499
    if (ret == 0)
7500
        ret = wc_HmacUpdate(&hmac, h1, h1Sz);
7501
7502
    if (ret == 0)
7503
        ret = wc_HmacFinal(&hmac, out);
7504
7505
    if (init == 0)
7506
        wc_HmacFree(&hmac);
7507
7508
    return ret;
7509
}
7510
7511
7512
/* Generates a deterministic key based of the message using RFC6979
7513
 * @param  [in]   hash     Hash value to sign
7514
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7515
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7516
 *                WC_HASH_TYPE_SHA256
7517
 * @param  [in]   priv     Current ECC private key set
7518
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7519
 * @param  [in]   order    ECC order parameter to use with generation
7520
 * @return  0 on success.
7521
 */
7522
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7523
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7524
        void* heap)
7525
{
7526
    int ret = 0;
7527
#ifndef WOLFSSL_SMALL_STACK
7528
    byte h1[MAX_ECC_BYTES];
7529
    byte V[WC_MAX_DIGEST_SIZE];
7530
    byte K[WC_MAX_DIGEST_SIZE];
7531
    byte x[MAX_ECC_BYTES];
7532
    mp_int z1[1];
7533
#else
7534
    byte *h1 = NULL;
7535
    byte *V  = NULL;
7536
    byte *K  = NULL;
7537
    byte *x  = NULL;
7538
    mp_int *z1 = NULL;
7539
#endif
7540
    word32 xSz, VSz, KSz, h1len, qLen;
7541
    byte intOct;
7542
    int qbits = 0;
7543
7544
    if (hash == NULL || k == NULL || order == NULL) {
7545
        return BAD_FUNC_ARG;
7546
    }
7547
7548
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7549
        WOLFSSL_MSG("hash size was too large!");
7550
        return BAD_FUNC_ARG;
7551
    }
7552
7553
    /* if none is provided then detect has type based on hash size */
7554
    if (hashType == WC_HASH_TYPE_NONE) {
7555
        if (hashSz == 64) {
7556
            hashType = WC_HASH_TYPE_SHA512;
7557
        }
7558
        else if (hashSz == 48) {
7559
            hashType = WC_HASH_TYPE_SHA384;
7560
        }
7561
        else if (hashSz == 32) {
7562
            hashType = WC_HASH_TYPE_SHA256;
7563
        }
7564
        else {
7565
            return BAD_FUNC_ARG;
7566
        }
7567
    }
7568
7569
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
7570
        WOLFSSL_MSG("private key larger than max expected!");
7571
        return BAD_FUNC_ARG;
7572
    }
7573
7574
#ifdef WOLFSSL_SMALL_STACK
7575
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
7576
    if (h1 == NULL) {
7577
        ret = MEMORY_E;
7578
    }
7579
7580
    if (ret == 0) {
7581
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7582
        if (V == NULL)
7583
            ret = MEMORY_E;
7584
    }
7585
7586
    if (ret == 0) {
7587
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7588
        if (K == NULL)
7589
            ret = MEMORY_E;
7590
    }
7591
7592
    if (ret == 0) {
7593
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7594
        if (x == NULL)
7595
            ret = MEMORY_E;
7596
    }
7597
7598
    if (ret == 0) {
7599
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
7600
        if (z1 == NULL)
7601
            ret = MEMORY_E;
7602
    }
7603
7604
    /* bail out if any error has been hit at this point */
7605
    if (ret != 0) {
7606
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7607
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7608
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7609
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7610
        return ret;
7611
    }
7612
#endif
7613
7614
    VSz = KSz = hashSz;
7615
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
7616
7617
    /* 3.2 b. Set V = 0x01 0x01 ... */
7618
    XMEMSET(V, 0x01, VSz);
7619
7620
    /* 3.2 c. Set K = 0x00 0x00 ... */
7621
    XMEMSET(K, 0x00, KSz);
7622
7623
    if (ret == 0) {
7624
        ret = mp_init(z1); /* always init z1 and free z1 */
7625
    }
7626
    if (ret == 0) {
7627
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
7628
    }
7629
    if (ret == 0) {
7630
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7631
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
7632
    #endif
7633
        qbits = mp_count_bits(order);
7634
        if (qbits < 0)
7635
            ret = MP_VAL;
7636
    }
7637
7638
    if (ret == 0) {
7639
         /* hash truncate if too long */
7640
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
7641
            /* calculate truncated hash size using bits rounded up byte */
7642
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
7643
        }
7644
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
7645
    }
7646
7647
    /* bits2octets on h1 */
7648
    if (ret == 0) {
7649
        XMEMSET(h1, 0, MAX_ECC_BYTES);
7650
7651
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7652
        /* mod reduce by order using conditional subtract
7653
         * RFC6979 lists a variant that uses the hash directly instead of
7654
         * doing bits2octets(H(m)), when variant macro is used avoid this
7655
         * bits2octets operation */
7656
        if (mp_cmp(z1, order) == MP_GT) {
7657
            int z1Sz;
7658
7659
            mp_sub(z1, order, z1);
7660
            z1Sz = mp_unsigned_bin_size(z1);
7661
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
7662
                ret = BUFFER_E;
7663
            }
7664
            else {
7665
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7666
            }
7667
        }
7668
        else
7669
    #endif
7670
        {
7671
            /* use original hash and keep leading 0's */
7672
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
7673
        }
7674
    }
7675
    mp_free(z1);
7676
7677
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
7678
    if (ret == 0) {
7679
        intOct = 0x00;
7680
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
7681
                hashType, heap);
7682
    }
7683
7684
    /* 3.2 step e. V = HMAC_K(V) */
7685
    if (ret == 0) {
7686
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7687
                heap);
7688
    }
7689
7690
7691
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
7692
    if (ret == 0) {
7693
        intOct = 0x01;
7694
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
7695
                heap);
7696
    }
7697
7698
    /* 3.2 step g. V = HMAC_K(V) */
7699
    if (ret == 0) {
7700
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
7701
                heap);
7702
    }
7703
7704
    /* 3.2 step h. loop through the next steps until a valid value is found */
7705
    if (ret == 0 ) {
7706
        int err;
7707
7708
        intOct = 0x00;
7709
        do {
7710
            xSz = 0; /* used as tLen */
7711
            err = 0; /* start as good until generated k is tested */
7712
7713
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
7714
            while (xSz < qLen) {
7715
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7716
                        hashType, heap);
7717
                if (ret == 0) {
7718
                    int sz;
7719
7720
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
7721
                    XMEMCPY(x + xSz, V, (size_t)sz);
7722
                    xSz += (word32)sz;
7723
                }
7724
                else {
7725
                    break; /* error case */
7726
                }
7727
            }
7728
7729
            if (ret == 0) {
7730
                mp_clear(k); /* 3.2 step h.1 clear T */
7731
                ret = mp_read_unsigned_bin(k, x, xSz);
7732
            }
7733
7734
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
7735
                /* handle odd case where shift of 'k' is needed with RFC 6979
7736
                 *  k = bits2int(T) in section 3.2 h.3 */
7737
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
7738
            }
7739
7740
            /* 3.2 step h.3 the key should be smaller than the order of base
7741
             * point */
7742
            if (ret == 0) {
7743
                if (mp_cmp(k, order) != MP_LT) {
7744
                    err = MP_VAL;
7745
                } else if (mp_iszero(k) == MP_YES) {
7746
                    /* no 0 key's */
7747
                    err = MP_ZERO_E;
7748
                }
7749
            }
7750
7751
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
7752
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
7753
            if (ret == 0 && err != 0) {
7754
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
7755
                    hashType, heap);
7756
                if (ret == 0) {
7757
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
7758
                    hashType, heap);
7759
                }
7760
            }
7761
        } while (ret == 0 && err != 0);
7762
    }
7763
7764
    ForceZero(x, MAX_ECC_BYTES);
7765
#ifdef WOLFSSL_SMALL_STACK
7766
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
7767
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7768
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
7769
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
7770
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
7771
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
7772
    wc_MemZero_Check(x, MAX_ECC_BYTES);
7773
#endif
7774
7775
    return ret;
7776
}
7777
7778
7779
/* Sets the deterministic flag for 'k' generation with sign.
7780
 * returns 0 on success
7781
 */
7782
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
7783
                                enum wc_HashType hashType)
7784
{
7785
    if (key == NULL) {
7786
        return BAD_FUNC_ARG;
7787
    }
7788
7789
    key->deterministic = flag ? 1 : 0;
7790
    key->hashType = hashType;
7791
    return 0;
7792
}
7793
7794
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
7795
{
7796
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
7797
}
7798
7799
#endif /* end sign_ex and deterministic sign */
7800
7801
7802
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
7803
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
7804
407
{
7805
407
    int ret = MP_OKAY;
7806
407
    DECLARE_CURVE_SPECS(1);
7807
7808
407
    if (k == NULL || klen == 0 || key == NULL) {
7809
20
        return BAD_FUNC_ARG;
7810
20
    }
7811
7812
387
    ALLOC_CURVE_SPECS(1, ret);
7813
387
    if (ret == MP_OKAY) {
7814
375
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7815
375
    }
7816
7817
387
    if (ret != 0) {
7818
13
        FREE_CURVE_SPECS();
7819
13
        return ret;
7820
13
    }
7821
7822
374
#ifndef WOLFSSL_NO_MALLOC
7823
374
    if (key->sign_k == NULL) {
7824
374
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7825
374
                                                            DYNAMIC_TYPE_ECC);
7826
374
        if (key->sign_k) {
7827
372
            ret = mp_init(key->sign_k);
7828
372
        }
7829
2
        else {
7830
2
            ret = MEMORY_E;
7831
2
        }
7832
374
    }
7833
374
#endif
7834
7835
374
    if (ret == 0) {
7836
372
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
7837
372
    }
7838
374
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
7839
34
        ret = MP_VAL;
7840
34
    }
7841
#ifdef WOLFSSL_NO_MALLOC
7842
    if (ret == 0) {
7843
        key->sign_k_set = 1;
7844
    }
7845
#endif
7846
7847
374
    wc_ecc_curve_free(curve);
7848
374
    FREE_CURVE_SPECS();
7849
374
    return ret;
7850
387
}
7851
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
7852
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
7853
7854
#endif /* !HAVE_ECC_SIGN */
7855
7856
#ifdef WOLFSSL_CUSTOM_CURVES
7857
void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
7858
455
{
7859
455
#ifndef WOLFSSL_ECC_CURVE_STATIC
7860
455
    if (curve->prime != NULL)
7861
148
        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
7862
455
    if (curve->Af != NULL)
7863
127
        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
7864
455
    if (curve->Bf != NULL)
7865
120
        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
7866
455
    if (curve->order != NULL)
7867
99
        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
7868
455
    if (curve->Gx != NULL)
7869
105
        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
7870
455
    if (curve->Gy != NULL)
7871
105
        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
7872
455
#endif
7873
7874
455
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
7875
7876
455
    (void)heap;
7877
455
}
7878
#endif /* WOLFSSL_CUSTOM_CURVES */
7879
7880
/**
7881
  Free an ECC key from memory
7882
  key   The key you wish to free
7883
*/
7884
WOLFSSL_ABI
7885
int wc_ecc_free(ecc_key* key)
7886
31.8k
{
7887
31.8k
    if (key == NULL) {
7888
1
        return 0;
7889
1
    }
7890
7891
31.8k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7892
31.8k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7893
31.8k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7894
31.8k
#ifndef WOLFSSL_NO_MALLOC
7895
31.8k
    if (key->sign_k != NULL)
7896
197
#endif
7897
197
    {
7898
197
        mp_forcezero(key->sign_k);
7899
197
        mp_free(key->sign_k);
7900
197
#ifndef WOLFSSL_NO_MALLOC
7901
197
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7902
197
#endif
7903
197
    }
7904
31.8k
#endif
7905
7906
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7907
    #ifdef WC_ASYNC_ENABLE_ECC
7908
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
7909
    #endif
7910
    wc_ecc_free_async(key);
7911
#endif
7912
7913
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
7914
    /* free secure memory */
7915
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
7916
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
7917
       caamFreePart(key->partNum);
7918
    }
7919
#endif
7920
7921
#ifdef WOLFSSL_SE050
7922
#ifdef WOLFSSL_SE050_AUTO_ERASE
7923
    wc_se050_erase_object(key->keyId);
7924
#endif
7925
    se050_ecc_free_key(key);
7926
#endif
7927
7928
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
7929
    atmel_ecc_free(key->slot);
7930
    key->slot = ATECC_INVALID_SLOT;
7931
#endif /* WOLFSSL_ATECC508A */
7932
7933
#ifdef WOLFSSL_KCAPI_ECC
7934
    KcapiEcc_Free(key);
7935
#endif
7936
7937
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7938
    key->privKey = NULL;
7939
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
7940
    ForceZero(&key->xSec, sizeof(key->xSec));
7941
#endif
7942
7943
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
7944
    wc_MAXQ10XX_EccFree(key);
7945
#endif
7946
7947
31.8k
    mp_clear(key->pubkey.x);
7948
31.8k
    mp_clear(key->pubkey.y);
7949
31.8k
    mp_clear(key->pubkey.z);
7950
7951
#ifdef ALT_ECC_SIZE
7952
    if (key->k)
7953
#endif
7954
31.8k
        mp_forcezero(key->k);
7955
#ifdef WOLFSSL_ECC_BLIND_K
7956
#ifdef ALT_ECC_SIZE
7957
    if (key->kb)
7958
#endif
7959
        mp_forcezero(key->kb);
7960
#ifdef ALT_ECC_SIZE
7961
    if (key->ku)
7962
#endif
7963
        mp_forcezero(key->ku);
7964
#endif
7965
7966
31.8k
#ifdef WOLFSSL_CUSTOM_CURVES
7967
31.8k
    if (key->deallocSet && key->dp != NULL)
7968
0
        wc_ecc_free_curve(key->dp, key->heap);
7969
31.8k
#endif
7970
7971
#ifdef WOLFSSL_CHECK_MEM_ZERO
7972
    wc_MemZero_Check(key, sizeof(ecc_key));
7973
#endif
7974
7975
31.8k
    return 0;
7976
31.8k
}
7977
7978
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7979
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
7980
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
7981
      defined(WOLFSSL_IMXRT1170_CAAM))
7982
7983
/* Handles add failure cases:
7984
 *
7985
 * Before add:
7986
 *   Case 1: A is infinity
7987
 *        -> Copy B into result.
7988
 *   Case 2: B is infinity
7989
 *        -> Copy A into result.
7990
 *   Case 3: x and z are the same in A and B (same x value in affine)
7991
 *     Case 3a: y values the same - same point
7992
 *           -> Double instead of add.
7993
 *     Case 3b: y values different - negative of the other when points on curve
7994
 *           -> Need to set result to infinity.
7995
 *
7996
 * After add:
7997
 *   Case 1: A and B are the same point (maybe different z)
7998
 *           (Result was: x == y == z == 0)
7999
 *        -> Need to double instead.
8000
 *
8001
 *   Case 2: A + B = <infinity> = 0.
8002
 *           (Result was: z == 0, x and/or y not 0)
8003
 *        -> Need to set result to infinity.
8004
 */
8005
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8006
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8007
979k
{
8008
979k
    int err;
8009
8010
979k
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8011
        /* A is infinity. */
8012
84.7k
        err = wc_ecc_copy_point(B, R);
8013
84.7k
    }
8014
895k
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8015
        /* B is infinity. */
8016
5.68k
        err = wc_ecc_copy_point(A, R);
8017
5.68k
    }
8018
889k
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8019
        /* x ordinattes the same. */
8020
409
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8021
            /* A = B */
8022
185
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8023
185
        }
8024
224
        else {
8025
            /* A = -B */
8026
224
            err = mp_set(R->x, 0);
8027
224
            if (err == MP_OKAY)
8028
223
                err = mp_set(R->y, 0);
8029
224
            if (err == MP_OKAY)
8030
223
                err = mp_set(R->z, 1);
8031
224
            if ((err == MP_OKAY) && (infinity != NULL))
8032
97
                *infinity = 1;
8033
224
        }
8034
409
    }
8035
889k
    else {
8036
889k
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8037
889k
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8038
            /* When all zero then should have done a double */
8039
4.96k
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8040
66
                if (mp_iszero(B->z)) {
8041
0
                    err = wc_ecc_copy_point(B, R);
8042
0
                    if (err == MP_OKAY) {
8043
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8044
0
                    }
8045
0
                    if (err == MP_OKAY) {
8046
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8047
0
                    }
8048
0
                }
8049
66
                else {
8050
66
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8051
66
                }
8052
66
            }
8053
            /* When only Z zero then result is infinity */
8054
4.90k
            else {
8055
4.90k
                err = mp_set(R->x, 0);
8056
4.90k
                if (err == MP_OKAY)
8057
4.90k
                    err = mp_set(R->y, 0);
8058
4.90k
                if (err == MP_OKAY)
8059
4.90k
                    err = mp_set(R->z, 1);
8060
4.90k
                if ((err == MP_OKAY) && (infinity != NULL))
8061
4.63k
                    *infinity = 1;
8062
4.90k
            }
8063
4.96k
        }
8064
889k
    }
8065
8066
979k
    return err;
8067
979k
}
8068
8069
/* Handles when P is the infinity point.
8070
 *
8071
 * Double infinity -> infinity.
8072
 * Otherwise do normal double - which can't lead to infinity as odd order.
8073
 */
8074
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8075
                                  mp_int* modulus, mp_digit mp)
8076
1.06M
{
8077
1.06M
    int err;
8078
8079
1.06M
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8080
        /* P is infinity. */
8081
76.2k
        err = wc_ecc_copy_point(P, R);
8082
76.2k
    }
8083
986k
    else {
8084
986k
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8085
986k
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8086
22.2k
           err = mp_set(R->x, 0);
8087
22.2k
           if (err == MP_OKAY)
8088
22.2k
               err = mp_set(R->y, 0);
8089
22.2k
           if (err == MP_OKAY)
8090
22.2k
               err = mp_set(R->z, 1);
8091
22.2k
        }
8092
986k
    }
8093
8094
1.06M
    return err;
8095
1.06M
}
8096
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8097
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8098
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8099
            (WOLFSSL_IMXRT1170_CAAM))
8100
        */
8101
8102
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8103
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL) && \
8104
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8105
#ifdef ECC_SHAMIR
8106
8107
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8108
    ecc_point* Bm, mp_int* modulus, void* heap)
8109
692
{
8110
692
    int err = MP_OKAY;
8111
692
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8112
8113
692
    (void)heap;
8114
8115
692
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8116
#ifdef MP_INT_SIZE_CHECK_NULL
8117
    if (mu == NULL)
8118
       err = MEMORY_E;
8119
#endif
8120
692
    if (err == MP_OKAY) {
8121
692
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8122
692
    }
8123
692
    if (err == MP_OKAY) {
8124
692
        err = mp_montgomery_calc_normalization(mu, modulus);
8125
8126
692
        if (err == MP_OKAY) {
8127
            /* copy ones ... */
8128
692
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8129
692
        }
8130
8131
692
        if (err == MP_OKAY)
8132
692
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8133
692
        if (err == MP_OKAY)
8134
692
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8135
8136
692
        if (err == MP_OKAY)
8137
692
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8138
692
        if (err == MP_OKAY)
8139
692
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8140
692
        if (err == MP_OKAY)
8141
692
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8142
8143
        /* done with mu */
8144
692
        mp_clear(mu);
8145
692
    }
8146
8147
692
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8148
8149
692
    return err;
8150
692
}
8151
8152
/** Computes kA*A + kB*B = C using Shamir's Trick
8153
  A        First point to multiply
8154
  kA       What to multiple A by
8155
  B        Second point to multiply
8156
  kB       What to multiple B by
8157
  C        [out] Destination point (can overlap with A or B)
8158
  a        ECC curve parameter a
8159
  modulus  Modulus for curve
8160
  return MP_OKAY on success
8161
*/
8162
#ifdef FP_ECC
8163
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8164
                             ecc_point* B, mp_int* kB,
8165
                             ecc_point* C, mp_int* a, mp_int* modulus,
8166
                             void* heap)
8167
#else
8168
int ecc_mul2add(ecc_point* A, mp_int* kA,
8169
                    ecc_point* B, mp_int* kB,
8170
                    ecc_point* C, mp_int* a, mp_int* modulus,
8171
                    void* heap)
8172
#endif
8173
4.53k
{
8174
#ifdef WOLFSSL_SMALL_STACK_CACHE
8175
  ecc_key        *key = NULL;
8176
#endif
8177
4.53k
#ifdef WOLFSSL_SMALL_STACK
8178
4.53k
  ecc_point**    precomp = NULL;
8179
#else
8180
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8181
  #ifdef WOLFSSL_NO_MALLOC
8182
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8183
  #endif
8184
#endif
8185
4.53k
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8186
#ifdef WOLFSSL_NO_MALLOC
8187
  unsigned char tA[ECC_BUFSIZE];
8188
  unsigned char tB[ECC_BUFSIZE];
8189
#else
8190
4.53k
  unsigned char* tA = NULL;
8191
4.53k
  unsigned char* tB = NULL;
8192
4.53k
#endif
8193
4.53k
  int            err = MP_OKAY, first, x, y;
8194
4.53k
  mp_digit       mp = 0;
8195
8196
  /* argchks */
8197
4.53k
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8198
4.53k
                                                         modulus == NULL) {
8199
0
     return ECC_BAD_ARG_E;
8200
0
  }
8201
8202
4.53k
#ifndef WOLFSSL_NO_MALLOC
8203
  /* allocate memory */
8204
4.53k
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8205
4.53k
  if (tA == NULL) {
8206
1
     return MP_MEM;
8207
1
  }
8208
4.53k
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8209
4.53k
  if (tB == NULL) {
8210
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8211
0
     return MP_MEM;
8212
0
  }
8213
4.53k
#endif
8214
8215
#ifdef WOLFSSL_SMALL_STACK_CACHE
8216
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8217
  if (key == NULL) {
8218
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8219
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8220
     return MP_MEM;
8221
  }
8222
#endif
8223
4.53k
#ifdef WOLFSSL_SMALL_STACK
8224
4.53k
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8225
4.53k
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8226
4.53k
  if (precomp == NULL) {
8227
0
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8228
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8229
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8230
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8231
  #endif
8232
0
     return MP_MEM;
8233
0
  }
8234
4.53k
#endif
8235
#ifdef WOLFSSL_SMALL_STACK_CACHE
8236
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8237
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8238
#ifdef ALT_ECC_SIZE
8239
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8240
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8241
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8242
#endif
8243
8244
  if (key->t1 == NULL || key->t2 == NULL
8245
#ifdef ALT_ECC_SIZE
8246
     || key->x == NULL || key->y == NULL || key->z == NULL
8247
#endif
8248
  ) {
8249
#ifdef ALT_ECC_SIZE
8250
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8251
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8252
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8253
#endif
8254
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8255
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8256
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8257
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8258
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8259
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8260
      return MEMORY_E;
8261
  }
8262
  C->key = key;
8263
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8264
8265
  /* init variables */
8266
4.53k
  XMEMSET(tA, 0, ECC_BUFSIZE);
8267
4.53k
  XMEMSET(tB, 0, ECC_BUFSIZE);
8268
#ifndef WOLFSSL_SMALL_STACK
8269
  XMEMSET(precomp, 0, sizeof(precomp));
8270
#else
8271
4.53k
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8272
4.53k
#endif
8273
#ifdef WOLFSSL_CHECK_MEM_ZERO
8274
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8275
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8276
#endif
8277
8278
  /* get sizes */
8279
4.53k
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8280
4.53k
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8281
4.53k
  len  = MAX(lenA, lenB);
8282
8283
  /* sanity check */
8284
4.53k
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8285
0
    err = BAD_FUNC_ARG;
8286
0
  }
8287
8288
4.53k
  if (err == MP_OKAY) {
8289
    /* extract and justify kA */
8290
4.53k
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8291
8292
    /* extract and justify kB */
8293
4.53k
    if (err == MP_OKAY)
8294
4.53k
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8295
8296
    /* allocate the table */
8297
4.53k
    if (err == MP_OKAY) {
8298
77.0k
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8299
        #ifdef WOLFSSL_NO_MALLOC
8300
            precomp[x] = &lcl_precomp[x];
8301
        #endif
8302
72.4k
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8303
72.4k
            if (err != MP_OKAY)
8304
1
                break;
8305
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8306
            precomp[x]->key = key;
8307
        #endif
8308
72.4k
        }
8309
4.53k
    }
8310
4.53k
  }
8311
8312
4.53k
  if (err == MP_OKAY)
8313
    /* init montgomery reduction */
8314
4.53k
    err = mp_montgomery_setup(modulus, &mp);
8315
8316
4.53k
  if (err == MP_OKAY) {
8317
4.53k
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8318
4.53k
  }
8319
8320
4.53k
  if (err == MP_OKAY) {
8321
    /* precomp [i,0](A + B) table */
8322
4.53k
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8323
4.53k
  }
8324
4.53k
  if (err == MP_OKAY) {
8325
4.53k
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8326
4.53k
                                                          a, modulus, mp, NULL);
8327
4.53k
  }
8328
8329
4.53k
  if (err == MP_OKAY) {
8330
    /* precomp [0,i](A + B) table */
8331
4.52k
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8332
4.52k
  }
8333
4.53k
  if (err == MP_OKAY) {
8334
4.52k
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8335
4.52k
                                                             modulus, mp, NULL);
8336
4.52k
  }
8337
8338
4.53k
  if (err == MP_OKAY) {
8339
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8340
18.1k
    for (x = 1; x < 4; x++) {
8341
54.3k
      for (y = 1; y < 4; y++) {
8342
40.7k
        if (err == MP_OKAY) {
8343
40.7k
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8344
40.7k
                                                  precomp[x+(y<<2)], a, modulus,
8345
40.7k
                                                  mp, NULL);
8346
40.7k
        }
8347
40.7k
      }
8348
13.5k
    }
8349
4.52k
  }
8350
8351
4.53k
  if (err == MP_OKAY) {
8352
4.52k
    nibble  = 3;
8353
4.52k
    first   = 1;
8354
4.52k
    bitbufA = tA[0];
8355
4.52k
    bitbufB = tB[0];
8356
8357
    /* for every byte of the multiplicands */
8358
567k
    for (x = 0; x < (int)len || nibble != 3; ) {
8359
        /* grab a nibble */
8360
563k
        if (++nibble == 4) {
8361
140k
            if (x == (int)len) break;
8362
140k
            bitbufA = tA[x];
8363
140k
            bitbufB = tB[x];
8364
140k
            nibble  = 0;
8365
140k
            x++;
8366
140k
        }
8367
8368
        /* extract two bits from both, shift/update */
8369
563k
        nA = (bitbufA >> 6) & 0x03;
8370
563k
        nB = (bitbufB >> 6) & 0x03;
8371
563k
        bitbufA = (bitbufA << 2) & 0xFF;
8372
563k
        bitbufB = (bitbufB << 2) & 0xFF;
8373
8374
        /* if both zero, if first, continue */
8375
563k
        if ((nA == 0) && (nB == 0) && (first == 1)) {
8376
2.35k
            continue;
8377
2.35k
        }
8378
8379
        /* double twice, only if this isn't the first */
8380
560k
        if (first == 0) {
8381
            /* double twice */
8382
554k
            if (err == MP_OKAY)
8383
554k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8384
554k
            if (err == MP_OKAY)
8385
554k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
8386
6
            else
8387
6
                break;
8388
554k
        }
8389
8390
        /* if not both zero */
8391
560k
        if ((nA != 0) || (nB != 0)) {
8392
504k
            unsigned int i = nA + (nB<<2);
8393
504k
            if (first == 1) {
8394
                /* if first, copy from table */
8395
6.01k
                first = 0;
8396
6.01k
                if (err == MP_OKAY)
8397
6.01k
                    err = mp_copy(precomp[i]->x, C->x);
8398
8399
6.01k
                if (err == MP_OKAY)
8400
6.01k
                    err = mp_copy(precomp[i]->y, C->y);
8401
8402
6.01k
                if (err == MP_OKAY)
8403
6.01k
                    err = mp_copy(precomp[i]->z, C->z);
8404
0
                else
8405
0
                    break;
8406
498k
            } else {
8407
                /* if not first, add from table */
8408
498k
                if (err == MP_OKAY)
8409
498k
                    err = ecc_projective_add_point_safe(C, precomp[i],
8410
498k
                                                        C, a, modulus, mp,
8411
498k
                                                        &first);
8412
498k
                if (err != MP_OKAY)
8413
9
                    break;
8414
498k
            }
8415
504k
        }
8416
560k
    }
8417
4.52k
  }
8418
8419
  /* reduce to affine */
8420
4.53k
  if (err == MP_OKAY)
8421
4.50k
    err = ecc_map(C, modulus, mp);
8422
8423
  /* clean up */
8424
77.0k
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8425
72.4k
     wc_ecc_del_point_ex(precomp[x], heap);
8426
72.4k
  }
8427
8428
4.53k
  ForceZero(tA, ECC_BUFSIZE);
8429
4.53k
  ForceZero(tB, ECC_BUFSIZE);
8430
#ifdef WOLFSSL_SMALL_STACK_CACHE
8431
#ifdef ALT_ECC_SIZE
8432
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8433
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8434
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8435
#endif
8436
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8437
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8438
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8439
  C->key = NULL;
8440
#endif
8441
4.53k
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8442
4.53k
#ifndef WOLFSSL_NO_MALLOC
8443
4.53k
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8444
4.53k
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8445
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8446
  wc_MemZero_Check(tB, ECC_BUFSIZE);
8447
  wc_MemZero_Check(tA, ECC_BUFSIZE);
8448
#endif
8449
4.53k
  return err;
8450
4.53k
}
8451
8452
#endif /* ECC_SHAMIR */
8453
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
8454
        * !WOLFSSL_CRYPTOCEL */
8455
8456
8457
#ifdef HAVE_ECC_VERIFY
8458
/* verify
8459
 *
8460
 * w  = s^-1 mod n
8461
 * u1 = xw
8462
 * u2 = rw
8463
 * X = u1*G + u2*Q
8464
 * v = X_x1 mod n
8465
 * accept if v == r
8466
 */
8467
8468
/**
8469
 Verify an ECC signature
8470
 sig         The signature to verify
8471
 siglen      The length of the signature (octets)
8472
 hash        The hash (message digest) that was signed
8473
 hashlen     The length of the hash (octets)
8474
 res         Result of signature, 1==valid, 0==invalid
8475
 key         The corresponding public ECC key
8476
 return      MP_OKAY if successful (even if the signature is not valid)
8477
             Caller should check the *res value to determine if the signature
8478
             is valid or invalid. Other negative values are returned on error.
8479
 */
8480
WOLFSSL_ABI
8481
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
8482
                       word32 hashlen, int* res, ecc_key* key)
8483
737
{
8484
737
    int err;
8485
8486
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8487
    mp_int *r = NULL, *s = NULL;
8488
#else
8489
737
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8490
737
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
8491
737
#endif
8492
#ifdef WOLFSSL_ASYNC_CRYPT
8493
    int isPrivateKeyOnly = 0;
8494
#endif
8495
#ifdef NO_ASN
8496
    word32 keySz;
8497
#endif
8498
8499
737
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
8500
10
        return ECC_BAD_ARG_E;
8501
10
    }
8502
727
    if (hashlen > WC_MAX_DIGEST_SIZE) {
8503
0
        return BAD_LENGTH_E;
8504
0
    }
8505
8506
727
#ifdef WOLF_CRYPTO_CB
8507
727
    #ifndef WOLF_CRYPTO_CB_FIND
8508
727
    if (key->devId != INVALID_DEVID)
8509
0
    #endif
8510
0
    {
8511
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
8512
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8513
0
            return err;
8514
        /* fall-through when unavailable */
8515
0
    }
8516
727
#endif
8517
8518
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
8519
    (void)siglen;
8520
    (void)hashlen;
8521
    (void)s;
8522
    (void)r;
8523
    (void)err;
8524
    return NO_VALID_DEVID;
8525
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
8526
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8527
    err = wc_ecc_alloc_async(key);
8528
    if (err != 0)
8529
        return err;
8530
    r = key->r;
8531
    s = key->s;
8532
#else
8533
727
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8534
727
        DYNAMIC_TYPE_ECC);
8535
    #ifdef MP_INT_SIZE_CHECK_NULL
8536
    if (r == NULL)
8537
        return MEMORY_E;
8538
    #endif
8539
727
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
8540
727
        DYNAMIC_TYPE_ECC);
8541
    #ifdef MP_INT_SIZE_CHECK_NULL
8542
    if (s == NULL) {
8543
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8544
        return MEMORY_E;
8545
    }
8546
    #endif
8547
727
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8548
727
    if (err != 0) {
8549
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8550
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8551
0
        return err;
8552
0
    }
8553
727
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8554
727
    if (err != 0) {
8555
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8556
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8557
0
        return err;
8558
0
    }
8559
727
#endif /* WOLFSSL_ASYNC_CRYPT */
8560
8561
727
    switch (key->state) {
8562
727
        case ECC_STATE_NONE:
8563
727
        case ECC_STATE_VERIFY_DECODE:
8564
727
            key->state = ECC_STATE_VERIFY_DECODE;
8565
8566
            /* default to invalid signature */
8567
727
            *res = 0;
8568
8569
727
    #ifndef NO_ASN
8570
            /* Decode ASN.1 ECDSA signature. */
8571
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8572
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
8573
             * If either of those don't allocate correctly, none of
8574
             * the rest of this function will execute, and everything
8575
             * gets cleaned up at the end. */
8576
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
8577
        #else
8578
            /* r and s are initialized. */
8579
727
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
8580
727
        #endif
8581
727
            if (err < 0) {
8582
0
                break;
8583
0
            }
8584
    #else
8585
            /* No support for DSA ASN.1 header.
8586
             * Signature must be r+s directly. */
8587
            keySz = 0;
8588
            if (key->dp != NULL) {
8589
                keySz = (word32)key->dp->size;
8590
            }
8591
            if (siglen != keySz * 2) {
8592
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
8593
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
8594
            }
8595
8596
            /* Import signature into r,s */
8597
            mp_init(r);
8598
            mp_init(s);
8599
            mp_read_unsigned_bin(r, sig, keySz);
8600
            mp_read_unsigned_bin(s, sig + keySz, keySz);
8601
    #endif /* !NO_ASN */
8602
727
            FALL_THROUGH;
8603
8604
727
        case ECC_STATE_VERIFY_DO:
8605
727
            key->state = ECC_STATE_VERIFY_DO;
8606
        #ifdef WOLFSSL_ASYNC_CRYPT
8607
            if (key->type == ECC_PRIVATEKEY_ONLY) {
8608
                isPrivateKeyOnly = 1;
8609
            }
8610
        #endif
8611
727
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
8612
8613
727
        #ifndef WOLFSSL_ASYNC_CRYPT
8614
            /* done with R/S */
8615
727
            mp_clear(r);
8616
727
            mp_clear(s);
8617
727
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8618
727
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8619
        #ifdef MP_INT_SIZE_CHECK_NULL
8620
            r = NULL;
8621
            s = NULL;
8622
        #endif
8623
727
        #endif
8624
8625
727
            if (err < 0) {
8626
35
                break;
8627
35
            }
8628
692
            FALL_THROUGH;
8629
8630
692
        case ECC_STATE_VERIFY_RES:
8631
692
            key->state = ECC_STATE_VERIFY_RES;
8632
692
            err = 0;
8633
692
            break;
8634
8635
0
        default:
8636
0
            err = BAD_STATE_E;
8637
727
    }
8638
8639
#ifdef WOLFSSL_ASYNC_CRYPT
8640
    /* if async pending then return and skip done cleanup below */
8641
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8642
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
8643
            key->state++;
8644
        return err;
8645
    }
8646
#endif
8647
8648
    /* cleanup */
8649
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8650
    wc_ecc_free_async(key);
8651
#else
8652
727
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
8653
727
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
8654
727
#endif
8655
8656
    /* make sure required variables are reset */
8657
727
    wc_ecc_reset(key);
8658
727
    return err;
8659
727
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
8660
727
}
8661
8662
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
8663
8664
#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
8665
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8666
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
8667
727
{
8668
727
    int err = MP_OKAY;
8669
727
    DECLARE_CURVE_SPECS(1);
8670
8671
727
    ALLOC_CURVE_SPECS(1, err);
8672
727
    if (err == MP_OKAY) {
8673
727
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8674
727
    }
8675
727
    if (err != 0) {
8676
0
        FREE_CURVE_SPECS();
8677
0
        return err;
8678
0
    }
8679
8680
727
    if (mp_iszero(r) || mp_iszero(s)) {
8681
0
        err = MP_ZERO_E;
8682
0
    }
8683
727
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
8684
16
        err = MP_VAL;
8685
16
    }
8686
727
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
8687
19
        err = MP_VAL;
8688
19
    }
8689
8690
727
    wc_ecc_curve_free(curve);
8691
727
    FREE_CURVE_SPECS();
8692
727
    return err;
8693
727
}
8694
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
8695
8696
#ifdef HAVE_ECC_VERIFY_HELPER
8697
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
8698
    word32 hashlen, int* res, ecc_key* key)
8699
4.81k
{
8700
4.81k
    (void)r;
8701
4.81k
    (void)s;
8702
4.81k
    (void)hash;
8703
4.81k
    (void)hashlen;
8704
4.81k
    (void)res;
8705
4.81k
    (void)key;
8706
8707
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
8708
  if (key->handle != -1) {
8709
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
8710
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8711
  }
8712
  if (wolfSSL_GetHandleCbSet() == 1) {
8713
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
8714
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8715
  }
8716
#endif
8717
8718
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
8719
    if (key->idx == ECC_CUSTOM_IDX || (1
8720
    #ifndef WOLFSSL_SP_NO_256
8721
         && ecc_sets[key->idx].id != ECC_SECP256R1
8722
    #endif
8723
    #ifdef WOLFSSL_SP_SM2
8724
         && ecc_sets[key->idx].id != ECC_SM2P256V1
8725
    #endif
8726
    #ifdef WOLFSSL_SP_384
8727
         && ecc_sets[key->idx].id != ECC_SECP384R1
8728
    #endif
8729
    #ifdef WOLFSSL_SP_521
8730
         && ecc_sets[key->idx].id != ECC_SECP521R1
8731
    #endif
8732
        )) {
8733
        return WC_KEY_SIZE_E;
8734
    }
8735
#endif
8736
8737
#if defined(WOLFSSL_HAVE_SP_ECC)
8738
    if (key->idx != ECC_CUSTOM_IDX) {
8739
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
8740
        /* perform blocking call to non-blocking function */
8741
        ecc_nb_ctx_t nb_ctx;
8742
        int err;
8743
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
8744
        err = NOT_COMPILED_IN; /* set default error */
8745
    #endif
8746
    #ifndef WOLFSSL_SP_NO_256
8747
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
8748
        #ifdef WC_ECC_NONBLOCK
8749
            if (key->nb_ctx) {
8750
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8751
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8752
                    key->heap);
8753
            }
8754
            #ifdef WC_ECC_NONBLOCK_ONLY
8755
            do { /* perform blocking call to non-blocking function */
8756
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
8757
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8758
                    key->heap);
8759
            } while (err == FP_WOULDBLOCK);
8760
            return err;
8761
            #endif
8762
        #endif /* WC_ECC_NONBLOCK */
8763
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8764
            {
8765
                int ret;
8766
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8767
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
8768
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8769
                RESTORE_VECTOR_REGISTERS();
8770
                return ret;
8771
            }
8772
        #endif
8773
        }
8774
    #endif
8775
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
8776
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
8777
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
8778
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
8779
                key->pubkey.y, key->pubkey.z, r, s, res,
8780
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
8781
                                          key->fpIdx, key->fpBuild, key->heap),
8782
                key->heap);
8783
            #endif
8784
            #if !defined(FP_ECC_CONTROL)
8785
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
8786
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8787
            #endif
8788
        }
8789
    #endif
8790
    #ifdef WOLFSSL_SP_384
8791
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
8792
        #ifdef WC_ECC_NONBLOCK
8793
            if (key->nb_ctx) {
8794
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8795
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8796
                    key->heap);
8797
            }
8798
            #ifdef WC_ECC_NONBLOCK_ONLY
8799
            do { /* perform blocking call to non-blocking function */
8800
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
8801
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8802
                    key->heap);
8803
            } while (err == FP_WOULDBLOCK);
8804
            return err;
8805
            #endif
8806
        #endif /* WC_ECC_NONBLOCK */
8807
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8808
            {
8809
                int ret;
8810
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8811
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
8812
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8813
                RESTORE_VECTOR_REGISTERS();
8814
                return ret;
8815
            }
8816
        #endif
8817
        }
8818
    #endif
8819
    #ifdef WOLFSSL_SP_521
8820
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
8821
        #ifdef WC_ECC_NONBLOCK
8822
            if (key->nb_ctx) {
8823
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
8824
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
8825
                    key->heap);
8826
            }
8827
            #ifdef WC_ECC_NONBLOCK_ONLY
8828
            do { /* perform blocking call to non-blocking function */
8829
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
8830
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
8831
                    key->heap);
8832
            } while (err == FP_WOULDBLOCK);
8833
            return err;
8834
            #endif
8835
        #endif /* WC_ECC_NONBLOCK */
8836
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
8837
            {
8838
                int ret;
8839
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
8840
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
8841
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
8842
                RESTORE_VECTOR_REGISTERS();
8843
                return ret;
8844
            }
8845
        #endif
8846
        }
8847
    #endif
8848
    }
8849
#endif
8850
8851
4.81k
    return NOT_COMPILED_IN;
8852
4.81k
}
8853
8854
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
8855
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
8856
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
8857
692
{
8858
692
   int        err;
8859
692
   ecc_point* mG = NULL;
8860
692
   ecc_point* mQ = NULL;
8861
#ifdef WOLFSSL_NO_MALLOC
8862
   ecc_point  lcl_mG;
8863
   ecc_point  lcl_mQ;
8864
#endif
8865
692
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8866
692
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8867
692
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
8868
692
#endif
8869
692
   mp_int*    e;
8870
692
   mp_int*    v = NULL;      /* Will be w. */
8871
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
8872
   mp_int     u1tmp[1];
8873
   mp_int     u2tmp[1];
8874
#endif
8875
692
   mp_int*    u1 = NULL;     /* Will be e. */
8876
692
   mp_int*    u2 = NULL;     /* Will be w. */
8877
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
8878
   err = wc_ecc_alloc_mpint(key, &key->e);
8879
   if (err != 0) {
8880
      return err;
8881
   }
8882
   e = key->e;
8883
8884
   err = mp_init(e);
8885
#else
8886
692
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8887
#ifdef MP_INT_SIZE_CHECK_NULL
8888
   if (e_lcl == NULL) {
8889
       return MEMORY_E;
8890
   }
8891
#endif
8892
692
   e = e_lcl;
8893
8894
692
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8895
692
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
8896
692
   if (err != MP_OKAY) {
8897
0
#ifdef WOLFSSL_SMALL_STACK
8898
0
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
8899
0
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8900
0
   #endif
8901
0
#endif
8902
0
      return MEMORY_E;
8903
0
   }
8904
8905
   /* read hash */
8906
692
   if (err == MP_OKAY) {
8907
       /* we may need to truncate if hash is longer than key size */
8908
692
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
8909
8910
       /* truncate down to byte size, may be all that's needed */
8911
692
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8912
50
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8913
692
       err = mp_read_unsigned_bin(e, hash, hashlen);
8914
8915
       /* may still need bit truncation too */
8916
692
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
8917
45
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8918
692
   }
8919
8920
   /* check for async hardware acceleration */
8921
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8922
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8923
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8924
   #ifdef HAVE_CAVIUM_V
8925
      if (NitroxEccIsCurveSupported(key))
8926
   #endif
8927
      {
8928
          word32 keySz = (word32)key->dp->size;
8929
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8930
          if (err == MP_OKAY)
8931
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
8932
          if (err == MP_OKAY)
8933
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
8934
          if (err == MP_OKAY)
8935
          #ifdef HAVE_CAVIUM_V
8936
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
8937
                    &key->pubkey.y->raw, &r->raw, &s->raw,
8938
                    &curve->prime->raw, &curve->order->raw, res);
8939
          #else
8940
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
8941
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
8942
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
8943
                    &curve->Gx->raw, &curve->Gy->raw, res);
8944
          #endif
8945
8946
      #ifndef HAVE_CAVIUM_V
8947
          mp_clear(e);
8948
      #endif
8949
8950
          return err;
8951
      }
8952
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8953
   }
8954
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8955
8956
692
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
8957
#ifdef MP_INT_SIZE_CHECK_NULL
8958
   if (w == NULL) {
8959
       err = MEMORY_E;
8960
   }
8961
#endif
8962
8963
692
   if (err == MP_OKAY) {
8964
#ifdef WOLFSSL_CHECK_VER_FAULTS
8965
    #ifndef WOLFSSL_NO_MALLOC
8966
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8967
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
8968
       if (u1 == NULL || u2 == NULL)
8969
            err = MEMORY_E;
8970
    #else
8971
        u1 = u1tmp;
8972
        u2 = u2tmp;
8973
    #endif
8974
#else
8975
692
       u1 = e;
8976
692
       u2 = w;
8977
692
#endif
8978
692
       v = w;
8979
692
   }
8980
692
   if (err == MP_OKAY) {
8981
692
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8982
692
   }
8983
#ifdef WOLFSSL_CHECK_VER_FAULTS
8984
   if (err == MP_OKAY) {
8985
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8986
   }
8987
   if (err == MP_OKAY) {
8988
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
8989
   }
8990
#endif
8991
8992
   /* allocate points */
8993
692
   if (err == MP_OKAY) {
8994
   #ifdef WOLFSSL_NO_MALLOC
8995
       mG = &lcl_mG;
8996
   #endif
8997
692
       err = wc_ecc_new_point_ex(&mG, key->heap);
8998
692
   }
8999
692
   if (err == MP_OKAY) {
9000
   #ifdef WOLFSSL_NO_MALLOC
9001
       mQ = &lcl_mQ;
9002
   #endif
9003
692
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9004
692
   }
9005
9006
   /*  w  = s^-1 mod n */
9007
692
   if (err == MP_OKAY)
9008
692
       err = mp_invmod(s, curve->order, w);
9009
9010
   /* u1 = ew */
9011
692
   if (err == MP_OKAY)
9012
692
       err = mp_mulmod(e, w, curve->order, u1);
9013
9014
#ifdef WOLFSSL_CHECK_VER_FAULTS
9015
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9016
        err = BAD_STATE_E;
9017
    }
9018
#endif
9019
9020
   /* u2 = rw */
9021
692
   if (err == MP_OKAY)
9022
692
       err = mp_mulmod(r, w, curve->order, u2);
9023
9024
#ifdef WOLFSSL_CHECK_VER_FAULTS
9025
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9026
        err = BAD_STATE_E;
9027
    }
9028
#endif
9029
9030
   /* find mG and mQ */
9031
692
   if (err == MP_OKAY)
9032
692
       err = mp_copy(curve->Gx, mG->x);
9033
692
   if (err == MP_OKAY)
9034
692
       err = mp_copy(curve->Gy, mG->y);
9035
692
   if (err == MP_OKAY)
9036
692
       err = mp_set(mG->z, 1);
9037
9038
692
   if (err == MP_OKAY)
9039
692
       err = mp_copy(key->pubkey.x, mQ->x);
9040
692
   if (err == MP_OKAY)
9041
692
       err = mp_copy(key->pubkey.y, mQ->y);
9042
692
   if (err == MP_OKAY)
9043
692
       err = mp_copy(key->pubkey.z, mQ->z);
9044
9045
#if defined(FREESCALE_LTC_ECC)
9046
   /* use PKHA to compute u1*mG + u2*mQ */
9047
   if (err == MP_OKAY)
9048
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9049
   if (err == MP_OKAY)
9050
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9051
   if (err == MP_OKAY)
9052
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9053
#else
9054
#ifndef ECC_SHAMIR
9055
    if (err == MP_OKAY)
9056
    {
9057
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9058
        ecc_point mG1, mQ1;
9059
        wc_ecc_copy_point(mQ, &mQ1);
9060
        wc_ecc_copy_point(mG, &mG1);
9061
     #endif
9062
9063
        mp_digit mp = 0;
9064
9065
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9066
            /* compute u1*mG + u2*mQ = mG */
9067
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9068
                                                                     key->heap);
9069
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9070
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9071
                err = BAD_STATE_E;
9072
            }
9073
9074
            /* store new value for comparing with after add operation */
9075
           wc_ecc_copy_point(mG, &mG1);
9076
        #endif
9077
            if (err == MP_OKAY) {
9078
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9079
                                                                     key->heap);
9080
            }
9081
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9082
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9083
                err = BAD_STATE_E;
9084
            }
9085
        #endif
9086
9087
            /* find the montgomery mp */
9088
            if (err == MP_OKAY)
9089
                err = mp_montgomery_setup(curve->prime, &mp);
9090
9091
            /* add them */
9092
            if (err == MP_OKAY)
9093
                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
9094
                                                        curve->prime, mp, NULL);
9095
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9096
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9097
                err = BAD_STATE_E;
9098
            }
9099
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9100
                err = BAD_STATE_E;
9101
            }
9102
        #endif
9103
        }
9104
        else {
9105
            /* compute 0*mG + u2*mQ = mG */
9106
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9107
                                                                     key->heap);
9108
            /* find the montgomery mp */
9109
            if (err == MP_OKAY)
9110
                err = mp_montgomery_setup(curve->prime, &mp);
9111
        }
9112
9113
        /* reduce */
9114
        if (err == MP_OKAY)
9115
            err = ecc_map(mG, curve->prime, mp);
9116
    }
9117
#else
9118
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9119
692
    if (err == MP_OKAY) {
9120
692
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9121
692
                                                                     key->heap);
9122
692
    }
9123
692
#endif /* ECC_SHAMIR */
9124
692
#endif /* FREESCALE_LTC_ECC */
9125
9126
   /* v = X_x1 mod n */
9127
692
   if (err == MP_OKAY)
9128
692
       err = mp_mod(mG->x, curve->order, v);
9129
9130
   /* does v == r */
9131
692
   if (err == MP_OKAY) {
9132
692
       if (mp_cmp(v, r) == MP_EQ)
9133
631
           *res = 1;
9134
#ifdef WOLFSSL_CHECK_VER_FAULTS
9135
       /* redundant comparison as sanity check that first one happened */
9136
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9137
           *res = 0;
9138
#endif
9139
692
   }
9140
9141
   /* cleanup */
9142
692
   wc_ecc_del_point_ex(mG, key->heap);
9143
692
   wc_ecc_del_point_ex(mQ, key->heap);
9144
9145
692
   mp_clear(e);
9146
692
   mp_clear(w);
9147
692
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9148
#ifdef WOLFSSL_CHECK_VER_FAULTS
9149
   mp_clear(u1);
9150
   mp_clear(u2);
9151
#ifndef WOLFSSL_NO_MALLOC
9152
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9153
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9154
#endif
9155
#endif
9156
692
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9157
692
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9158
692
#endif
9159
9160
692
   return err;
9161
692
}
9162
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9163
#endif /* HAVE_ECC_VERIFY_HELPER */
9164
9165
/**
9166
   Verify an ECC signature
9167
   r           The signature R component to verify
9168
   s           The signature S component to verify
9169
   hash        The hash (message digest) that was signed
9170
   hashlen     The length of the hash (octets)
9171
   res         Result of signature, 1==valid, 0==invalid
9172
   key         The corresponding public ECC key
9173
   return      MP_OKAY if successful (even if the signature is not valid)
9174
               Caller should check the *res value to determine if the signature
9175
               is valid or invalid. Other negative values are returned on error.
9176
*/
9177
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9178
                    word32 hashlen, int* res, ecc_key* key)
9179
1.35k
{
9180
#if defined(WOLFSSL_STM32_PKA)
9181
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9182
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9183
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9184
#else
9185
1.35k
   int           err;
9186
1.35k
   word32        keySz = 0;
9187
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9188
   byte sigRS[ATECC_KEY_SIZE*2];
9189
#elif defined(WOLFSSL_CRYPTOCELL)
9190
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9191
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9192
   word32 msgLenInBytes = hashlen;
9193
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9194
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9195
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9196
#elif defined(WOLFSSL_KCAPI_ECC)
9197
   byte sigRS[MAX_ECC_BYTES*2];
9198
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9199
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9200
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9201
#elif defined(WOLFSSL_SE050)
9202
#else
9203
1.35k
   int curveLoaded = 0;
9204
1.35k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9205
1.35k
#endif
9206
9207
1.35k
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9208
0
       return ECC_BAD_ARG_E;
9209
9210
   /* default to invalid signature */
9211
1.35k
   *res = 0;
9212
9213
   /* is the IDX valid ?  */
9214
1.35k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9215
0
      return ECC_BAD_ARG_E;
9216
0
   }
9217
9218
1.35k
   err = wc_ecc_check_r_s_range(key, r, s);
9219
1.35k
   if (err != MP_OKAY) {
9220
79
      return err;
9221
79
   }
9222
9223
1.27k
   keySz = (word32)key->dp->size;
9224
9225
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9226
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9227
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9228
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9229
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9230
            sw->eccVerify.r = r;
9231
            sw->eccVerify.s = s;
9232
            sw->eccVerify.hash = hash;
9233
            sw->eccVerify.hashlen = hashlen;
9234
            sw->eccVerify.stat = res;
9235
            sw->eccVerify.key = key;
9236
            return WC_PENDING_E;
9237
        }
9238
    }
9239
#endif
9240
9241
#ifndef HAVE_ECC_VERIFY_HELPER
9242
9243
#ifndef WOLFSSL_SE050
9244
    /* Extract R and S with front zero padding (if required),
9245
     * SE050 does this in port layer  */
9246
    XMEMSET(sigRS, 0, sizeof(sigRS));
9247
    err = mp_to_unsigned_bin(r, sigRS +
9248
                                (keySz - mp_unsigned_bin_size(r)));
9249
    if (err != MP_OKAY) {
9250
        return err;
9251
    }
9252
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9253
                                (keySz - mp_unsigned_bin_size(s)));
9254
    if (err != MP_OKAY) {
9255
        return err;
9256
    }
9257
#endif /* WOLFSSL_SE050 */
9258
9259
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9260
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9261
    if (err != 0) {
9262
       return err;
9263
    }
9264
    (void)hashlen;
9265
#elif defined(WOLFSSL_CRYPTOCELL)
9266
9267
   /* truncate if hash is longer than key size */
9268
   if (msgLenInBytes > keySz) {
9269
       msgLenInBytes = keySz;
9270
   }
9271
   hash_mode = cc310_hashModeECC(msgLenInBytes);
9272
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
9273
       /* hash_mode = */ cc310_hashModeECC(keySz);
9274
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
9275
   }
9276
9277
   /* verify the signature using the public key */
9278
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
9279
                           &key->ctx.pubKey,
9280
                           hash_mode,
9281
                           &sigRS[0],
9282
                           keySz*2,
9283
                           (byte*)hash,
9284
                           msgLenInBytes);
9285
9286
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
9287
       /* signature verification reported invalid signature. */
9288
       *res = 0; /* Redundant, added for code clarity */
9289
       err = MP_OKAY;
9290
   }
9291
   else if (err != SA_SILIB_RET_OK) {
9292
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
9293
       return err;
9294
   }
9295
   else {
9296
       /* valid signature. */
9297
       *res = 1;
9298
       err = MP_OKAY;
9299
   }
9300
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9301
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
9302
                                hash, hashlen,
9303
                                res, key);
9304
#elif defined(WOLFSSL_KCAPI_ECC)
9305
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
9306
    if (err == 0) {
9307
        *res = 1;
9308
    }
9309
#elif defined(WOLFSSL_SE050)
9310
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9311
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9312
    if (hashlen > sizeof(hashcopy))
9313
        return ECC_BAD_ARG_E;
9314
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
9315
    mp_reverse(sigRS, keySz);
9316
    mp_reverse(sigRS + keySz, keySz);
9317
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
9318
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
9319
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
9320
9321
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
9322
                                     xil_curve_type[key->dp->id],
9323
                                     XIL_CAST_U64(hashcopy), keySz,
9324
                                     XIL_CAST_U64(key->keyRaw),
9325
                                     XIL_CAST_U64(sigRS));
9326
9327
    if (err != XST_SUCCESS) {
9328
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
9329
        err = WC_HW_E;
9330
    } else {
9331
        *res = 1;
9332
    }
9333
#endif
9334
9335
#else
9336
  /* checking if private key with no public part */
9337
1.27k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
9338
601
      WOLFSSL_MSG("Verify called with private key, generating public part");
9339
601
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9340
601
      if (err != MP_OKAY) {
9341
1
          return err;
9342
1
      }
9343
600
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9344
600
      if (err != MP_OKAY) {
9345
0
          FREE_CURVE_SPECS();
9346
0
          return err;
9347
0
      }
9348
600
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
9349
600
      if (err != MP_OKAY) {
9350
9
           WOLFSSL_MSG("Unable to extract public key");
9351
9
           wc_ecc_curve_free(curve);
9352
9
           FREE_CURVE_SPECS();
9353
9
           return err;
9354
9
      }
9355
591
      curveLoaded = 1;
9356
591
  }
9357
9358
1.26k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
9359
1.26k
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
9360
0
      if (curveLoaded) {
9361
0
           wc_ecc_curve_free(curve);
9362
0
           FREE_CURVE_SPECS();
9363
0
      }
9364
0
      return err;
9365
0
  }
9366
9367
1.26k
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
9368
1.26k
   if (!curveLoaded) {
9369
675
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
9370
675
       if (err != 0) {
9371
0
          return err;
9372
0
       }
9373
       /* read in the specs for this curve */
9374
675
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
9375
675
       if (err != 0) {
9376
0
          FREE_CURVE_SPECS();
9377
0
          return err;
9378
0
       }
9379
675
   }
9380
9381
1.26k
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
9382
1.26k
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9383
9384
1.26k
   (void)curveLoaded;
9385
1.26k
   wc_ecc_curve_free(curve);
9386
1.26k
   FREE_CURVE_SPECS();
9387
1.26k
#endif /* HAVE_ECC_VERIFY_HELPER */
9388
9389
1.26k
   (void)keySz;
9390
1.26k
   (void)hashlen;
9391
9392
1.26k
   return err;
9393
1.26k
#endif /* WOLFSSL_STM32_PKA */
9394
1.26k
}
9395
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
9396
#endif /* HAVE_ECC_VERIFY */
9397
9398
#ifdef HAVE_ECC_KEY_IMPORT
9399
/* import point from der
9400
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
9401
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
9402
                               const int curve_idx, ecc_point* point,
9403
                               int shortKeySize)
9404
14
{
9405
14
    int err = 0;
9406
14
#ifdef HAVE_COMP_KEY
9407
14
    int compressed = 0;
9408
14
#endif
9409
14
    int keysize;
9410
14
    byte pointType;
9411
9412
#ifndef HAVE_COMP_KEY
9413
    (void)shortKeySize;
9414
#endif
9415
9416
14
    if (in == NULL || point == NULL || (curve_idx < 0) ||
9417
14
        (wc_ecc_is_valid_idx(curve_idx) == 0))
9418
0
        return ECC_BAD_ARG_E;
9419
9420
    /* must be odd */
9421
14
    if ((inLen & 1) == 0) {
9422
0
        return ECC_BAD_ARG_E;
9423
0
    }
9424
9425
    /* clear if previously allocated */
9426
14
    mp_clear(point->x);
9427
14
    mp_clear(point->y);
9428
14
    mp_clear(point->z);
9429
9430
    /* init point */
9431
#ifdef ALT_ECC_SIZE
9432
    point->x = (mp_int*)&point->xyz[0];
9433
    point->y = (mp_int*)&point->xyz[1];
9434
    point->z = (mp_int*)&point->xyz[2];
9435
    alt_fp_init(point->x);
9436
    alt_fp_init(point->y);
9437
    alt_fp_init(point->z);
9438
#else
9439
14
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
9440
14
#endif
9441
14
    if (err != MP_OKAY)
9442
0
        return MEMORY_E;
9443
9444
14
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
9445
9446
    /* check for point type (4, 2, or 3) */
9447
14
    pointType = in[0];
9448
14
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
9449
0
                                         pointType != ECC_POINT_COMP_ODD) {
9450
0
        err = ASN_PARSE_E;
9451
0
    }
9452
9453
14
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
9454
0
#ifdef HAVE_COMP_KEY
9455
0
        compressed = 1;
9456
#else
9457
        err = NOT_COMPILED_IN;
9458
#endif
9459
0
    }
9460
9461
    /* adjust to skip first byte */
9462
14
    inLen -= 1;
9463
14
    in += 1;
9464
9465
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
9466
     * is true */
9467
14
#ifdef HAVE_COMP_KEY
9468
14
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
9469
#else
9470
    keysize = (int)(inLen>>1);
9471
#endif
9472
9473
    /* read data */
9474
14
    if (err == MP_OKAY)
9475
14
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
9476
9477
14
#ifdef HAVE_COMP_KEY
9478
14
    if (err == MP_OKAY && compressed == 1) {   /* build y */
9479
    #if defined(WOLFSSL_HAVE_SP_ECC)
9480
        #ifndef WOLFSSL_SP_NO_256
9481
        if (curve_idx != ECC_CUSTOM_IDX &&
9482
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
9483
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
9484
        }
9485
        else
9486
        #endif
9487
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9488
        if (curve_idx != ECC_CUSTOM_IDX &&
9489
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
9490
            sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
9491
        }
9492
        else
9493
        #endif
9494
        #ifdef WOLFSSL_SP_384
9495
        if (curve_idx != ECC_CUSTOM_IDX &&
9496
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
9497
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
9498
        }
9499
        else
9500
        #endif
9501
        #ifdef WOLFSSL_SP_521
9502
        if (curve_idx != ECC_CUSTOM_IDX &&
9503
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
9504
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
9505
        }
9506
        else
9507
        #endif
9508
    #endif
9509
0
    #if !defined(WOLFSSL_SP_MATH)
9510
0
        {
9511
0
            int did_init = 0;
9512
0
        #ifdef WOLFSSL_SMALL_STACK
9513
0
            mp_int* t1 = NULL;
9514
0
            mp_int* t2 = NULL;
9515
        #else
9516
            mp_int t1[1], t2[1];
9517
        #endif
9518
0
            DECLARE_CURVE_SPECS(3);
9519
9520
0
            ALLOC_CURVE_SPECS(3, err);
9521
9522
0
        #ifdef WOLFSSL_SMALL_STACK
9523
0
            if (err == MP_OKAY) {
9524
0
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9525
0
                                      DYNAMIC_TYPE_BIGINT);
9526
0
                if (t1 == NULL) {
9527
0
                    err = MEMORY_E;
9528
0
                }
9529
0
            }
9530
0
            if (err == MP_OKAY) {
9531
0
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
9532
0
                                      DYNAMIC_TYPE_BIGINT);
9533
0
                if (t2 == NULL) {
9534
0
                    err = MEMORY_E;
9535
0
                }
9536
0
            }
9537
0
        #endif
9538
9539
0
            if (err == MP_OKAY) {
9540
0
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
9541
0
                    err = MEMORY_E;
9542
0
                else
9543
0
                    did_init = 1;
9544
0
            }
9545
9546
            /* load curve info */
9547
0
            if (err == MP_OKAY)
9548
0
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
9549
0
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
9550
0
                        ECC_CURVE_FIELD_BF));
9551
9552
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
9553
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
9554
            /* validate prime is prime for custom curves */
9555
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
9556
                int isPrime = MP_NO;
9557
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
9558
                if (err == MP_OKAY && isPrime == MP_NO)
9559
                    err = MP_VAL;
9560
            }
9561
        #endif
9562
9563
            /* compute x^3 */
9564
0
            if (err == MP_OKAY)
9565
0
                err = mp_sqr(point->x, t1);
9566
0
            if (err == MP_OKAY)
9567
0
                err = mp_mulmod(t1, point->x, curve->prime, t1);
9568
9569
            /* compute x^3 + a*x */
9570
0
            if (err == MP_OKAY)
9571
0
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
9572
0
            if (err == MP_OKAY)
9573
0
                err = mp_add(t1, t2, t1);
9574
9575
            /* compute x^3 + a*x + b */
9576
0
            if (err == MP_OKAY)
9577
0
                err = mp_add(t1, curve->Bf, t1);
9578
9579
            /* compute sqrt(x^3 + a*x + b) */
9580
0
            if (err == MP_OKAY)
9581
0
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
9582
9583
            /* adjust y */
9584
0
            if (err == MP_OKAY) {
9585
0
                if ((mp_isodd(t2) == MP_YES &&
9586
0
                                            pointType == ECC_POINT_COMP_ODD) ||
9587
0
                    (mp_isodd(t2) == MP_NO &&
9588
0
                                            pointType == ECC_POINT_COMP_EVEN)) {
9589
0
                    err = mp_mod(t2, curve->prime, point->y);
9590
0
                }
9591
0
                else {
9592
0
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
9593
0
                }
9594
0
            }
9595
9596
0
            if (did_init) {
9597
0
                mp_clear(t2);
9598
0
                mp_clear(t1);
9599
0
            }
9600
9601
0
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
9602
0
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
9603
9604
0
            wc_ecc_curve_free(curve);
9605
0
            FREE_CURVE_SPECS();
9606
0
        }
9607
    #else
9608
        {
9609
            err = WC_KEY_SIZE_E;
9610
        }
9611
    #endif
9612
0
    }
9613
14
#endif
9614
9615
14
    if (err == MP_OKAY) {
9616
13
#ifdef HAVE_COMP_KEY
9617
13
        if (compressed == 0)
9618
13
#endif
9619
13
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
9620
13
    }
9621
14
    if (err == MP_OKAY)
9622
11
        err = mp_set(point->z, 1);
9623
9624
14
    if (err != MP_OKAY) {
9625
3
        mp_clear(point->x);
9626
3
        mp_clear(point->y);
9627
3
        mp_clear(point->z);
9628
3
    }
9629
9630
14
    RESTORE_VECTOR_REGISTERS();
9631
9632
14
    return err;
9633
14
}
9634
9635
/* function for backwards compatibility with previous implementations */
9636
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
9637
                            ecc_point* point)
9638
154
{
9639
154
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
9640
154
}
9641
#endif /* HAVE_ECC_KEY_IMPORT */
9642
9643
#ifdef HAVE_ECC_KEY_EXPORT
9644
/* export point to der */
9645
9646
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
9647
                               word32* outLen, int compressed)
9648
0
{
9649
0
    if (compressed == 0)
9650
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
9651
0
#ifdef HAVE_COMP_KEY
9652
0
    else
9653
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
9654
#else
9655
    return NOT_COMPILED_IN;
9656
#endif
9657
0
}
9658
9659
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
9660
                            word32* outLen)
9661
432
{
9662
432
    int    ret = MP_OKAY;
9663
432
    word32 numlen;
9664
432
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9665
9666
432
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9667
0
        return ECC_BAD_ARG_E;
9668
9669
432
    numlen = (word32)ecc_sets[curve_idx].size;
9670
9671
    /* return length needed only */
9672
432
    if (point != NULL && out == NULL && outLen != NULL) {
9673
22
        *outLen = 1 + 2*numlen;
9674
22
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9675
22
    }
9676
9677
410
    if (point == NULL || out == NULL || outLen == NULL)
9678
0
        return ECC_BAD_ARG_E;
9679
9680
410
    if (*outLen < (1 + 2*numlen)) {
9681
26
        *outLen = 1 + 2*numlen;
9682
26
        return BUFFER_E;
9683
26
    }
9684
9685
    /* Sanity check the ordinates' sizes. */
9686
384
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
9687
342
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
9688
92
        return ECC_BAD_ARG_E;
9689
92
    }
9690
9691
    /* store byte point type */
9692
292
    out[0] = ECC_POINT_UNCOMP;
9693
9694
292
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9695
292
        return MEMORY_E);
9696
9697
    /* pad and store x */
9698
163
    XMEMSET(buf, 0, ECC_BUFSIZE);
9699
163
    ret = mp_to_unsigned_bin(point->x, buf +
9700
163
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
9701
163
    if (ret != MP_OKAY)
9702
5
        goto done;
9703
158
    XMEMCPY(out+1, buf, numlen);
9704
9705
    /* pad and store y */
9706
158
    XMEMSET(buf, 0, ECC_BUFSIZE);
9707
158
    ret = mp_to_unsigned_bin(point->y, buf +
9708
158
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
9709
158
    if (ret != MP_OKAY)
9710
4
        goto done;
9711
154
    XMEMCPY(out+1+numlen, buf, numlen);
9712
9713
154
    *outLen = 1 + 2*numlen;
9714
9715
163
done:
9716
163
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9717
9718
163
    return ret;
9719
154
}
9720
9721
9722
/* export point to der */
9723
#ifdef HAVE_COMP_KEY
9724
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
9725
                                       byte* out, word32* outLen)
9726
0
{
9727
0
    int    ret = MP_OKAY;
9728
0
    word32 numlen;
9729
0
    word32 output_len;
9730
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9731
9732
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
9733
0
        return ECC_BAD_ARG_E;
9734
9735
0
    numlen = (word32)ecc_sets[curve_idx].size;
9736
0
    output_len = 1 + numlen; /* y point type + x */
9737
9738
    /* return length needed only */
9739
0
    if (point != NULL && out == NULL && outLen != NULL) {
9740
0
        *outLen = output_len;
9741
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9742
0
    }
9743
9744
0
    if (point == NULL || out == NULL || outLen == NULL)
9745
0
        return ECC_BAD_ARG_E;
9746
9747
9748
0
    if (*outLen < output_len) {
9749
0
        *outLen = output_len;
9750
0
        return BUFFER_E;
9751
0
    }
9752
9753
    /* Sanity check the ordinate's size. */
9754
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
9755
0
        return ECC_BAD_ARG_E;
9756
0
    }
9757
9758
    /* store byte point type */
9759
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
9760
0
                                            ECC_POINT_COMP_EVEN;
9761
9762
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9763
0
        return MEMORY_E);
9764
9765
    /* pad and store x */
9766
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
9767
0
    ret = mp_to_unsigned_bin(point->x, buf +
9768
0
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
9769
0
    if (ret != MP_OKAY)
9770
0
        goto done;
9771
0
    XMEMCPY(out+1, buf, numlen);
9772
9773
0
    *outLen = output_len;
9774
9775
0
done:
9776
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9777
9778
0
    return ret;
9779
0
}
9780
#endif /* HAVE_COMP_KEY */
9781
9782
/* export public ECC key in ANSI X9.63 format */
9783
WOLFSSL_ABI
9784
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
9785
12.8k
{
9786
12.8k
   int    ret = MP_OKAY;
9787
12.8k
   word32 numlen;
9788
12.8k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
9789
12.8k
   word32 pubxlen, pubylen;
9790
9791
   /* return length needed only */
9792
12.8k
   if (key != NULL && out == NULL && outLen != NULL) {
9793
      /* if key hasn't been setup assume max bytes for size estimation */
9794
2.17k
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
9795
2.17k
      *outLen = 1 + 2 * numlen;
9796
2.17k
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9797
2.17k
   }
9798
9799
10.6k
   if (key == NULL || out == NULL || outLen == NULL)
9800
0
      return ECC_BAD_ARG_E;
9801
9802
10.6k
   if (key->type == ECC_PRIVATEKEY_ONLY)
9803
242
       return ECC_PRIVATEONLY_E;
9804
9805
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
9806
    /* check if public key in secure memory */
9807
    if (key->securePubKey > 0) {
9808
        int keySz = wc_ecc_size(key);
9809
9810
        /* store byte point type */
9811
        out[0] = ECC_POINT_UNCOMP;
9812
9813
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
9814
            return WC_HW_E;
9815
9816
        *outLen = 1 + 2*keySz;
9817
        return MP_OKAY;
9818
    }
9819
#endif
9820
9821
10.3k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
9822
1.20k
       return ECC_BAD_ARG_E;
9823
1.20k
   }
9824
9825
9.19k
   numlen = (word32)key->dp->size;
9826
9827
    /* verify room in out buffer */
9828
9.19k
   if (*outLen < (1 + 2*numlen)) {
9829
0
      *outLen = 1 + 2*numlen;
9830
0
      return BUFFER_E;
9831
0
   }
9832
9833
   /* verify public key length is less than key size */
9834
9.19k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
9835
9.19k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
9836
9.19k
   if ((pubxlen > numlen) || (pubylen > numlen)) {
9837
0
      WOLFSSL_MSG("Public key x/y invalid!");
9838
0
      return BUFFER_E;
9839
0
   }
9840
9841
   /* store byte point type */
9842
9.19k
   out[0] = ECC_POINT_UNCOMP;
9843
9844
9.19k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
9845
9.19k
       return MEMORY_E);
9846
9847
   /* pad and store x */
9848
9.06k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9849
9.06k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
9850
9.06k
   if (ret != MP_OKAY)
9851
13
      goto done;
9852
9.04k
   XMEMCPY(out+1, buf, numlen);
9853
9854
   /* pad and store y */
9855
9.04k
   XMEMSET(buf, 0, ECC_BUFSIZE);
9856
9.04k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
9857
9.04k
   if (ret != MP_OKAY)
9858
19
      goto done;
9859
9.02k
   XMEMCPY(out+1+numlen, buf, numlen);
9860
9861
9.02k
   *outLen = 1 + 2*numlen;
9862
9863
9.06k
done:
9864
9.06k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
9865
9866
9.06k
   return ret;
9867
9.02k
}
9868
9869
9870
/* export public ECC key in ANSI X9.63 format, extended with
9871
 * compression option */
9872
WOLFSSL_ABI
9873
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
9874
                          int compressed)
9875
7.50k
{
9876
7.50k
    if (compressed == 0)
9877
4.65k
        return wc_ecc_export_x963(key, out, outLen);
9878
2.84k
#ifdef HAVE_COMP_KEY
9879
2.84k
    else
9880
2.84k
        return wc_ecc_export_x963_compressed(key, out, outLen);
9881
#else
9882
    return NOT_COMPILED_IN;
9883
#endif
9884
7.50k
}
9885
#endif /* HAVE_ECC_KEY_EXPORT */
9886
9887
9888
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
9889
9890
/* is ecc point on curve described by dp ? */
9891
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
9892
4.91k
{
9893
4.91k
#if !defined(WOLFSSL_SP_MATH)
9894
4.91k
   int err;
9895
4.91k
#ifdef WOLFSSL_SMALL_STACK
9896
4.91k
   mp_int* t1;
9897
4.91k
   mp_int* t2;
9898
#else
9899
   mp_int  t1[1], t2[1];
9900
#endif
9901
9902
4.91k
#ifdef WOLFSSL_SMALL_STACK
9903
4.91k
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9904
4.91k
   if (t1 == NULL)
9905
77
       return MEMORY_E;
9906
4.83k
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
9907
4.83k
   if (t2 == NULL) {
9908
52
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
9909
52
       return MEMORY_E;
9910
52
   }
9911
4.78k
#endif
9912
9913
4.78k
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
9914
0
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9915
0
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9916
0
      return err;
9917
0
   }
9918
9919
4.78k
   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
9920
9921
   /* compute y^2 */
9922
4.78k
   if (err == MP_OKAY)
9923
4.78k
       err = mp_sqr(ecp->y, t1);
9924
9925
   /* compute x^3 */
9926
4.78k
   if (err == MP_OKAY)
9927
4.73k
       err = mp_sqr(ecp->x, t2);
9928
4.78k
   if (err == MP_OKAY)
9929
4.70k
       err = mp_mod(t2, prime, t2);
9930
4.78k
   if (err == MP_OKAY)
9931
4.68k
       err = mp_mul(ecp->x, t2, t2);
9932
9933
   /* compute y^2 - x^3 */
9934
4.78k
   if (err == MP_OKAY)
9935
4.68k
       err = mp_submod(t1, t2, prime, t1);
9936
9937
   /* Determine if curve "a" should be used in calc */
9938
4.78k
#ifdef WOLFSSL_CUSTOM_CURVES
9939
4.78k
   if (err == MP_OKAY) {
9940
      /* Use a and prime to determine if a == 3 */
9941
4.52k
      err = mp_set(t2, 0);
9942
4.52k
      if (err == MP_OKAY)
9943
4.52k
          err = mp_submod(prime, a, prime, t2);
9944
4.52k
   }
9945
4.78k
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
9946
      /* compute y^2 - x^3 + a*x */
9947
2.11k
      if (err == MP_OKAY)
9948
2.11k
          err = mp_mulmod(t2, ecp->x, prime, t2);
9949
2.11k
      if (err == MP_OKAY)
9950
2.09k
          err = mp_addmod(t1, t2, prime, t1);
9951
2.11k
   }
9952
2.67k
   else
9953
2.67k
#endif /* WOLFSSL_CUSTOM_CURVES */
9954
2.67k
   {
9955
      /* assumes "a" == 3 */
9956
2.67k
      (void)a;
9957
9958
      /* compute y^2 - x^3 + 3x */
9959
2.67k
      if (err == MP_OKAY)
9960
2.40k
          err = mp_add(t1, ecp->x, t1);
9961
2.67k
      if (err == MP_OKAY)
9962
2.40k
          err = mp_add(t1, ecp->x, t1);
9963
2.67k
      if (err == MP_OKAY)
9964
2.40k
          err = mp_add(t1, ecp->x, t1);
9965
2.67k
      if (err == MP_OKAY)
9966
2.40k
          err = mp_mod(t1, prime, t1);
9967
2.67k
  }
9968
9969
   /* adjust range (0, prime) */
9970
4.78k
   while (err == MP_OKAY && mp_isneg(t1)) {
9971
0
      err = mp_add(t1, prime, t1);
9972
0
   }
9973
4.78k
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
9974
0
      err = mp_sub(t1, prime, t1);
9975
0
   }
9976
9977
   /* compare to b */
9978
4.78k
   if (err == MP_OKAY) {
9979
4.44k
       if (mp_cmp(t1, b) != MP_EQ) {
9980
1.48k
          err = IS_POINT_E;
9981
2.96k
       } else {
9982
2.96k
          err = MP_OKAY;
9983
2.96k
       }
9984
4.44k
   }
9985
9986
4.78k
   mp_clear(t1);
9987
4.78k
   mp_clear(t2);
9988
9989
4.78k
   RESTORE_VECTOR_REGISTERS();
9990
9991
4.78k
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
9992
4.78k
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
9993
9994
4.78k
   return err;
9995
#else
9996
   (void)a;
9997
   (void)b;
9998
9999
#ifdef WOLFSSL_HAVE_SP_ECC
10000
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10001
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10002
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10003
   }
10004
#endif
10005
#ifndef WOLFSSL_SP_NO_256
10006
   if (mp_count_bits(prime) == 256) {
10007
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10008
   }
10009
#endif
10010
#ifdef WOLFSSL_SP_384
10011
   if (mp_count_bits(prime) == 384) {
10012
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10013
   }
10014
#endif
10015
#ifdef WOLFSSL_SP_521
10016
   if (mp_count_bits(prime) == 521) {
10017
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10018
   }
10019
#endif
10020
#else
10021
   (void)ecp;
10022
   (void)prime;
10023
#endif
10024
   return WC_KEY_SIZE_E;
10025
#endif
10026
4.78k
}
10027
10028
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10029
2.60k
{
10030
2.60k
    int err = MP_OKAY;
10031
10032
    /* Validate parameters. */
10033
2.60k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10034
0
        err = BAD_FUNC_ARG;
10035
0
    }
10036
10037
2.60k
    if (err == MP_OKAY) {
10038
        /* x must be in the range [0, p-1] */
10039
2.60k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10040
275
            err = ECC_OUT_OF_RANGE_E;
10041
275
        }
10042
2.60k
    }
10043
10044
2.60k
    if (err == MP_OKAY) {
10045
        /* y must be in the range [0, p-1] */
10046
2.32k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10047
189
            err = ECC_OUT_OF_RANGE_E;
10048
189
        }
10049
2.32k
    }
10050
10051
2.60k
    if (err == MP_OKAY) {
10052
        /* z must be one, that is point must be in affine form. */
10053
2.13k
        if (!mp_isone(ecp->z)) {
10054
683
            err = ECC_BAD_ARG_E;
10055
683
        }
10056
2.13k
    }
10057
10058
2.60k
    if (err == MP_OKAY) {
10059
        /* Check x and y are valid for curve equation. */
10060
1.45k
        err = _ecc_is_point(ecp, a, b, prime);
10061
1.45k
    }
10062
10063
2.60k
    return err;
10064
2.60k
}
10065
10066
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10067
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10068
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10069
/* validate privkey * generator == pubkey, 0 on success */
10070
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10071
{
10072
    int        err;
10073
    ecc_point* base = NULL;
10074
    ecc_point* res  = NULL;
10075
#ifdef WOLFSSL_NO_MALLOC
10076
    ecc_point lcl_base;
10077
    ecc_point lcl_res;
10078
#endif
10079
    DECLARE_CURVE_SPECS(3);
10080
10081
    if (key == NULL)
10082
        return BAD_FUNC_ARG;
10083
10084
    ALLOC_CURVE_SPECS(3, err);
10085
    if (err != MP_OKAY) {
10086
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10087
        return err;
10088
    }
10089
10090
#ifdef WOLFSSL_NO_MALLOC
10091
    res = &lcl_res;
10092
#endif
10093
    err = wc_ecc_new_point_ex(&res, key->heap);
10094
10095
#ifdef WOLFSSL_HAVE_SP_ECC
10096
#ifndef WOLFSSL_SP_NO_256
10097
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10098
        if (err == MP_OKAY) {
10099
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10100
        }
10101
    }
10102
    else
10103
#endif
10104
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10105
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10106
        if (err == MP_OKAY) {
10107
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10108
        }
10109
    }
10110
    else
10111
#endif
10112
#ifdef WOLFSSL_SP_384
10113
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10114
        if (err == MP_OKAY) {
10115
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10116
        }
10117
    }
10118
    else
10119
#endif
10120
#ifdef WOLFSSL_SP_521
10121
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10122
        if (err == MP_OKAY) {
10123
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10124
        }
10125
    }
10126
    else
10127
#endif
10128
#endif
10129
    {
10130
        if (err == MP_OKAY) {
10131
        #ifdef WOLFSSL_NO_MALLOC
10132
            base = &lcl_base;
10133
        #endif
10134
            err = wc_ecc_new_point_ex(&base, key->heap);
10135
        }
10136
10137
        if (err == MP_OKAY) {
10138
            /* load curve info */
10139
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10140
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10141
        }
10142
10143
        /* set up base generator */
10144
        if (err == MP_OKAY)
10145
            err = mp_copy(curve->Gx, base->x);
10146
        if (err == MP_OKAY)
10147
            err = mp_copy(curve->Gy, base->y);
10148
        if (err == MP_OKAY)
10149
            err = mp_set(base->z, 1);
10150
10151
#ifdef WOLFSSL_KCAPI_ECC
10152
        if (err == MP_OKAY) {
10153
            word32 pubkey_sz = (word32)key->dp->size*2;
10154
            if (key->handle == NULL) {
10155
                /* if handle loaded, then pubkey_raw already populated */
10156
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10157
            }
10158
            if (err == 0) {
10159
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10160
                                           pubkey_sz/2);
10161
            }
10162
            if (err == MP_OKAY) {
10163
                err = mp_read_unsigned_bin(res->y,
10164
                                           key->pubkey_raw + pubkey_sz/2,
10165
                                           pubkey_sz/2);
10166
            }
10167
            if (err == MP_OKAY) {
10168
                err = mp_set(res->z, 1);
10169
            }
10170
        }
10171
        (void)a;
10172
        (void)prime;
10173
#else
10174
#ifdef ECC_TIMING_RESISTANT
10175
        if (err == MP_OKAY)
10176
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10177
                                          curve->order, key->rng, 1, key->heap);
10178
#else
10179
        if (err == MP_OKAY)
10180
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10181
                                              curve->order, NULL, 1, key->heap);
10182
#endif
10183
#endif /* WOLFSSL_KCAPI_ECC */
10184
    }
10185
10186
    if (err == MP_OKAY) {
10187
        /* compare result to public key */
10188
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10189
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10190
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10191
            /* didn't match */
10192
            err = ECC_PRIV_KEY_E;
10193
        }
10194
    }
10195
10196
    wc_ecc_curve_free(curve);
10197
    wc_ecc_del_point_ex(res, key->heap);
10198
    wc_ecc_del_point_ex(base, key->heap);
10199
    FREE_CURVE_SPECS();
10200
10201
    return err;
10202
}
10203
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10204
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10205
10206
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10207
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10208
10209
/* check privkey generator helper, creates prime needed */
10210
static int ecc_check_privkey_gen_helper(ecc_key* key)
10211
{
10212
    int    err;
10213
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
10214
    DECLARE_CURVE_SPECS(2);
10215
#endif
10216
10217
    if (key == NULL)
10218
        return BAD_FUNC_ARG;
10219
10220
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10221
    /* Hardware based private key, so this operation is not supported */
10222
    err = MP_OKAY; /* just report success */
10223
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10224
    /* Hardware based private key, so this operation is not supported */
10225
    err = MP_OKAY; /* just report success */
10226
#elif defined(WOLFSSL_KCAPI_ECC)
10227
    /* Hardware based private key, so this operation is not supported */
10228
    err = MP_OKAY; /* just report success */
10229
#else
10230
    ALLOC_CURVE_SPECS(2, err);
10231
10232
    /* load curve info */
10233
    if (err == MP_OKAY)
10234
        err = wc_ecc_curve_load(key->dp, &curve,
10235
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10236
10237
    if (err == MP_OKAY)
10238
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10239
10240
    wc_ecc_curve_free(curve);
10241
    FREE_CURVE_SPECS();
10242
10243
#endif /* WOLFSSL_ATECC508A */
10244
10245
    return err;
10246
}
10247
10248
/* Performs a Pairwise Consistency Test on an ECC key pair. */
10249
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10250
{
10251
    int err = 0;
10252
    word32 flags = key->flags;
10253
10254
    /* If flags not set default to cofactor and dec/sign */
10255
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10256
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10257
    }
10258
10259
    if (flags & WC_ECC_FLAG_COFACTOR) {
10260
        err = ecc_check_privkey_gen_helper(key);
10261
    }
10262
10263
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10264
#ifndef WOLFSSL_SMALL_STACK
10265
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10266
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10267
#else
10268
        byte* sig;
10269
#endif
10270
        byte* digest;
10271
        word32 sigLen, digestLen;
10272
        int dynRng = 0, res = 0;
10273
10274
        sigLen = (word32)wc_ecc_sig_size(key);
10275
        digestLen = WC_SHA256_DIGEST_SIZE;
10276
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
10277
            DYNAMIC_TYPE_ECC, return MEMORY_E);
10278
        digest = sig + sigLen;
10279
10280
        if (rng == NULL) {
10281
            dynRng = 1;
10282
            rng = wc_rng_new(NULL, 0, key->heap);
10283
            if (rng == NULL) {
10284
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10285
                return MEMORY_E;
10286
            }
10287
        }
10288
10289
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10290
10291
        if (!err)
10292
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10293
                    rng, key);
10294
        if (!err)
10295
            err = wc_ecc_verify_hash(sig, sigLen,
10296
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10297
10298
        if (res == 0)
10299
            err = ECC_PCT_E;
10300
10301
        if (dynRng) {
10302
            wc_rng_free(rng);
10303
        }
10304
        ForceZero(sig, sigLen + digestLen);
10305
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10306
    }
10307
    (void)rng;
10308
10309
    if (err != 0)
10310
        err = ECC_PCT_E;
10311
10312
    return err;
10313
}
10314
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10315
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10316
10317
#ifndef WOLFSSL_SP_MATH
10318
/* validate order * pubkey = point at infinity, 0 on success */
10319
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10320
        mp_int* prime, mp_int* order)
10321
6.42k
{
10322
6.42k
    ecc_point* inf = NULL;
10323
#ifdef WOLFSSL_NO_MALLOC
10324
    ecc_point  lcl_inf;
10325
#endif
10326
6.42k
    int err;
10327
10328
6.42k
    if (key == NULL)
10329
0
        return BAD_FUNC_ARG;
10330
6.42k
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10331
6.42k
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10332
6.42k
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10333
0
       return IS_POINT_E;
10334
0
   }
10335
10336
#ifdef WOLFSSL_NO_MALLOC
10337
    inf = &lcl_inf;
10338
#endif
10339
6.42k
    err = wc_ecc_new_point_ex(&inf, key->heap);
10340
6.42k
    if (err == MP_OKAY) {
10341
#ifdef WOLFSSL_HAVE_SP_ECC
10342
#ifndef WOLFSSL_SP_NO_256
10343
        if (key->idx != ECC_CUSTOM_IDX &&
10344
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
10345
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
10346
        }
10347
        else
10348
#endif
10349
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10350
        if (key->idx != ECC_CUSTOM_IDX &&
10351
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
10352
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
10353
        }
10354
        else
10355
#endif
10356
#ifdef WOLFSSL_SP_384
10357
        if (key->idx != ECC_CUSTOM_IDX &&
10358
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
10359
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
10360
        }
10361
        else
10362
#endif
10363
#ifdef WOLFSSL_SP_521
10364
        if (key->idx != ECC_CUSTOM_IDX &&
10365
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
10366
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
10367
        }
10368
        else
10369
#endif
10370
#endif
10371
6.41k
#if !defined(WOLFSSL_SP_MATH)
10372
6.41k
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10373
6.41k
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10374
18
            err = ECC_INF_E;
10375
#else
10376
        {
10377
            (void)a;
10378
            (void)prime;
10379
10380
            err = WC_KEY_SIZE_E;
10381
        }
10382
#endif
10383
6.41k
    }
10384
10385
6.42k
    wc_ecc_del_point_ex(inf, key->heap);
10386
10387
6.42k
    return err;
10388
6.42k
}
10389
#endif /* !WOLFSSL_SP_MATH */
10390
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10391
10392
10393
#ifdef OPENSSL_EXTRA
10394
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
10395
{
10396
    int err = MP_OKAY;
10397
    DECLARE_CURVE_SPECS(2);
10398
10399
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
10400
        return BAD_FUNC_ARG;
10401
10402
    ALLOC_CURVE_SPECS(2, err);
10403
10404
    if (err == MP_OKAY)
10405
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10406
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
10407
    if (err == MP_OKAY)
10408
        err = mp_copy(curve->Gx, ecp->x);
10409
    if (err == MP_OKAY)
10410
        err = mp_copy(curve->Gy, ecp->y);
10411
    if (err == MP_OKAY)
10412
        err = mp_set(ecp->z, 1);
10413
10414
    wc_ecc_curve_free(curve);
10415
    FREE_CURVE_SPECS();
10416
10417
    return err;
10418
}
10419
#endif /* OPENSSL_EXTRA */
10420
10421
10422
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
10423
 * ECC Full Public Key Validation Routine. If the parameter
10424
 * partial is set, then it follows section 5.6.2.3.4, the ECC
10425
 * Partial Public Key Validation Routine.
10426
 * If the parameter priv is set, add in a few extra
10427
 * checks on the bounds of the private key. */
10428
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
10429
1.71k
{
10430
1.71k
    int err = MP_OKAY;
10431
1.71k
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10432
1.71k
    mp_int* b = NULL;
10433
1.71k
    #ifdef USE_ECC_B_PARAM
10434
1.71k
        DECLARE_CURVE_SPECS(4);
10435
    #else
10436
        #ifndef WOLFSSL_SMALL_STACK
10437
            mp_int b_lcl;
10438
        #endif
10439
        DECLARE_CURVE_SPECS(3);
10440
    #endif /* USE_ECC_B_PARAM */
10441
1.71k
#endif
10442
10443
1.71k
    ASSERT_SAVED_VECTOR_REGISTERS();
10444
10445
1.71k
    if (key == NULL)
10446
0
        return BAD_FUNC_ARG;
10447
10448
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
10449
    /* consider key check success on HW crypto
10450
     * ex: ATECC508/608A, CryptoCell and Silabs
10451
     *
10452
     * consider key check success on most Crypt Cb only builds
10453
     */
10454
    err = MP_OKAY;
10455
10456
#else
10457
10458
#ifdef WOLFSSL_HAVE_SP_ECC
10459
#ifndef WOLFSSL_SP_NO_256
10460
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10461
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10462
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10463
    }
10464
#endif
10465
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10466
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10467
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10468
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10469
    }
10470
#endif
10471
#ifdef WOLFSSL_SP_384
10472
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10473
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10474
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10475
    }
10476
#endif
10477
#ifdef WOLFSSL_SP_521
10478
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10479
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10480
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10481
    }
10482
#endif
10483
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
10484
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
10485
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
10486
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10487
    }
10488
#endif
10489
#endif
10490
10491
1.71k
#ifndef WOLFSSL_SP_MATH
10492
1.71k
    #ifdef USE_ECC_B_PARAM
10493
1.71k
        ALLOC_CURVE_SPECS(4, err);
10494
    #else
10495
        ALLOC_CURVE_SPECS(3, err);
10496
        #ifndef WOLFSSL_SMALL_STACK
10497
            b = &b_lcl;
10498
        #else
10499
            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10500
            if (b == NULL) {
10501
                FREE_CURVE_SPECS();
10502
                return MEMORY_E;
10503
            }
10504
        #endif
10505
        XMEMSET(b, 0, sizeof(mp_int));
10506
    #endif
10507
10508
    #ifdef WOLFSSL_CAAM
10509
    /* keys can be black encrypted ones which can not be checked like plain text
10510
     * keys */
10511
    if (key->blackKey > 0) {
10512
        /* encrypted key was used */
10513
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10514
        FREE_CURVE_SPECS();
10515
        return 0;
10516
    }
10517
    #endif
10518
10519
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
10520
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
10521
    /* pubkey point cannot be at infinity */
10522
1.71k
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10523
0
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10524
0
        FREE_CURVE_SPECS();
10525
0
        return ECC_INF_E;
10526
0
    }
10527
10528
    /* load curve info */
10529
1.71k
    if (err == MP_OKAY)
10530
1.67k
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10531
1.67k
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
10532
1.67k
#ifdef USE_ECC_B_PARAM
10533
1.67k
            | ECC_CURVE_FIELD_BF
10534
1.67k
#endif
10535
1.67k
    ));
10536
10537
#ifndef USE_ECC_B_PARAM
10538
    /* load curve b parameter */
10539
    if (err == MP_OKAY)
10540
        err = mp_init(b);
10541
    if (err == MP_OKAY)
10542
        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
10543
#else
10544
1.71k
    if (err == MP_OKAY)
10545
1.61k
        b = curve->Bf;
10546
1.71k
#endif
10547
10548
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
10549
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
10550
    /* Qx must be in the range [0, p-1] */
10551
1.71k
    if (err == MP_OKAY) {
10552
1.61k
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10553
1.60k
                mp_isneg(key->pubkey.x)) {
10554
11
            err = ECC_OUT_OF_RANGE_E;
10555
11
        }
10556
1.61k
    }
10557
10558
    /* Qy must be in the range [0, p-1] */
10559
1.71k
    if (err == MP_OKAY) {
10560
1.60k
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10561
1.59k
                mp_isneg(key->pubkey.y)) {
10562
10
            err = ECC_OUT_OF_RANGE_E;
10563
10
        }
10564
1.60k
    }
10565
10566
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
10567
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
10568
    /* make sure point is actually on curve */
10569
1.71k
    if (err == MP_OKAY)
10570
1.59k
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10571
10572
1.71k
    if (!partial) {
10573
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10574
        /* pubkey * order must be at infinity */
10575
1.71k
        if (err == MP_OKAY)
10576
1.27k
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10577
1.27k
                    curve->prime, curve->order);
10578
1.71k
    }
10579
10580
1.71k
    if (priv) {
10581
        /* SP 800-56Ar3, section 5.6.2.1.2 */
10582
        /* private keys must be in the range [1, n-1] */
10583
1.71k
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10584
365
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10585
365
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10586
        #ifdef WOLFSSL_KCAPI_ECC
10587
            && key->handle == NULL
10588
        #endif
10589
1.71k
        ) {
10590
0
            err = ECC_PRIV_KEY_E;
10591
0
        }
10592
10593
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
10594
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
10595
        /* private * base generator must equal pubkey */
10596
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
10597
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10598
    #endif
10599
1.71k
    }
10600
10601
1.71k
    wc_ecc_curve_free(curve);
10602
10603
#ifndef USE_ECC_B_PARAM
10604
    mp_clear(b);
10605
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10606
#endif
10607
10608
1.71k
    FREE_CURVE_SPECS();
10609
10610
#else
10611
    /* The single precision math curve is not available */
10612
    err = WC_KEY_SIZE_E;
10613
#endif /* !WOLFSSL_SP_MATH */
10614
1.71k
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10615
10616
1.71k
    (void)partial;
10617
1.71k
    (void)priv;
10618
1.71k
    return err;
10619
1.71k
}
10620
10621
10622
/* perform sanity checks on ecc key validity, 0 on success */
10623
WOLFSSL_ABI
10624
int wc_ecc_check_key(ecc_key* key)
10625
10.4k
{
10626
10.4k
    int ret;
10627
10.4k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10628
10.4k
    ret = _ecc_validate_public_key(key, 0, 1);
10629
10.4k
    RESTORE_VECTOR_REGISTERS();
10630
10.4k
    return ret;
10631
10.4k
}
10632
10633
10634
#ifdef HAVE_ECC_KEY_IMPORT
10635
/* import public ECC key in ANSI X9.63 format */
10636
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
10637
                          int curve_id)
10638
213
{
10639
213
    int err = MP_OKAY;
10640
213
#ifdef HAVE_COMP_KEY
10641
213
    int compressed = 0;
10642
213
#endif
10643
213
    int keysize = 0;
10644
213
    byte pointType;
10645
#ifdef WOLFSSL_CRYPTOCELL
10646
    const CRYS_ECPKI_Domain_t* pDomain;
10647
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10648
#endif
10649
213
    if (in == NULL || key == NULL)
10650
0
        return BAD_FUNC_ARG;
10651
10652
    /* must be odd */
10653
213
    if ((inLen & 1) == 0) {
10654
0
        return ECC_BAD_ARG_E;
10655
0
    }
10656
10657
    /* make sure required variables are reset */
10658
213
    wc_ecc_reset(key);
10659
10660
    /* init key */
10661
    #ifdef ALT_ECC_SIZE
10662
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10663
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10664
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10665
        alt_fp_init(key->pubkey.x);
10666
        alt_fp_init(key->pubkey.y);
10667
        alt_fp_init(key->pubkey.z);
10668
        key->k = (mp_int*)key->ka;
10669
        alt_fp_init(key->k);
10670
    #ifdef WOLFSSL_ECC_BLIND_K
10671
        key->kb = (mp_int*)key->kba;
10672
        key->ku = (mp_int*)key->kua;
10673
        alt_fp_init(key->kb);
10674
        alt_fp_init(key->ku);
10675
    #endif
10676
    #else
10677
213
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10678
213
    #ifndef WOLFSSL_ECC_BLIND_K
10679
213
                                                                      NULL, NULL
10680
    #else
10681
                                                                key->kb, key->ku
10682
    #endif
10683
213
                            );
10684
213
    #endif
10685
213
    if (err != MP_OKAY)
10686
0
        return MEMORY_E;
10687
#ifdef WOLFSSL_ECC_BLIND_K
10688
    mp_forcezero(key->kb);
10689
#endif
10690
10691
213
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10692
10693
    /* check for point type (4, 2, or 3) */
10694
213
    pointType = in[0];
10695
213
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10696
93
                                         pointType != ECC_POINT_COMP_ODD) {
10697
19
        err = ASN_PARSE_E;
10698
19
    }
10699
10700
213
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10701
160
    #ifdef HAVE_COMP_KEY
10702
160
        compressed = 1;
10703
    #else
10704
        err = NOT_COMPILED_IN;
10705
    #endif
10706
160
    }
10707
10708
    /* adjust to skip first byte */
10709
213
    inLen -= 1;
10710
213
    in += 1;
10711
10712
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10713
    /* For SECP256R1 only save raw public key for hardware */
10714
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
10715
    #ifdef HAVE_COMP_KEY
10716
        if (!compressed)
10717
    #endif
10718
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10719
    }
10720
#elif defined(WOLFSSL_KCAPI_ECC)
10721
    XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10722
#endif
10723
10724
213
    if (err == MP_OKAY) {
10725
194
    #ifdef HAVE_COMP_KEY
10726
        /* adjust inLen if compressed */
10727
194
        if (compressed)
10728
160
            inLen = inLen*2 + 1;  /* used uncompressed len */
10729
194
    #endif
10730
10731
        /* determine key size */
10732
194
        keysize = (int)(inLen>>1);
10733
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
10734
         *       on created keys or signatures */
10735
194
        err = wc_ecc_set_curve(key, keysize, curve_id);
10736
194
        key->type = ECC_PUBLICKEY;
10737
194
    }
10738
10739
    /* read data */
10740
213
    if (err == MP_OKAY)
10741
194
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10742
10743
213
#ifdef HAVE_COMP_KEY
10744
213
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10745
153
#if !defined(WOLFSSL_SP_MATH)
10746
153
    #ifdef WOLFSSL_SMALL_STACK
10747
153
        mp_int* t1 = NULL;
10748
153
        mp_int* t2 = NULL;
10749
    #else
10750
        mp_int t1[1], t2[1];
10751
    #endif
10752
153
        int did_init = 0;
10753
10754
153
        DECLARE_CURVE_SPECS(3);
10755
153
        ALLOC_CURVE_SPECS(3, err);
10756
10757
153
        #ifdef WOLFSSL_SMALL_STACK
10758
153
        if (err == MP_OKAY) {
10759
145
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10760
145
            if (t1 == NULL) {
10761
4
                err = MEMORY_E;
10762
4
            }
10763
145
        }
10764
153
        if (err == MP_OKAY) {
10765
141
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10766
141
            if (t2 == NULL) {
10767
4
                err = MEMORY_E;
10768
4
            }
10769
141
        }
10770
153
        #endif
10771
153
        if (err == MP_OKAY) {
10772
137
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10773
0
                err = MEMORY_E;
10774
137
            else
10775
137
                did_init = 1;
10776
137
        }
10777
10778
        /* load curve info */
10779
153
        if (err == MP_OKAY)
10780
137
            err = wc_ecc_curve_load(key->dp, &curve,
10781
137
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10782
137
                 ECC_CURVE_FIELD_BF));
10783
10784
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
10785
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10786
        /* validate prime is prime for custom curves */
10787
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
10788
            int isPrime = MP_NO;
10789
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10790
            if (err == MP_OKAY && isPrime == MP_NO)
10791
                err = MP_VAL;
10792
        }
10793
    #endif
10794
10795
        /* compute x^3 */
10796
153
        if (err == MP_OKAY)
10797
134
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
10798
153
        if (err == MP_OKAY)
10799
131
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
10800
10801
        /* compute x^3 + a*x */
10802
153
        if (err == MP_OKAY)
10803
127
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
10804
153
        if (err == MP_OKAY)
10805
126
            err = mp_add(t1, t2, t1);
10806
10807
        /* compute x^3 + a*x + b */
10808
153
        if (err == MP_OKAY)
10809
126
            err = mp_add(t1, curve->Bf, t1);
10810
10811
        /* compute sqrt(x^3 + a*x + b) */
10812
153
        if (err == MP_OKAY)
10813
126
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
10814
10815
        /* adjust y */
10816
153
        if (err == MP_OKAY) {
10817
78
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
10818
48
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
10819
45
                err = mp_mod(t2, curve->prime, t2);
10820
45
            }
10821
33
            else {
10822
33
                err = mp_submod(curve->prime, t2, curve->prime, t2);
10823
33
            }
10824
78
            if (err == MP_OKAY)
10825
78
                err = mp_copy(t2, key->pubkey.y);
10826
78
        }
10827
10828
153
        if (did_init) {
10829
137
            mp_clear(t2);
10830
137
            mp_clear(t1);
10831
137
        }
10832
153
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10833
153
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10834
10835
153
        wc_ecc_curve_free(curve);
10836
153
        FREE_CURVE_SPECS();
10837
#else
10838
    #ifndef WOLFSSL_SP_NO_256
10839
        if (key->dp->id == ECC_SECP256R1) {
10840
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
10841
                key->pubkey.y);
10842
        }
10843
        else
10844
    #endif
10845
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10846
        if (key->dp->id == ECC_SM2P256V1) {
10847
            sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
10848
        }
10849
        else
10850
    #endif
10851
    #ifdef WOLFSSL_SP_384
10852
        if (key->dp->id == ECC_SECP384R1) {
10853
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
10854
                key->pubkey.y);
10855
        }
10856
        else
10857
    #endif
10858
    #ifdef WOLFSSL_SP_521
10859
        if (key->dp->id == ECC_SECP521R1) {
10860
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
10861
                key->pubkey.y);
10862
        }
10863
        else
10864
    #endif
10865
        {
10866
            err = WC_KEY_SIZE_E;
10867
        }
10868
#endif
10869
153
    }
10870
213
#endif /* HAVE_COMP_KEY */
10871
10872
213
    if (err == MP_OKAY) {
10873
101
    #ifdef HAVE_COMP_KEY
10874
101
        if (compressed == 0)
10875
23
    #endif
10876
23
        {
10877
23
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
10878
23
                (word32)keysize);
10879
23
        }
10880
101
    }
10881
213
    if (err == MP_OKAY)
10882
96
        err = mp_set(key->pubkey.z, 1);
10883
10884
#ifdef WOLFSSL_CRYPTOCELL
10885
    if (err == MP_OKAY) {
10886
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
10887
10888
        /* create public key from external key buffer */
10889
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
10890
                                               (byte*)in-1, /* re-adjust */
10891
                                               inLen+1,     /* original input */
10892
                                               &key->ctx.pubKey,
10893
                                               &tempBuff);
10894
10895
        if (err != SA_SILIB_RET_OK){
10896
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
10897
        }
10898
    }
10899
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10900
    if (err == MP_OKAY)
10901
        err = silabs_ecc_import(key, keysize, 1, 0);
10902
#elif defined(WOLFSSL_SE050)
10903
    if (err == MP_OKAY) {
10904
        /* reset key ID, in case used before */
10905
        key->keyId = 0;
10906
        key->keyIdSet = 0;
10907
    }
10908
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10909
    #ifndef HAVE_COMP_KEY
10910
    if (err == MP_OKAY) {
10911
    #else
10912
    if (err == MP_OKAY && !compressed) {
10913
    #endif
10914
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
10915
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
10916
    }
10917
#endif
10918
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
10919
    if (err == MP_OKAY)
10920
        err = wc_ecc_check_key(key);
10921
#endif
10922
10923
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
10924
    if (err == MP_OKAY) {
10925
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
10926
    }
10927
#endif
10928
10929
213
    if (err != MP_OKAY) {
10930
117
        mp_clear(key->pubkey.x);
10931
117
        mp_clear(key->pubkey.y);
10932
117
        mp_clear(key->pubkey.z);
10933
117
        mp_clear(key->k);
10934
117
    }
10935
10936
213
    RESTORE_VECTOR_REGISTERS();
10937
10938
213
    return err;
10939
213
}
10940
10941
WOLFSSL_ABI
10942
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
10943
179
{
10944
179
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
10945
179
}
10946
#endif /* HAVE_ECC_KEY_IMPORT */
10947
10948
#ifdef HAVE_ECC_KEY_EXPORT
10949
10950
/* export ecc key to component form, d is optional if only exporting public
10951
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
10952
 * return MP_OKAY on success */
10953
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
10954
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
10955
0
{
10956
0
    int err = 0;
10957
0
    word32 keySz;
10958
10959
0
    if (key == NULL) {
10960
0
        return BAD_FUNC_ARG;
10961
0
    }
10962
10963
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
10964
0
        return ECC_BAD_ARG_E;
10965
0
    }
10966
0
    keySz = (word32)key->dp->size;
10967
10968
    /* private key, d */
10969
0
    if (d != NULL) {
10970
0
        if (dLen == NULL ||
10971
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
10972
0
            return BAD_FUNC_ARG;
10973
10974
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10975
        /* Hardware cannot export private portion */
10976
        return NOT_COMPILED_IN;
10977
    #else
10978
    #if defined(WOLFSSL_SECO_CAAM)
10979
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
10980
            /* Hardware cannot export private portion */
10981
            WOLFSSL_MSG("Can not export private key from HSM");
10982
            return NOT_COMPILED_IN;
10983
        }
10984
    #endif
10985
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10986
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
10987
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
10988
                *dLen = keySz + WC_CAAM_MAC_SZ;
10989
                return BUFFER_E;
10990
            }
10991
10992
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
10993
                encType);
10994
            *dLen = keySz + WC_CAAM_MAC_SZ;
10995
        }
10996
        else if (encType == WC_TYPE_BLACK_KEY &&
10997
                key->blackKey != CAAM_BLACK_KEY_ECB &&
10998
                key->blackKey > 0) {
10999
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11000
                *dLen = keySz + WC_CAAM_MAC_SZ;
11001
                return BUFFER_E;
11002
            }
11003
11004
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11005
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11006
                    return WC_HW_E;
11007
            }
11008
11009
            *dLen = keySz + WC_CAAM_MAC_SZ;
11010
        }
11011
        else
11012
    #endif
11013
0
        {
11014
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11015
0
            if (err != MP_OKAY)
11016
0
                return err;
11017
0
        }
11018
0
    #endif
11019
0
    }
11020
11021
    /* public x component */
11022
0
    if (qx != NULL) {
11023
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11024
0
            return BAD_FUNC_ARG;
11025
11026
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11027
0
        if (err != MP_OKAY)
11028
0
            return err;
11029
0
    }
11030
11031
    /* public y component */
11032
0
    if (qy != NULL) {
11033
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11034
0
            return BAD_FUNC_ARG;
11035
11036
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11037
0
        if (err != MP_OKAY)
11038
0
            return err;
11039
0
    }
11040
11041
0
    return err;
11042
0
}
11043
11044
11045
/* export ecc private key only raw, outLen is in/out size as unsigned bin
11046
   return MP_OKAY on success */
11047
WOLFSSL_ABI
11048
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11049
0
{
11050
0
    if (out == NULL || outLen == NULL) {
11051
0
        return BAD_FUNC_ARG;
11052
0
    }
11053
11054
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11055
    /* check if black key in secure memory */
11056
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11057
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11058
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11059
            WC_TYPE_BLACK_KEY);
11060
    }
11061
#endif
11062
11063
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11064
0
        WC_TYPE_UNSIGNED_BIN);
11065
0
}
11066
11067
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11068
 * return MP_OKAY on success, negative on error */
11069
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11070
                             byte* qy, word32* qyLen)
11071
0
{
11072
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11073
0
        return BAD_FUNC_ARG;
11074
0
    }
11075
11076
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11077
0
        WC_TYPE_UNSIGNED_BIN);
11078
0
}
11079
11080
/* export ecc key to raw elements including public (Qx,Qy) and
11081
 *   private (d) as unsigned bin
11082
 * return MP_OKAY on success, negative on error */
11083
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11084
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11085
0
{
11086
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11087
0
        WC_TYPE_UNSIGNED_BIN);
11088
0
}
11089
11090
#endif /* HAVE_ECC_KEY_EXPORT */
11091
11092
#ifdef HAVE_ECC_KEY_IMPORT
11093
/* import private key, public part optional if (pub) passed as NULL */
11094
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11095
                                 const byte* pub, word32 pubSz, ecc_key* key,
11096
                                 int curve_id)
11097
7.01k
{
11098
7.01k
    int ret;
11099
#ifdef WOLFSSL_CRYPTOCELL
11100
    const CRYS_ECPKI_Domain_t* pDomain;
11101
#endif
11102
7.01k
    if (key == NULL || priv == NULL)
11103
117
        return BAD_FUNC_ARG;
11104
11105
    /* public optional, NULL if only importing private */
11106
6.89k
    if (pub != NULL) {
11107
0
    #ifndef NO_ASN
11108
0
        word32 idx = 0;
11109
0
        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
11110
0
        if (ret < 0)
11111
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11112
0
        key->type = ECC_PRIVATEKEY;
11113
    #else
11114
        (void)pubSz;
11115
        ret = NOT_COMPILED_IN;
11116
    #endif
11117
0
    }
11118
6.89k
    else {
11119
        /* make sure required variables are reset */
11120
6.89k
        wc_ecc_reset(key);
11121
11122
        /* set key size */
11123
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11124
         *       on created keys or signatures */
11125
6.89k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11126
6.89k
        key->type = ECC_PRIVATEKEY_ONLY;
11127
6.89k
    }
11128
11129
6.89k
    if (ret != 0)
11130
766
        return ret;
11131
11132
#ifdef WOLFSSL_CRYPTOCELL
11133
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11134
    /* import private key - priv checked for NULL at top */
11135
    if (priv[0] != '\0') {
11136
11137
        /* Create private key from external key buffer*/
11138
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11139
                                      priv,
11140
                                      privSz,
11141
                                      &key->ctx.privKey);
11142
11143
        if (ret != SA_SILIB_RET_OK) {
11144
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11145
            return ret;
11146
        }
11147
11148
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11149
    #ifdef WOLFSSL_ECC_BLIND_K
11150
        if (ret == MP_OKAY) {
11151
            err = ecc_blind_k_rng(key, NULL);
11152
        }
11153
    #endif
11154
    }
11155
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11156
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11157
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11158
        int part = caamFindUnusedPartition();
11159
        if (part >= 0) {
11160
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11161
            if (vaddr == 0) {
11162
                WOLFSSL_MSG("Unable to get partition");
11163
                return MEMORY_E;
11164
            }
11165
11166
            key->partNum  = part;
11167
            key->blackKey = (word32)vaddr;
11168
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11169
                return WC_HW_E;
11170
11171
            if (pub != NULL) {
11172
                /* +1 to account for x963 compressed bit */
11173
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11174
                    return WC_HW_E;
11175
                key->securePubKey = (word32)vaddr + privSz;
11176
            }
11177
        }
11178
        else {
11179
            WOLFSSL_MSG("Unable to find an unused partition");
11180
            return MEMORY_E;
11181
        }
11182
    #else
11183
        key->blackKey = CAAM_BLACK_KEY_CCM;
11184
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11185
    #ifdef WOLFSSL_ECC_BLIND_K
11186
        if (ret == MP_OKAY) {
11187
            err = ecc_blind_k_rng(key, NULL);
11188
        }
11189
    #endif
11190
    #endif
11191
    }
11192
    else {
11193
        key->blackKey = 0;
11194
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11195
    #ifdef WOLFSSL_ECC_BLIND_K
11196
        if (ret == MP_OKAY) {
11197
            err = ecc_blind_k_rng(key, NULL);
11198
        }
11199
    #endif
11200
11201
        /* If using AES-ECB encrypted black keys check here if key is valid,
11202
         * if not valid than assume is an encrypted key. A public key is needed
11203
         * for testing validity. */
11204
        if (key->devId == WOLFSSL_CAAM_DEVID && (
11205
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11206
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11207
            if ((pub != NULL) && (ret == MP_OKAY) &&
11208
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11209
                key->blackKey = CAAM_BLACK_KEY_ECB;
11210
            }
11211
            else if ((pub == NULL) && (ret == MP_OKAY)) {
11212
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11213
                key->blackKey = CAAM_BLACK_KEY_ECB;
11214
            }
11215
            else {
11216
                WOLFSSL_MSG("Importing key that is not a black key!");
11217
            }
11218
        }
11219
    }
11220
#else
11221
11222
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11223
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11224
#endif
11225
11226
6.12k
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11227
#ifdef HAVE_WOLF_BIGINT
11228
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11229
                                                                 privSz) != 0) {
11230
        mp_clear(key->k);
11231
        ret = ASN_GETINT_E;
11232
    }
11233
#endif /* HAVE_WOLF_BIGINT */
11234
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11235
    if (ret == 0) {
11236
        WC_DECLARE_VAR(order, mp_int, 1, 0);
11237
11238
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
11239
            ret=MEMORY_E);
11240
11241
        if (ret == 0) {
11242
            ret = mp_init(order);
11243
        }
11244
        if (ret == 0) {
11245
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11246
        }
11247
    #ifdef WOLFSSL_SM2
11248
        /* SM2 curve: private key must be less than order-1. */
11249
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11250
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11251
            ret = mp_sub_d(order, 1, order);
11252
        }
11253
    #endif
11254
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11255
            ret = ECC_PRIV_KEY_E;
11256
        }
11257
11258
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
11259
    }
11260
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11261
#ifdef WOLFSSL_ECC_BLIND_K
11262
    if (ret == 0) {
11263
        ret = ecc_blind_k_rng(key, NULL);
11264
    }
11265
#endif
11266
11267
6.12k
#endif /* WOLFSSL_CRYPTOCELL */
11268
11269
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11270
    if ((pub != NULL) && (ret == MP_OKAY))
11271
        /* public key needed to perform key validation */
11272
        ret = _ecc_validate_public_key(key, 1, 1);
11273
11274
#endif
11275
11276
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11277
    RESTORE_VECTOR_REGISTERS();
11278
#endif
11279
11280
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11281
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11282
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11283
    }
11284
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11285
    if (ret == 0) {
11286
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11287
    }
11288
#endif
11289
11290
6.12k
    return ret;
11291
6.89k
}
11292
11293
/* ecc private key import, public key in ANSI X9.63 format, private raw */
11294
WOLFSSL_ABI
11295
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11296
                           word32 pubSz, ecc_key* key)
11297
49
{
11298
49
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11299
49
                                                                ECC_CURVE_DEF);
11300
49
}
11301
#endif /* HAVE_ECC_KEY_IMPORT */
11302
11303
#ifndef NO_ASN
11304
/**
11305
   Convert ECC R,S to signature
11306
   r       R component of signature
11307
   s       S component of signature
11308
   out     DER-encoded ECDSA signature
11309
   outlen  [in/out] output buffer size, output signature size
11310
   return  MP_OKAY on success
11311
*/
11312
WOLFSSL_ABI
11313
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11314
472
{
11315
472
    int err;
11316
472
#ifdef WOLFSSL_SMALL_STACK
11317
472
    mp_int* rtmp = NULL;
11318
472
    mp_int* stmp = NULL;
11319
#else
11320
    mp_int  rtmp[1];
11321
    mp_int  stmp[1];
11322
#endif
11323
11324
472
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11325
2
        return ECC_BAD_ARG_E;
11326
11327
470
#ifdef WOLFSSL_SMALL_STACK
11328
470
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11329
470
    if (rtmp == NULL)
11330
0
        return MEMORY_E;
11331
470
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11332
470
    if (stmp == NULL) {
11333
0
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11334
0
        return MEMORY_E;
11335
0
    }
11336
470
#endif
11337
11338
470
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11339
470
    if (err != MP_OKAY) {
11340
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11341
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11342
0
        return err;
11343
0
    }
11344
11345
470
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11346
470
    if (err == MP_OKAY)
11347
467
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11348
11349
470
    if (err == MP_OKAY) {
11350
462
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11351
16
            err = MP_ZERO_E;
11352
462
    }
11353
470
    if (err == MP_OKAY) {
11354
446
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11355
9
            err = MP_READ_E;
11356
9
        }
11357
446
    }
11358
11359
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11360
470
    if (err == MP_OKAY)
11361
437
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11362
11363
470
    mp_clear(rtmp);
11364
470
    mp_clear(stmp);
11365
470
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11366
470
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11367
11368
470
    return err;
11369
470
}
11370
11371
/**
11372
   Convert ECC R,S raw unsigned bin to signature
11373
   r       R component of signature
11374
   rSz     R size
11375
   s       S component of signature
11376
   sSz     S size
11377
   out     DER-encoded ECDSA signature
11378
   outlen  [in/out] output buffer size, output signature size
11379
   return  MP_OKAY on success
11380
*/
11381
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11382
    byte* out, word32* outlen)
11383
277
{
11384
277
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11385
0
        return ECC_BAD_ARG_E;
11386
11387
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11388
277
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11389
277
}
11390
11391
/**
11392
   Convert ECC signature to R,S
11393
   sig     DER-encoded ECDSA signature
11394
   sigLen  length of signature in octets
11395
   r       R component of signature
11396
   rLen    [in/out] output "r" buffer size, output "r" size
11397
   s       S component of signature
11398
   sLen    [in/out] output "s" buffer size, output "s" size
11399
   return  MP_OKAY on success, negative on error
11400
*/
11401
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11402
                     byte* s, word32* sLen)
11403
0
{
11404
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11405
0
        return ECC_BAD_ARG_E;
11406
11407
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11408
0
}
11409
#endif /* !NO_ASN */
11410
11411
#ifdef HAVE_ECC_KEY_IMPORT
11412
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
11413
          const char* qy, const char* d, int curve_id, int encType)
11414
1.62k
{
11415
1.62k
    int err = MP_OKAY;
11416
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11417
    !defined(WOLFSSL_ATECC608A)
11418
    const CRYS_ECPKI_Domain_t* pDomain;
11419
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11420
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11421
#endif
11422
11423
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11424
    defined(WOLFSSL_CRYPTOCELL)
11425
    word32 keySz = 0;
11426
#endif
11427
11428
    /* if d is NULL, only import as public key using Qx,Qy */
11429
1.62k
    if (key == NULL || qx == NULL || qy == NULL) {
11430
0
        return BAD_FUNC_ARG;
11431
0
    }
11432
11433
    /* make sure required variables are reset */
11434
1.62k
    wc_ecc_reset(key);
11435
11436
    /* set curve type and index */
11437
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11438
     *       on created keys or signatures */
11439
1.62k
    err = wc_ecc_set_curve(key, 0, curve_id);
11440
1.62k
    if (err != 0) {
11441
0
        return err;
11442
0
    }
11443
11444
    /* init key */
11445
#ifdef ALT_ECC_SIZE
11446
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11447
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11448
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11449
    alt_fp_init(key->pubkey.x);
11450
    alt_fp_init(key->pubkey.y);
11451
    alt_fp_init(key->pubkey.z);
11452
    key->k = (mp_int*)key->ka;
11453
    alt_fp_init(key->k);
11454
#ifdef WOLFSSL_ECC_BLIND_K
11455
    key->kb = (mp_int*)key->kba;
11456
    key->ku = (mp_int*)key->kua;
11457
    alt_fp_init(key->kb);
11458
    alt_fp_init(key->ku);
11459
#endif
11460
#else
11461
1.62k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11462
1.62k
#ifndef WOLFSSL_ECC_BLIND_K
11463
1.62k
                                                                      NULL, NULL
11464
#else
11465
                                                                key->kb, key->ku
11466
#endif
11467
1.62k
                        );
11468
1.62k
#endif
11469
1.62k
    if (err != MP_OKAY)
11470
0
        return MEMORY_E;
11471
#ifdef WOLFSSL_ECC_BLIND_K
11472
    mp_forcezero(key->kb);
11473
#endif
11474
11475
    /* read Qx */
11476
1.62k
    if (err == MP_OKAY) {
11477
1.62k
        if (encType == WC_TYPE_HEX_STR)
11478
1.62k
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
11479
0
        else
11480
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
11481
0
                (word32)key->dp->size);
11482
11483
1.62k
        if (mp_isneg(key->pubkey.x)) {
11484
19
            WOLFSSL_MSG("Invalid Qx");
11485
19
            err = BAD_FUNC_ARG;
11486
19
        }
11487
1.62k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
11488
28
            err = BAD_FUNC_ARG;
11489
28
        }
11490
1.62k
    }
11491
11492
    /* read Qy */
11493
1.62k
    if (err == MP_OKAY) {
11494
1.51k
        if (encType == WC_TYPE_HEX_STR)
11495
1.51k
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
11496
0
        else
11497
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
11498
0
                (word32)key->dp->size);
11499
11500
1.51k
        if (mp_isneg(key->pubkey.y)) {
11501
14
            WOLFSSL_MSG("Invalid Qy");
11502
14
            err = BAD_FUNC_ARG;
11503
14
        }
11504
1.51k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
11505
46
            err = BAD_FUNC_ARG;
11506
46
        }
11507
1.51k
    }
11508
11509
1.62k
    if (err == MP_OKAY) {
11510
1.44k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
11511
51
            WOLFSSL_MSG("Invalid Qx and Qy");
11512
51
            err = ECC_INF_E;
11513
51
        }
11514
1.44k
    }
11515
11516
1.62k
    if (err == MP_OKAY)
11517
1.39k
        err = mp_set(key->pubkey.z, 1);
11518
11519
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11520
    /* For SECP256R1 only save raw public key for hardware */
11521
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
11522
        keySz = key->dp->size;
11523
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11524
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11525
        if (err == MP_OKAY)
11526
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
11527
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11528
    }
11529
#elif defined(WOLFSSL_CRYPTOCELL)
11530
    if (err == MP_OKAY) {
11531
        keyRaw[0] = ECC_POINT_UNCOMP;
11532
        keySz = (word32)key->dp->size;
11533
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
11534
            WC_TYPE_UNSIGNED_BIN);
11535
        if (err == MP_OKAY) {
11536
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
11537
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11538
        }
11539
11540
        if (err == MP_OKAY) {
11541
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11542
11543
            /* create public key from external key buffer */
11544
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11545
                                                   keyRaw,
11546
                                                   keySz*2 + 1,
11547
                                                   &key->ctx.pubKey,
11548
                                                   &tempBuff);
11549
        }
11550
11551
        if (err != SA_SILIB_RET_OK){
11552
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11553
            return err;
11554
        }
11555
    }
11556
#elif defined(WOLFSSL_KCAPI_ECC)
11557
    if (err == MP_OKAY) {
11558
        word32 keySz = key->dp->size;
11559
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
11560
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
11561
        if (err == MP_OKAY) {
11562
            err = wc_export_int(key->pubkey.y,
11563
                &key->pubkey_raw[keySz], &keySz, keySz,
11564
                WC_TYPE_UNSIGNED_BIN);
11565
        }
11566
    }
11567
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11568
    if (err == MP_OKAY) {
11569
        const word32 keySize = key->dp->size;
11570
        word32 bufSize = sizeof(key->keyRaw);
11571
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
11572
                            WC_TYPE_UNSIGNED_BIN);
11573
        if (err == MP_OKAY) {
11574
            const word32 offset = bufSize;
11575
            bufSize = sizeof(key->keyRaw) - offset;
11576
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
11577
                                keySize, WC_TYPE_UNSIGNED_BIN);
11578
        }
11579
        if (err == MP_OKAY) {
11580
            mp_reverse(key->keyRaw, keySize);
11581
            mp_reverse(&key->keyRaw[keySize], keySize);
11582
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
11583
                                           keySize * 2);
11584
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
11585
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
11586
                                              xil_curve_type[key->dp->id],
11587
                                              XIL_CAST_U64(key->keyRaw));
11588
            if (err) {
11589
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
11590
                err = WC_HW_E;
11591
            }
11592
#endif
11593
        }
11594
    }
11595
#endif
11596
11597
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11598
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11599
#endif
11600
11601
    /* import private key */
11602
1.62k
    if (err == MP_OKAY) {
11603
1.39k
        if (d != NULL) {
11604
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
11605
            /* Hardware doesn't support loading private key */
11606
            err = NOT_COMPILED_IN;
11607
11608
        #elif defined(WOLFSSL_CRYPTOCELL)
11609
            key->type = ECC_PRIVATEKEY;
11610
11611
            if (encType == WC_TYPE_HEX_STR)
11612
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11613
            else
11614
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
11615
                    key->dp->size);
11616
            if (err == MP_OKAY) {
11617
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
11618
                    WC_TYPE_UNSIGNED_BIN);
11619
            }
11620
        #ifdef WOLFSSL_ECC_BLIND_K
11621
            if (err == 0) {
11622
                err = ecc_blind_k_rng(key, NULL);
11623
            }
11624
        #endif
11625
11626
            if (err == MP_OKAY) {
11627
                /* Create private key from external key buffer*/
11628
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
11629
                                              keyRaw,
11630
                                              keySz,
11631
                                              &key->ctx.privKey);
11632
11633
                if (err != SA_SILIB_RET_OK){
11634
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11635
                    return err;
11636
                }
11637
            }
11638
11639
        #else
11640
0
            key->type = ECC_PRIVATEKEY;
11641
0
            if (encType == WC_TYPE_HEX_STR)
11642
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
11643
0
            else {
11644
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11645
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11646
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11647
                    key->dp->size + WC_CAAM_MAC_SZ);
11648
                }
11649
                else
11650
            #endif /* WOLFSSL_QNX_CAAM */
11651
0
                {
11652
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
11653
0
                        (word32)key->dp->size);
11654
0
                }
11655
0
            }
11656
        #ifdef WOLFSSL_ECC_BLIND_K
11657
            if (err == 0) {
11658
                err = ecc_blind_k_rng(key, NULL);
11659
            }
11660
        #endif
11661
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11662
            if (err == MP_OKAY) {
11663
                const word32 key_size = key->dp->size;
11664
                word32 buf_size = key_size;
11665
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
11666
                                    WC_TYPE_UNSIGNED_BIN);
11667
                mp_reverse(key->privKey, key_size);
11668
            }
11669
#endif
11670
11671
0
        #endif /* #else-case of custom HW-specific implementations */
11672
0
            if (mp_iszero(key->k) || mp_isneg(key->k)) {
11673
0
                WOLFSSL_MSG("Invalid private key");
11674
0
                err = BAD_FUNC_ARG;
11675
0
            }
11676
1.39k
        } else {
11677
1.39k
            key->type = ECC_PUBLICKEY;
11678
1.39k
        }
11679
1.39k
    }
11680
11681
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11682
    if (err == MP_OKAY) {
11683
        err = wc_ecc_check_key(key);
11684
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
11685
                                  mp_iszero(key->pubkey.y))) {
11686
            err = BAD_FUNC_ARG;
11687
        }
11688
    }
11689
#endif
11690
11691
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11692
    RESTORE_VECTOR_REGISTERS();
11693
#endif
11694
11695
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11696
    if (err == MP_OKAY) {
11697
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11698
    }
11699
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11700
    if (err == MP_OKAY) {
11701
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
11702
    }
11703
#endif
11704
11705
1.62k
    if (err != MP_OKAY) {
11706
231
        mp_clear(key->pubkey.x);
11707
231
        mp_clear(key->pubkey.y);
11708
231
        mp_clear(key->pubkey.z);
11709
231
        mp_clear(key->k);
11710
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11711
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
11712
#endif
11713
231
    }
11714
11715
1.62k
    return err;
11716
1.62k
}
11717
11718
/**
11719
   Import raw ECC key
11720
   key       The destination ecc_key structure
11721
   qx        x component of the public key, as ASCII hex string
11722
   qy        y component of the public key, as ASCII hex string
11723
   d         private key, as ASCII hex string, optional if importing public
11724
             key only
11725
   curve_id  The id of the curve.
11726
   @return    MP_OKAY on success
11727
*/
11728
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
11729
                   const char* d, int curve_id)
11730
0
{
11731
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
11732
0
        WC_TYPE_HEX_STR);
11733
0
}
11734
11735
/* Import x, y and optional private (d) as unsigned binary */
11736
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
11737
                   const byte* d, int curve_id)
11738
0
{
11739
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
11740
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
11741
0
}
11742
11743
/**
11744
   Import raw ECC key
11745
   key       The destination ecc_key structure
11746
   qx        x component of the public key, as ASCII hex string
11747
   qy        y component of the public key, as ASCII hex string
11748
   d         private key, as ASCII hex string, optional if importing public
11749
             key only
11750
   curveName ECC curve name, from ecc_sets[]
11751
   return    MP_OKAY on success
11752
*/
11753
WOLFSSL_ABI
11754
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
11755
                   const char* d, const char* curveName)
11756
9.51k
{
11757
9.51k
    int err, x;
11758
11759
    /* if d is NULL, only import as public key using Qx,Qy */
11760
9.51k
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
11761
0
        return BAD_FUNC_ARG;
11762
0
    }
11763
11764
    /* set curve type and index */
11765
153k
    for (x = 0; ecc_sets[x].size != 0; x++) {
11766
153k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
11767
153k
                     XSTRLEN(curveName)) == 0) {
11768
9.51k
            break;
11769
9.51k
        }
11770
153k
    }
11771
11772
9.51k
    if (ecc_sets[x].size == 0) {
11773
0
        WOLFSSL_MSG("ecc_set curve name not found");
11774
0
        err = ASN_PARSE_E;
11775
9.51k
    } else {
11776
9.51k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
11777
9.51k
            WC_TYPE_HEX_STR);
11778
9.51k
    }
11779
11780
0
    return err;
11781
9.51k
}
11782
#endif /* HAVE_ECC_KEY_IMPORT */
11783
11784
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
11785
/* public key size in octets */
11786
static int ecc_public_key_size(ecc_key* key, word32* sz)
11787
857
{
11788
857
    if (key == NULL || key->dp == NULL)
11789
0
        return BAD_FUNC_ARG;
11790
11791
    /* 'Uncompressed' | x | y */
11792
857
    *sz = 1 + 2 * (word32)key->dp->size;
11793
11794
857
    return 0;
11795
857
}
11796
#endif
11797
11798
/* key size in octets */
11799
WOLFSSL_ABI
11800
int wc_ecc_size(ecc_key* key)
11801
541
{
11802
541
    if (key == NULL || key->dp == NULL)
11803
0
        return 0;
11804
11805
541
    return key->dp->size;
11806
541
}
11807
11808
/* maximum signature size based on key size */
11809
WOLFSSL_ABI
11810
int wc_ecc_sig_size_calc(int sz)
11811
0
{
11812
0
    int maxSigSz = 0;
11813
11814
    /* calculate based on key bits */
11815
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
11816
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
11817
11818
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11819
0
    if (maxSigSz < (128 + 2)) {
11820
0
        maxSigSz -= 1;
11821
0
    }
11822
11823
0
    return maxSigSz;
11824
0
}
11825
11826
/* maximum signature size based on actual key curve */
11827
WOLFSSL_ABI
11828
int wc_ecc_sig_size(const ecc_key* key)
11829
554
{
11830
554
    int maxSigSz;
11831
554
    int orderBits, keySz;
11832
11833
554
    if (key == NULL || key->dp == NULL)
11834
0
        return 0;
11835
11836
    /* the signature r and s will always be less than order */
11837
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
11838
        extra byte for r and s, so add 2 */
11839
554
    keySz = key->dp->size;
11840
554
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
11841
554
    if (orderBits > keySz * 8) {
11842
0
        keySz = (orderBits + 7) >> 3;
11843
0
    }
11844
    /* maximum possible signature header size is 7 bytes */
11845
554
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
11846
554
    if ((orderBits % 8) == 0) {
11847
        /* MSB can be set, so add 2 */
11848
376
        maxSigSz += ECC_MAX_PAD_SZ;
11849
376
    }
11850
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
11851
554
    if (maxSigSz < (128 + 2)) {
11852
376
        maxSigSz -= 1;
11853
376
    }
11854
11855
554
    return maxSigSz;
11856
554
}
11857
11858
11859
#ifdef FP_ECC
11860
11861
/* fixed point ECC cache */
11862
/* number of entries in the cache */
11863
#ifndef FP_ENTRIES
11864
    #define FP_ENTRIES 15
11865
#endif
11866
11867
/* number of bits in LUT */
11868
#ifndef FP_LUT
11869
    #define FP_LUT     8U
11870
#endif
11871
11872
#ifdef ECC_SHAMIR
11873
    /* Sharmir requires a bigger LUT, TAO */
11874
    #if (FP_LUT > 12) || (FP_LUT < 4)
11875
        #error FP_LUT must be between 4 and 12 inclusively
11876
    #endif
11877
#else
11878
    #if (FP_LUT > 12) || (FP_LUT < 2)
11879
        #error FP_LUT must be between 2 and 12 inclusively
11880
    #endif
11881
#endif
11882
11883
11884
#if !defined(WOLFSSL_SP_MATH)
11885
11886
/** Our FP cache */
11887
typedef struct {
11888
   ecc_point* g;               /* cached COPY of base point */
11889
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
11890
   int        LUT_set;         /* flag to determine if the LUT has been computed */
11891
   mp_int     mu;              /* copy of the montgomery constant */
11892
   int        lru_count;       /* amount of times this entry has been used */
11893
   int        lock;            /* flag to indicate cache eviction */
11894
                               /* permitted (0) or not (1) */
11895
} fp_cache_t;
11896
11897
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
11898
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
11899
11900
#ifndef HAVE_THREAD_LS
11901
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
11902
#ifndef WOLFSSL_MUTEX_INITIALIZER
11903
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
11904
#endif
11905
#endif /* HAVE_THREAD_LS */
11906
11907
/* simple table to help direct the generation of the LUT */
11908
static const struct {
11909
   int ham, terma, termb;
11910
} lut_orders[] = {
11911
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
11912
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
11913
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
11914
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
11915
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
11916
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
11917
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
11918
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
11919
#if FP_LUT > 6
11920
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
11921
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
11922
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
11923
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
11924
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
11925
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
11926
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
11927
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
11928
#if FP_LUT > 7
11929
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
11930
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
11931
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
11932
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
11933
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
11934
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
11935
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
11936
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
11937
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
11938
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
11939
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
11940
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
11941
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
11942
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
11943
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
11944
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
11945
#if FP_LUT > 8
11946
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
11947
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
11948
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
11949
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
11950
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
11951
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
11952
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
11953
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
11954
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
11955
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
11956
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
11957
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
11958
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
11959
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
11960
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
11961
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
11962
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
11963
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
11964
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
11965
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
11966
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
11967
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
11968
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
11969
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
11970
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
11971
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
11972
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
11973
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
11974
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
11975
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
11976
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
11977
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
11978
#if FP_LUT > 9
11979
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
11980
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
11981
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
11982
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
11983
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
11984
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
11985
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
11986
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
11987
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
11988
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
11989
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
11990
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
11991
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
11992
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
11993
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
11994
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
11995
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
11996
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
11997
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
11998
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
11999
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12000
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12001
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12002
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12003
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12004
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12005
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12006
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12007
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12008
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12009
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12010
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12011
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12012
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12013
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12014
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12015
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12016
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12017
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12018
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12019
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12020
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12021
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12022
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12023
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12024
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12025
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12026
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12027
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12028
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12029
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12030
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12031
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12032
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12033
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12034
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12035
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12036
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12037
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12038
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12039
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12040
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12041
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12042
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12043
#if FP_LUT > 10
12044
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12045
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12046
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12047
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12048
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12049
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12050
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12051
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12052
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12053
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12054
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12055
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12056
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12057
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12058
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12059
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12060
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12061
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12062
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12063
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12064
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12065
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12066
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12067
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12068
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12069
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12070
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12071
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12072
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12073
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12074
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12075
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12076
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12077
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12078
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12079
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12080
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12081
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12082
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12083
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12084
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12085
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12086
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12087
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12088
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12089
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12090
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12091
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12092
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12093
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12094
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12095
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12096
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12097
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12098
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12099
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12100
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12101
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12102
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12103
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12104
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12105
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12106
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12107
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12108
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12109
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12110
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12111
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12112
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12113
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12114
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12115
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12116
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12117
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12118
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12119
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12120
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12121
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12122
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12123
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12124
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12125
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12126
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12127
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12128
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12129
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12130
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12131
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12132
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12133
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12134
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12135
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12136
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12137
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12138
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12139
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12140
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12141
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12142
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12143
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12144
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12145
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12146
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12147
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12148
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12149
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12150
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12151
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12152
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12153
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12154
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12155
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12156
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12157
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12158
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12159
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12160
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12161
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12162
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12163
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12164
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12165
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12166
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12167
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12168
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12169
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12170
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12171
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12172
#if FP_LUT > 11
12173
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12174
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12175
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12176
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12177
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12178
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12179
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12180
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12181
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12182
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12183
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12184
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12185
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12186
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12187
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12188
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12189
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12190
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12191
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12192
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12193
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12194
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12195
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12196
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12197
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12198
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12199
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12200
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12201
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12202
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12203
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12204
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12205
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12206
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12207
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12208
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12209
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12210
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12211
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12212
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12213
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12214
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12215
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12216
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12217
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12218
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12219
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12220
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12221
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12222
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12223
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12224
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12225
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12226
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12227
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12228
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12229
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12230
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12231
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12232
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12233
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12234
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12235
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12236
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12237
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12238
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12239
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12240
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12241
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12242
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12243
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12244
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12245
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12246
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12247
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12248
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12249
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12250
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12251
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12252
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12253
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12254
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12255
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12256
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12257
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12258
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12259
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12260
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12261
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12262
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12263
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12264
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12265
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12266
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12267
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12268
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12269
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12270
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12271
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12272
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12273
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12274
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12275
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12276
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12277
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12278
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12279
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12280
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12281
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12282
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12283
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12284
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12285
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12286
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12287
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12288
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12289
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12290
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12291
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12292
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12293
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12294
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12295
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12296
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12297
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12298
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12299
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12300
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12301
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12302
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12303
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12304
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12305
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12306
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12307
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12308
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12309
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12310
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12311
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12312
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12313
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12314
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12315
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12316
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12317
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12318
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12319
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12320
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12321
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12322
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12323
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12324
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12325
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12326
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12327
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12328
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12329
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12330
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12331
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12332
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12333
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12334
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12335
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12336
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12337
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12338
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12339
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12340
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
12341
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
12342
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
12343
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
12344
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
12345
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
12346
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
12347
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
12348
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
12349
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
12350
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
12351
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
12352
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
12353
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
12354
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
12355
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
12356
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
12357
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
12358
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
12359
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
12360
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
12361
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
12362
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
12363
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
12364
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
12365
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
12366
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
12367
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
12368
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
12369
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
12370
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
12371
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
12372
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
12373
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
12374
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
12375
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
12376
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
12377
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
12378
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
12379
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
12380
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
12381
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
12382
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
12383
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
12384
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
12385
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
12386
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
12387
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
12388
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
12389
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
12390
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
12391
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
12392
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
12393
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
12394
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
12395
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
12396
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
12397
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
12398
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
12399
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
12400
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
12401
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
12402
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
12403
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
12404
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
12405
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
12406
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
12407
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
12408
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
12409
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
12410
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
12411
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
12412
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
12413
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
12414
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
12415
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
12416
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
12417
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
12418
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
12419
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
12420
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
12421
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
12422
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
12423
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
12424
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
12425
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
12426
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
12427
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
12428
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
12429
#endif
12430
#endif
12431
#endif
12432
#endif
12433
#endif
12434
#endif
12435
};
12436
12437
12438
/* find a hole and free as required, return -1 if no hole found */
12439
static int find_hole(void)
12440
{
12441
#ifdef WOLFSSL_NO_MALLOC
12442
   return -1;
12443
#else
12444
   int      x, y, z;
12445
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
12446
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
12447
          z = x;
12448
          y = fp_cache[x].lru_count;
12449
       }
12450
   }
12451
12452
   /* decrease all */
12453
   for (x = 0; x < FP_ENTRIES; x++) {
12454
      if (fp_cache[x].lru_count > 3) {
12455
         --(fp_cache[x].lru_count);
12456
      }
12457
   }
12458
12459
   /* free entry z */
12460
   if (z >= 0 && fp_cache[z].g) {
12461
      mp_clear(&fp_cache[z].mu);
12462
      wc_ecc_del_point(fp_cache[z].g);
12463
      fp_cache[z].g  = NULL;
12464
      for (x = 0; x < (1<<FP_LUT); x++) {
12465
         wc_ecc_del_point(fp_cache[z].LUT[x]);
12466
         fp_cache[z].LUT[x] = NULL;
12467
      }
12468
      fp_cache[z].LUT_set = 0;
12469
      fp_cache[z].lru_count = 0;
12470
   }
12471
   return z;
12472
#endif /* !WOLFSSL_NO_MALLOC */
12473
}
12474
12475
/* determine if a base is already in the cache and if so, where */
12476
static int find_base(ecc_point* g)
12477
{
12478
   int x;
12479
   for (x = 0; x < FP_ENTRIES; x++) {
12480
      if (fp_cache[x].g != NULL &&
12481
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
12482
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
12483
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
12484
         break;
12485
      }
12486
   }
12487
   if (x == FP_ENTRIES) {
12488
      x = -1;
12489
   }
12490
   return x;
12491
}
12492
12493
/* add a new base to the cache */
12494
static int add_entry(int idx, ecc_point *g)
12495
{
12496
   unsigned x, y;
12497
12498
   /* allocate base and LUT */
12499
   fp_cache[idx].g = wc_ecc_new_point();
12500
   if (fp_cache[idx].g == NULL) {
12501
      return MP_MEM;
12502
   }
12503
12504
   /* copy x and y */
12505
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
12506
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
12507
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
12508
      wc_ecc_del_point(fp_cache[idx].g);
12509
      fp_cache[idx].g = NULL;
12510
      return MP_MEM;
12511
   }
12512
12513
   for (x = 0; x < (1U<<FP_LUT); x++) {
12514
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
12515
      if (fp_cache[idx].LUT[x] == NULL) {
12516
         for (y = 0; y < x; y++) {
12517
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
12518
            fp_cache[idx].LUT[y] = NULL;
12519
         }
12520
         wc_ecc_del_point(fp_cache[idx].g);
12521
         fp_cache[idx].g         = NULL;
12522
         fp_cache[idx].lru_count = 0;
12523
         return MP_MEM;
12524
      }
12525
   }
12526
12527
   fp_cache[idx].LUT_set   = 0;
12528
   fp_cache[idx].lru_count = 0;
12529
12530
   return MP_OKAY;
12531
}
12532
#endif
12533
12534
#if !defined(WOLFSSL_SP_MATH)
12535
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
12536
 *
12537
 * The algorithm builds patterns in increasing bit order by first making all
12538
 * single bit input patterns, then all two bit input patterns and so on
12539
 */
12540
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
12541
    mp_int* mu)
12542
{
12543
   int err;
12544
   unsigned x, y, bitlen, lut_gap;
12545
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
12546
   int infinity;
12547
12548
#ifdef WOLFSSL_SMALL_STACK
12549
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
12550
       return MEMORY_E;
12551
#endif
12552
12553
   err = mp_init(tmp);
12554
   if (err != MP_OKAY) {
12555
       err = MP_MEM;
12556
       goto errout;
12557
   }
12558
12559
   /* sanity check to make sure lut_order table is of correct size,
12560
      should compile out to a NOP if true */
12561
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
12562
       err = BAD_FUNC_ARG;
12563
       goto errout;
12564
   }
12565
12566
   /* get bitlen and round up to next multiple of FP_LUT */
12567
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12568
   x       = bitlen % FP_LUT;
12569
   if (x) {
12570
       bitlen += FP_LUT - x;
12571
   }
12572
   lut_gap = bitlen / FP_LUT;
12573
12574
   /* init the mu */
12575
   err = mp_init_copy(&fp_cache[idx].mu, mu);
12576
   if (err != MP_OKAY)
12577
       goto errout;
12578
12579
   /* copy base */
12580
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
12581
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
12582
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
12583
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
12584
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
12585
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
12586
       err = MP_MULMOD_E;
12587
       goto errout;
12588
   }
12589
12590
   /* make all single bit entries */
12591
   for (x = 1; x < FP_LUT; x++) {
12592
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
12593
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
12594
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
12595
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
12596
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
12597
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
12598
          err = MP_INIT_E;
12599
          goto errout;
12600
      } else {
12601
12602
         /* now double it bitlen/FP_LUT times */
12603
         for (y = 0; y < lut_gap; y++) {
12604
             if ((err = ecc_projective_dbl_point_safe(
12605
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12606
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
12607
                                      a, modulus, mp)) != MP_OKAY) {
12608
                 goto errout;
12609
             }
12610
         }
12611
     }
12612
  }
12613
12614
   /* now make all entries in increase order of hamming weight */
12615
   for (x = 2; x <= FP_LUT; x++) {
12616
       if (err != MP_OKAY)
12617
           goto errout;
12618
       for (y = 0; y < (1UL<<FP_LUT); y++) {
12619
           if (lut_orders[y].ham != (int)x) continue;
12620
12621
           /* perform the add */
12622
           if ((err = ecc_projective_add_point_safe(
12623
                           fp_cache[idx].LUT[lut_orders[y].terma],
12624
                           fp_cache[idx].LUT[lut_orders[y].termb],
12625
                           fp_cache[idx].LUT[y], a, modulus, mp,
12626
                           &infinity)) != MP_OKAY) {
12627
               goto errout;
12628
           }
12629
       }
12630
   }
12631
12632
   /* now map all entries back to affine space to make point addition faster */
12633
   for (x = 1; x < (1UL<<FP_LUT); x++) {
12634
       if (err != MP_OKAY)
12635
           break;
12636
12637
       /* convert z to normal from montgomery */
12638
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
12639
12640
       /* invert it */
12641
       if (err == MP_OKAY)
12642
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
12643
                         fp_cache[idx].LUT[x]->z);
12644
12645
       if (err == MP_OKAY)
12646
         /* now square it */
12647
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
12648
12649
       if (err == MP_OKAY)
12650
         /* fix x */
12651
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
12652
                         fp_cache[idx].LUT[x]->x);
12653
12654
       if (err == MP_OKAY)
12655
         /* get 1/z^3 */
12656
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
12657
12658
       if (err == MP_OKAY)
12659
         /* fix y */
12660
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
12661
                         fp_cache[idx].LUT[x]->y);
12662
12663
       if (err == MP_OKAY)
12664
         /* free z */
12665
         mp_clear(fp_cache[idx].LUT[x]->z);
12666
   }
12667
12668
  errout:
12669
12670
   mp_clear(tmp);
12671
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12672
12673
   if (err == MP_OKAY) {
12674
       fp_cache[idx].LUT_set = 1;
12675
       return MP_OKAY;
12676
   }
12677
12678
   /* err cleanup */
12679
   for (y = 0; y < (1U<<FP_LUT); y++) {
12680
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
12681
      fp_cache[idx].LUT[y] = NULL;
12682
   }
12683
   wc_ecc_del_point(fp_cache[idx].g);
12684
   fp_cache[idx].g         = NULL;
12685
   fp_cache[idx].LUT_set   = 0;
12686
   fp_cache[idx].lru_count = 0;
12687
   mp_clear(&fp_cache[idx].mu);
12688
12689
   return err;
12690
}
12691
12692
/* perform a fixed point ECC mulmod */
12693
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
12694
                        mp_int* modulus, mp_digit mp, int map)
12695
{
12696
#ifdef WOLFCRYPT_HAVE_SAKKE
12697
    #define KB_SIZE 256
12698
#else
12699
    #define KB_SIZE 128
12700
#endif
12701
12702
#ifdef WOLFSSL_SMALL_STACK
12703
   unsigned char* kb = NULL;
12704
   mp_int*        tk = NULL;
12705
   mp_int*        order = NULL;
12706
#else
12707
   unsigned char kb[KB_SIZE];
12708
   mp_int        tk[1];
12709
   mp_int        order[1];
12710
#endif
12711
   int      x, err;
12712
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
12713
   int first;
12714
   int tk_zeroize = 0;
12715
12716
#ifdef WOLFSSL_SMALL_STACK
12717
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12718
   if (tk == NULL) {
12719
      err = MEMORY_E; goto done;
12720
   }
12721
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12722
   if (order == NULL) {
12723
      err = MEMORY_E; goto done;
12724
   }
12725
#endif
12726
12727
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
12728
       err = MP_INIT_E; goto done;
12729
   }
12730
12731
   if ((err = mp_copy(k, tk)) != MP_OKAY)
12732
       goto done;
12733
   tk_zeroize = 1;
12734
12735
#ifdef WOLFSSL_CHECK_MEM_ZERO
12736
   mp_memzero_add("accel_fp_mul tk", tk);
12737
#endif
12738
12739
   /* if it's smaller than modulus we fine */
12740
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
12741
      /* find order */
12742
       y = (unsigned)mp_unsigned_bin_size(modulus);
12743
      for (x = 0; ecc_sets[x].size; x++) {
12744
         if (y <= (unsigned)ecc_sets[x].size) break;
12745
      }
12746
12747
      /* back off if we are on the 521 bit curve */
12748
      if (y == 66) --x;
12749
12750
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12751
                                                MP_RADIX_HEX)) != MP_OKAY) {
12752
         goto done;
12753
      }
12754
12755
      /* k must be less than modulus */
12756
      if (mp_cmp(tk, order) != MP_LT) {
12757
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
12758
            goto done;
12759
         }
12760
      }
12761
   }
12762
12763
   /* get bitlen and round up to next multiple of FP_LUT */
12764
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12765
   x       = bitlen % FP_LUT;
12766
   if (x) {
12767
      bitlen += FP_LUT - (unsigned)x;
12768
   }
12769
   lut_gap = bitlen / FP_LUT;
12770
12771
   /* get the k value */
12772
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
12773
      err = BUFFER_E; goto done;
12774
   }
12775
12776
   /* store k */
12777
#ifdef WOLFSSL_SMALL_STACK
12778
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12779
   if (kb == NULL) {
12780
      err = MEMORY_E; goto done;
12781
   }
12782
#endif
12783
12784
   XMEMSET(kb, 0, KB_SIZE);
12785
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
12786
   #ifdef WOLFSSL_CHECK_MEM_ZERO
12787
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
12788
   #endif
12789
      /* let's reverse kb so it's little endian */
12790
      x = 0;
12791
      y = (unsigned)mp_unsigned_bin_size(tk);
12792
      if (y > 0) {
12793
          y -= 1;
12794
      }
12795
12796
      while ((unsigned)x < y) {
12797
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
12798
         ++x; --y;
12799
      }
12800
12801
      /* at this point we can start, yipee */
12802
      first = 1;
12803
      for (x = (int)lut_gap-1; x >= 0; x--) {
12804
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
12805
             by x bits from the start */
12806
          bitpos = (unsigned)x;
12807
          for (y = z = 0; y < FP_LUT; y++) {
12808
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
12809
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
12810
                                    the mult in each loop */
12811
          }
12812
12813
          /* double if not first */
12814
          if (!first) {
12815
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
12816
                                                              mp)) != MP_OKAY) {
12817
                break;
12818
             }
12819
          }
12820
12821
          /* add if not first, otherwise copy */
12822
          if (!first && z) {
12823
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
12824
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
12825
                break;
12826
             }
12827
          } else if (z) {
12828
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
12829
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
12830
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
12831
                 err = MP_MEM;
12832
                 break;
12833
             }
12834
             first = 0;
12835
          }
12836
      }
12837
   }
12838
12839
   if (err == MP_OKAY) {
12840
      (void) z; /* Acknowledge the unused assignment */
12841
      ForceZero(kb, KB_SIZE);
12842
12843
      /* map R back from projective space */
12844
      if (map) {
12845
         err = ecc_map(R, modulus, mp);
12846
      } else {
12847
         err = MP_OKAY;
12848
      }
12849
   }
12850
12851
done:
12852
   /* cleanup */
12853
   mp_clear(order);
12854
   /* Ensure it was initialized. */
12855
   if (tk_zeroize) {
12856
       mp_forcezero(tk);
12857
   }
12858
12859
#ifdef WOLFSSL_SMALL_STACK
12860
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12861
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12862
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
12863
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
12864
   wc_MemZero_Check(kb, KB_SIZE);
12865
   mp_memzero_check(tk);
12866
#endif
12867
12868
#undef KB_SIZE
12869
12870
   return err;
12871
}
12872
#endif
12873
12874
#ifdef ECC_SHAMIR
12875
#if !defined(WOLFSSL_SP_MATH)
12876
/* perform a fixed point ECC mulmod */
12877
static int accel_fp_mul2add(int idx1, int idx2,
12878
                            mp_int* kA, mp_int* kB,
12879
                            ecc_point *R, mp_int* a,
12880
                            mp_int* modulus, mp_digit mp)
12881
{
12882
#define KB_SIZE 128
12883
12884
#ifdef WOLFSSL_SMALL_STACK
12885
   unsigned char* kb[2] = {NULL, NULL};
12886
   mp_int*        tka = NULL;
12887
   mp_int*        tkb = NULL;
12888
   mp_int*        order = NULL;
12889
#else
12890
   unsigned char kb[2][KB_SIZE];
12891
   mp_int        tka[1];
12892
   mp_int        tkb[1];
12893
   mp_int        order[1];
12894
#endif
12895
   int      x, err;
12896
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
12897
   int first;
12898
12899
#ifdef WOLFSSL_SMALL_STACK
12900
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12901
   if (tka == NULL) {
12902
      err = MEMORY_E; goto done;
12903
   }
12904
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12905
   if (tkb == NULL) {
12906
      err = MEMORY_E; goto done;
12907
   }
12908
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12909
   if (order == NULL) {
12910
      err = MEMORY_E; goto done;
12911
   }
12912
#endif
12913
12914
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
12915
      err = MP_INIT_E; goto done;
12916
   }
12917
12918
   /* if it's smaller than modulus we fine */
12919
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
12920
      /* find order */
12921
      y = (unsigned)mp_unsigned_bin_size(modulus);
12922
      for (x = 0; ecc_sets[x].size; x++) {
12923
         if (y <= (unsigned)ecc_sets[x].size) break;
12924
      }
12925
12926
      /* back off if we are on the 521 bit curve */
12927
      if (y == 66) --x;
12928
12929
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12930
                                                MP_RADIX_HEX)) != MP_OKAY) {
12931
         goto done;
12932
      }
12933
12934
      /* kA must be less than modulus */
12935
      if (mp_cmp(kA, order) != MP_LT) {
12936
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
12937
            goto done;
12938
         }
12939
      } else {
12940
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12941
            goto done;
12942
         }
12943
      }
12944
   } else {
12945
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
12946
         goto done;
12947
      }
12948
   }
12949
#ifdef WOLFSSL_CHECK_MEM_ZERO
12950
   mp_memzero_add("accel_fp_mul2add tka", tka);
12951
#endif
12952
12953
   /* if it's smaller than modulus we fine */
12954
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
12955
      /* find order */
12956
      y = (unsigned)mp_unsigned_bin_size(modulus);
12957
      for (x = 0; ecc_sets[x].size; x++) {
12958
         if (y <= (unsigned)ecc_sets[x].size) break;
12959
      }
12960
12961
      /* back off if we are on the 521 bit curve */
12962
      if (y == 66) --x;
12963
12964
      if ((err = mp_read_radix(order, ecc_sets[x].order,
12965
                                                MP_RADIX_HEX)) != MP_OKAY) {
12966
         goto done;
12967
      }
12968
12969
      /* kB must be less than modulus */
12970
      if (mp_cmp(kB, order) != MP_LT) {
12971
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
12972
            goto done;
12973
         }
12974
      } else {
12975
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12976
            goto done;
12977
         }
12978
      }
12979
   } else {
12980
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
12981
         goto done;
12982
      }
12983
   }
12984
#ifdef WOLFSSL_CHECK_MEM_ZERO
12985
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
12986
#endif
12987
12988
   /* get bitlen and round up to next multiple of FP_LUT */
12989
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
12990
   x       = bitlen % FP_LUT;
12991
   if (x) {
12992
      bitlen += FP_LUT - (unsigned)x;
12993
   }
12994
   lut_gap = bitlen / FP_LUT;
12995
12996
   /* get the k value */
12997
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
12998
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
12999
      err = BUFFER_E; goto done;
13000
   }
13001
13002
   /* store k */
13003
#ifdef WOLFSSL_SMALL_STACK
13004
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13005
   if (kb[0] == NULL) {
13006
      err = MEMORY_E; goto done;
13007
   }
13008
#endif
13009
13010
   XMEMSET(kb[0], 0, KB_SIZE);
13011
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13012
      goto done;
13013
   }
13014
#ifdef WOLFSSL_CHECK_MEM_ZERO
13015
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13016
#endif
13017
13018
   /* let's reverse kb so it's little endian */
13019
   x = 0;
13020
   y = (unsigned)mp_unsigned_bin_size(tka);
13021
   if (y > 0) {
13022
       y -= 1;
13023
   }
13024
   mp_clear(tka);
13025
   while ((unsigned)x < y) {
13026
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13027
      ++x; --y;
13028
   }
13029
13030
   /* store b */
13031
#ifdef WOLFSSL_SMALL_STACK
13032
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13033
   if (kb[1] == NULL) {
13034
      err = MEMORY_E; goto done;
13035
   }
13036
#endif
13037
13038
   XMEMSET(kb[1], 0, KB_SIZE);
13039
#ifdef WOLFSSL_CHECK_MEM_ZERO
13040
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13041
#endif
13042
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13043
      x = 0;
13044
      y = (unsigned)mp_unsigned_bin_size(tkb);
13045
      if (y > 0) {
13046
          y -= 1;
13047
      }
13048
13049
      while ((unsigned)x < y) {
13050
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13051
         ++x; --y;
13052
      }
13053
13054
      /* at this point we can start, yipee */
13055
      first = 1;
13056
      for (x = (int)lut_gap-1; x >= 0; x--) {
13057
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13058
             offset by x bits from the start */
13059
          bitpos = (unsigned)x;
13060
          for (y = zA = zB = 0; y < FP_LUT; y++) {
13061
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13062
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13063
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13064
                                      the mult in each loop */
13065
          }
13066
13067
          /* double if not first */
13068
          if (!first) {
13069
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13070
                                                              mp)) != MP_OKAY) {
13071
                break;
13072
             }
13073
13074
             /* add if not first, otherwise copy */
13075
             if (zA) {
13076
                if ((err = ecc_projective_add_point_safe(R,
13077
                                             fp_cache[idx1].LUT[zA], R, a,
13078
                                             modulus, mp, &first)) != MP_OKAY) {
13079
                   break;
13080
                }
13081
             }
13082
13083
             if (zB) {
13084
                if ((err = ecc_projective_add_point_safe(R,
13085
                                             fp_cache[idx2].LUT[zB], R, a,
13086
                                             modulus, mp, &first)) != MP_OKAY) {
13087
                   break;
13088
                }
13089
             }
13090
          } else {
13091
             if (zA) {
13092
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13093
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13094
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13095
                     err = MP_MEM;
13096
                     break;
13097
                 }
13098
                    first = 0;
13099
             }
13100
             if (zB && first == 0) {
13101
                if ((err = ecc_projective_add_point_safe(R,
13102
                                        fp_cache[idx2].LUT[zB], R, a,
13103
                                        modulus, mp, &first)) != MP_OKAY){
13104
                   break;
13105
                }
13106
             } else if (zB && first == 1) {
13107
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13108
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13109
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13110
                     err = MP_MEM;
13111
                     break;
13112
                 }
13113
                    first = 0;
13114
             }
13115
          }
13116
      }
13117
   }
13118
13119
done:
13120
   /* cleanup */
13121
   mp_forcezero(tkb);
13122
   mp_forcezero(tka);
13123
   mp_clear(order);
13124
13125
#ifdef WOLFSSL_SMALL_STACK
13126
   if (kb[0])
13127
#endif
13128
      ForceZero(kb[0], KB_SIZE);
13129
#ifdef WOLFSSL_SMALL_STACK
13130
   if (kb[1])
13131
#endif
13132
      ForceZero(kb[1], KB_SIZE);
13133
13134
#ifdef WOLFSSL_SMALL_STACK
13135
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13136
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13137
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13138
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13139
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13140
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13141
   wc_MemZero_Check(kb[1], KB_SIZE);
13142
   wc_MemZero_Check(kb[0], KB_SIZE);
13143
   mp_memzero_check(tkb);
13144
   mp_memzero_check(tka);
13145
#endif
13146
13147
#undef KB_SIZE
13148
13149
    if (err != MP_OKAY)
13150
        return err;
13151
13152
   return ecc_map(R, modulus, mp);
13153
}
13154
13155
13156
/** ECC Fixed Point mulmod global with heap hint used
13157
  Computes kA*A + kB*B = C using Shamir's Trick
13158
  A        First point to multiply
13159
  kA       What to multiple A by
13160
  B        Second point to multiply
13161
  kB       What to multiple B by
13162
  C        [out] Destination point (can overlap with A or B)
13163
  a        ECC curve parameter a
13164
  modulus  Modulus for curve
13165
  return MP_OKAY on success
13166
*/
13167
int ecc_mul2add(ecc_point* A, mp_int* kA,
13168
                ecc_point* B, mp_int* kB,
13169
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13170
{
13171
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13172
   mp_digit mp = 0;
13173
#ifdef WOLFSSL_SMALL_STACK
13174
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13175
13176
   if (mu == NULL)
13177
       return MP_MEM;
13178
#else
13179
   mp_int   mu[1];
13180
#endif
13181
13182
   err = mp_init(mu);
13183
   if (err != MP_OKAY) {
13184
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13185
       return err;
13186
   }
13187
13188
#ifndef HAVE_THREAD_LS
13189
#ifndef WOLFSSL_MUTEX_INITIALIZER
13190
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13191
        wc_InitMutex(&ecc_fp_lock);
13192
        initMutex = 1;
13193
   }
13194
#endif
13195
13196
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13197
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13198
      return BAD_MUTEX_E;
13199
   }
13200
#endif /* HAVE_THREAD_LS */
13201
13202
      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13203
13204
      /* find point */
13205
      idx1 = find_base(A);
13206
13207
      /* no entry? */
13208
      if (idx1 == -1) {
13209
         /* find hole and add it */
13210
         if ((idx1 = find_hole()) >= 0) {
13211
            err = add_entry(idx1, A);
13212
         }
13213
      }
13214
      if (err == MP_OKAY && idx1 != -1) {
13215
         /* increment LRU */
13216
         ++(fp_cache[idx1].lru_count);
13217
      }
13218
13219
      if (err == MP_OKAY) {
13220
        /* find point */
13221
        idx2 = find_base(B);
13222
13223
        /* no entry? */
13224
        if (idx2 == -1) {
13225
           /* find hole and add it */
13226
           if ((idx2 = find_hole()) >= 0)
13227
              err = add_entry(idx2, B);
13228
         }
13229
      }
13230
13231
      if (err == MP_OKAY && idx2 != -1) {
13232
         /* increment LRU */
13233
         ++(fp_cache[idx2].lru_count);
13234
      }
13235
13236
      if (err == MP_OKAY) {
13237
        /* if it's >= 2 AND the LUT is not set build the LUT */
13238
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13239
           /* compute mp */
13240
           err = mp_montgomery_setup(modulus, &mp);
13241
13242
           if (err == MP_OKAY) {
13243
             mpInit = 1;
13244
             err = mp_montgomery_calc_normalization(mu, modulus);
13245
           }
13246
13247
           if (err == MP_OKAY)
13248
             /* build the LUT */
13249
             err = build_lut(idx1, a, modulus, mp, mu);
13250
        }
13251
      }
13252
13253
      if (err == MP_OKAY) {
13254
        /* if it's >= 2 AND the LUT is not set build the LUT */
13255
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13256
           if (mpInit == 0) {
13257
                /* compute mp */
13258
                err = mp_montgomery_setup(modulus, &mp);
13259
                if (err == MP_OKAY) {
13260
                    mpInit = 1;
13261
                    err = mp_montgomery_calc_normalization(mu, modulus);
13262
                }
13263
            }
13264
13265
            if (err == MP_OKAY)
13266
              /* build the LUT */
13267
              err = build_lut(idx2, a, modulus, mp, mu);
13268
        }
13269
      }
13270
13271
13272
      if (err == MP_OKAY) {
13273
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13274
                                     fp_cache[idx2].LUT_set) {
13275
           if (mpInit == 0) {
13276
              /* compute mp */
13277
              err = mp_montgomery_setup(modulus, &mp);
13278
           }
13279
           if (err == MP_OKAY)
13280
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13281
        } else {
13282
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13283
        }
13284
      }
13285
13286
      RESTORE_VECTOR_REGISTERS();
13287
13288
#ifndef HAVE_THREAD_LS
13289
    wc_UnLockMutex(&ecc_fp_lock);
13290
#endif /* HAVE_THREAD_LS */
13291
    mp_clear(mu);
13292
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13293
13294
    return err;
13295
}
13296
#endif
13297
#endif /* ECC_SHAMIR */
13298
13299
/** ECC Fixed Point mulmod global
13300
    k        The multiplicand
13301
    G        Base point to multiply
13302
    R        [out] Destination of product
13303
    a        ECC curve parameter a
13304
    modulus  The modulus for the curve
13305
    map      [boolean] If non-zero maps the point back to affine coordinates,
13306
             otherwise it's left in jacobian-montgomery form
13307
    return MP_OKAY if successful
13308
*/
13309
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13310
    mp_int* modulus, int map, void* heap)
13311
{
13312
#if !defined(WOLFSSL_SP_MATH)
13313
   int   idx, err = MP_OKAY;
13314
   mp_digit mp = 0;
13315
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13316
   int      mpSetup = 0;
13317
#ifndef HAVE_THREAD_LS
13318
   int got_ecc_fp_lock = 0;
13319
#endif
13320
13321
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13322
       return ECC_BAD_ARG_E;
13323
   }
13324
13325
   /* k can't have more bits than modulus count plus 1 */
13326
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13327
      return ECC_OUT_OF_RANGE_E;
13328
   }
13329
13330
#ifdef WOLFSSL_SMALL_STACK
13331
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13332
       return MP_MEM;
13333
#endif
13334
13335
   if (mp_init(mu) != MP_OKAY) {
13336
       err = MP_INIT_E;
13337
       goto out;
13338
   }
13339
13340
#ifndef HAVE_THREAD_LS
13341
#ifndef WOLFSSL_MUTEX_INITIALIZER
13342
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13343
        wc_InitMutex(&ecc_fp_lock);
13344
        initMutex = 1;
13345
   }
13346
#endif
13347
13348
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13349
      err = BAD_MUTEX_E;
13350
      goto out;
13351
   }
13352
   got_ecc_fp_lock = 1;
13353
#endif /* HAVE_THREAD_LS */
13354
13355
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13356
13357
      /* find point */
13358
      idx = find_base(G);
13359
13360
      /* no entry? */
13361
      if (idx == -1) {
13362
         /* find hole and add it */
13363
         idx = find_hole();
13364
13365
         if (idx >= 0)
13366
            err = add_entry(idx, G);
13367
      }
13368
      if (err == MP_OKAY && idx >= 0) {
13369
         /* increment LRU */
13370
         ++(fp_cache[idx].lru_count);
13371
      }
13372
13373
13374
      if (err == MP_OKAY) {
13375
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13376
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13377
           /* compute mp */
13378
           err = mp_montgomery_setup(modulus, &mp);
13379
13380
           if (err == MP_OKAY) {
13381
             /* compute mu */
13382
             mpSetup = 1;
13383
             err = mp_montgomery_calc_normalization(mu, modulus);
13384
           }
13385
13386
           if (err == MP_OKAY)
13387
             /* build the LUT */
13388
             err = build_lut(idx, a, modulus, mp, mu);
13389
        }
13390
      }
13391
13392
      if (err == MP_OKAY) {
13393
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13394
           if (mpSetup == 0) {
13395
              /* compute mp */
13396
              err = mp_montgomery_setup(modulus, &mp);
13397
           }
13398
           if (err == MP_OKAY)
13399
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13400
        } else {
13401
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
13402
        }
13403
      }
13404
13405
      RESTORE_VECTOR_REGISTERS();
13406
13407
  out:
13408
13409
#ifndef HAVE_THREAD_LS
13410
    if (got_ecc_fp_lock)
13411
        wc_UnLockMutex(&ecc_fp_lock);
13412
#endif /* HAVE_THREAD_LS */
13413
    mp_clear(mu);
13414
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13415
13416
    return err;
13417
13418
#else /* WOLFSSL_SP_MATH */
13419
13420
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13421
        return ECC_BAD_ARG_E;
13422
    }
13423
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13424
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13425
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13426
        return IS_POINT_E;
13427
    }
13428
13429
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13430
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13431
        int ret;
13432
        SAVE_VECTOR_REGISTERS(return _svr_ret);
13433
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13434
        RESTORE_VECTOR_REGISTERS();
13435
        return ret;
13436
    }
13437
#endif
13438
#ifndef WOLFSSL_SP_NO_256
13439
    if (mp_count_bits(modulus) == 256) {
13440
        int ret;
13441
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13442
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13443
        RESTORE_VECTOR_REGISTERS();
13444
        return ret;
13445
    }
13446
#endif
13447
#ifdef WOLFSSL_SP_384
13448
    if (mp_count_bits(modulus) == 384) {
13449
        int ret;
13450
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13451
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13452
        RESTORE_VECTOR_REGISTERS();
13453
        return ret;
13454
    }
13455
#endif
13456
#ifdef WOLFSSL_SP_521
13457
    if (mp_count_bits(modulus) == 521) {
13458
        int ret;
13459
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13460
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13461
        RESTORE_VECTOR_REGISTERS();
13462
        return ret;
13463
    }
13464
#endif
13465
    return WC_KEY_SIZE_E;
13466
#endif /* WOLFSSL_SP_MATH */
13467
}
13468
13469
/** ECC Fixed Point mulmod global
13470
    k        The multiplicand
13471
    G        Base point to multiply
13472
    R        [out] Destination of product
13473
    a        ECC curve parameter a
13474
    modulus  The modulus for the curve
13475
    map      [boolean] If non-zero maps the point back to affine coordinates,
13476
             otherwise it's left in jacobian-montgomery form
13477
    return MP_OKAY if successful
13478
*/
13479
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13480
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
13481
{
13482
#if !defined(WOLFSSL_SP_MATH)
13483
   int   idx, err = MP_OKAY;
13484
   mp_digit mp = 0;
13485
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13486
   int      mpSetup = 0;
13487
#ifndef HAVE_THREAD_LS
13488
   int got_ecc_fp_lock = 0;
13489
#endif
13490
13491
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13492
                                                                order == NULL) {
13493
       return ECC_BAD_ARG_E;
13494
   }
13495
13496
   /* k can't have more bits than order */
13497
   if (mp_count_bits(k) > mp_count_bits(order)) {
13498
      return ECC_OUT_OF_RANGE_E;
13499
   }
13500
13501
#ifdef WOLFSSL_SMALL_STACK
13502
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13503
       return MP_MEM;
13504
#endif
13505
13506
   if (mp_init(mu) != MP_OKAY) {
13507
       err = MP_INIT_E;
13508
       goto out;
13509
   }
13510
13511
#ifndef HAVE_THREAD_LS
13512
#ifndef WOLFSSL_MUTEX_INITIALIZER
13513
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13514
        wc_InitMutex(&ecc_fp_lock);
13515
        initMutex = 1;
13516
   }
13517
#endif
13518
13519
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13520
      err = BAD_MUTEX_E;
13521
      goto out;
13522
   }
13523
   got_ecc_fp_lock = 1;
13524
#endif /* HAVE_THREAD_LS */
13525
13526
      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
13527
13528
      /* find point */
13529
      idx = find_base(G);
13530
13531
      /* no entry? */
13532
      if (idx == -1) {
13533
         /* find hole and add it */
13534
         idx = find_hole();
13535
13536
         if (idx >= 0)
13537
            err = add_entry(idx, G);
13538
      }
13539
      if (err == MP_OKAY && idx >= 0) {
13540
         /* increment LRU */
13541
         ++(fp_cache[idx].lru_count);
13542
      }
13543
13544
13545
      if (err == MP_OKAY) {
13546
        /* if it's 2 build the LUT, if it's higher just use the LUT */
13547
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
13548
           /* compute mp */
13549
           err = mp_montgomery_setup(modulus, &mp);
13550
13551
           if (err == MP_OKAY) {
13552
             /* compute mu */
13553
             mpSetup = 1;
13554
             err = mp_montgomery_calc_normalization(mu, modulus);
13555
           }
13556
13557
           if (err == MP_OKAY)
13558
             /* build the LUT */
13559
             err = build_lut(idx, a, modulus, mp, mu);
13560
        }
13561
      }
13562
13563
      if (err == MP_OKAY) {
13564
        if (idx >= 0 && fp_cache[idx].LUT_set) {
13565
           if (mpSetup == 0) {
13566
              /* compute mp */
13567
              err = mp_montgomery_setup(modulus, &mp);
13568
           }
13569
           if (err == MP_OKAY)
13570
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
13571
        } else {
13572
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
13573
        }
13574
      }
13575
13576
      RESTORE_VECTOR_REGISTERS();
13577
13578
  out:
13579
13580
#ifndef HAVE_THREAD_LS
13581
    if (got_ecc_fp_lock)
13582
        wc_UnLockMutex(&ecc_fp_lock);
13583
#endif /* HAVE_THREAD_LS */
13584
    mp_clear(mu);
13585
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13586
13587
    return err;
13588
13589
#else /* WOLFSSL_SP_MATH */
13590
13591
    (void)rng;
13592
13593
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
13594
                                                                order == NULL) {
13595
        return ECC_BAD_ARG_E;
13596
    }
13597
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
13598
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
13599
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
13600
        return IS_POINT_E;
13601
    }
13602
13603
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
13604
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
13605
        int ret;
13606
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13607
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
13608
        RESTORE_VECTOR_REGISTERS();
13609
        return ret;
13610
    }
13611
#endif
13612
#ifndef WOLFSSL_SP_NO_256
13613
    if (mp_count_bits(modulus) == 256) {
13614
        int ret;
13615
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13616
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
13617
        RESTORE_VECTOR_REGISTERS();
13618
        return ret;
13619
    }
13620
#endif
13621
#ifdef WOLFSSL_SP_384
13622
    if (mp_count_bits(modulus) == 384) {
13623
        int ret;
13624
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13625
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
13626
        RESTORE_VECTOR_REGISTERS();
13627
        return ret;
13628
    }
13629
#endif
13630
#ifdef WOLFSSL_SP_521
13631
    if (mp_count_bits(modulus) == 521) {
13632
        int ret;
13633
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
13634
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
13635
        RESTORE_VECTOR_REGISTERS();
13636
        return ret;
13637
    }
13638
#endif
13639
    return WC_KEY_SIZE_E;
13640
#endif /* WOLFSSL_SP_MATH */
13641
}
13642
13643
#if !defined(WOLFSSL_SP_MATH)
13644
/* helper function for freeing the cache ...
13645
   must be called with the cache mutex locked */
13646
static void wc_ecc_fp_free_cache(void)
13647
{
13648
   unsigned x, y;
13649
   for (x = 0; x < FP_ENTRIES; x++) {
13650
      if (fp_cache[x].g != NULL) {
13651
         for (y = 0; y < (1U<<FP_LUT); y++) {
13652
            wc_ecc_del_point(fp_cache[x].LUT[y]);
13653
            fp_cache[x].LUT[y] = NULL;
13654
         }
13655
         wc_ecc_del_point(fp_cache[x].g);
13656
         fp_cache[x].g         = NULL;
13657
         mp_clear(&fp_cache[x].mu);
13658
         fp_cache[x].LUT_set   = 0;
13659
         fp_cache[x].lru_count = 0;
13660
         fp_cache[x].lock = 0;
13661
      }
13662
   }
13663
}
13664
#endif
13665
13666
13667
/** Init the Fixed Point cache */
13668
void wc_ecc_fp_init(void)
13669
{
13670
#ifndef WOLFSSL_SP_MATH
13671
#ifndef HAVE_THREAD_LS
13672
#ifndef WOLFSSL_MUTEX_INITIALIZER
13673
   if (initMutex == 0) {
13674
        wc_InitMutex(&ecc_fp_lock);
13675
        initMutex = 1;
13676
   }
13677
#endif
13678
#endif
13679
#endif
13680
}
13681
13682
13683
/** Free the Fixed Point cache */
13684
WOLFSSL_ABI
13685
void wc_ecc_fp_free(void)
13686
{
13687
#if !defined(WOLFSSL_SP_MATH)
13688
#ifndef HAVE_THREAD_LS
13689
#ifndef WOLFSSL_MUTEX_INITIALIZER
13690
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13691
        wc_InitMutex(&ecc_fp_lock);
13692
        initMutex = 1;
13693
   }
13694
#endif
13695
13696
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
13697
#endif /* HAVE_THREAD_LS */
13698
13699
       wc_ecc_fp_free_cache();
13700
13701
#ifndef HAVE_THREAD_LS
13702
       wc_UnLockMutex(&ecc_fp_lock);
13703
#ifndef WOLFSSL_MUTEX_INITIALIZER
13704
       wc_FreeMutex(&ecc_fp_lock);
13705
       initMutex = 0;
13706
#endif
13707
   }
13708
#endif /* HAVE_THREAD_LS */
13709
#endif
13710
}
13711
13712
13713
#endif /* FP_ECC */
13714
13715
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
13716
6.94k
{
13717
6.94k
    int err = 0;
13718
13719
6.94k
#ifdef ECC_TIMING_RESISTANT
13720
6.94k
    if (key == NULL) {
13721
0
        err = BAD_FUNC_ARG;
13722
0
    }
13723
6.94k
    else {
13724
6.94k
        key->rng = rng;
13725
6.94k
    }
13726
#else
13727
    (void)key;
13728
    (void)rng;
13729
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
13730
#endif
13731
13732
6.94k
    return err;
13733
6.94k
}
13734
13735
#ifdef HAVE_ECC_ENCRYPT
13736
13737
13738
enum ecCliState {
13739
    ecCLI_INIT      = 1,
13740
    ecCLI_SALT_GET  = 2,
13741
    ecCLI_SALT_SET  = 3,
13742
    ecCLI_SENT_REQ  = 4,
13743
    ecCLI_RECV_RESP = 5,
13744
    ecCLI_BAD_STATE = 99
13745
};
13746
13747
enum ecSrvState {
13748
    ecSRV_INIT      = 1,
13749
    ecSRV_SALT_GET  = 2,
13750
    ecSRV_SALT_SET  = 3,
13751
    ecSRV_RECV_REQ  = 4,
13752
    ecSRV_SENT_RESP = 5,
13753
    ecSRV_BAD_STATE = 99
13754
};
13755
13756
13757
struct ecEncCtx {
13758
    const byte* kdfSalt;   /* optional salt for kdf */
13759
    const byte* kdfInfo;   /* optional info for kdf */
13760
    const byte* macSalt;   /* optional salt for mac */
13761
    word32    kdfSaltSz;   /* size of kdfSalt */
13762
    word32    kdfInfoSz;   /* size of kdfInfo */
13763
    word32    macSaltSz;   /* size of macSalt */
13764
    void*     heap;        /* heap hint for memory used */
13765
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13766
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
13767
    byte      encAlgo;     /* which encryption type */
13768
    byte      kdfAlgo;     /* which key derivation function type */
13769
    byte      macAlgo;     /* which mac function type */
13770
    byte      protocol;    /* are we REQ_RESP client or server ? */
13771
    byte      cliSt;       /* protocol state, for sanity checks */
13772
    byte      srvSt;       /* protocol state, for sanity checks */
13773
    WC_RNG*   rng;
13774
};
13775
13776
/* optional set info, can be called before or after set_peer_salt */
13777
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
13778
0
{
13779
0
    if (ctx == NULL)
13780
0
        return BAD_FUNC_ARG;
13781
13782
0
    ctx->encAlgo = encAlgo;
13783
0
    ctx->kdfAlgo = kdfAlgo;
13784
0
    ctx->macAlgo = macAlgo;
13785
13786
0
    return 0;
13787
0
}
13788
13789
13790
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
13791
0
{
13792
0
    if (ctx == NULL || ctx->protocol == 0)
13793
0
        return NULL;
13794
13795
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13796
0
        if (ctx->cliSt == ecCLI_INIT) {
13797
0
            ctx->cliSt =  ecCLI_SALT_GET;
13798
0
            return ctx->clientSalt;
13799
0
        }
13800
0
        else {
13801
0
            ctx->cliSt = ecCLI_BAD_STATE;
13802
0
            return NULL;
13803
0
        }
13804
0
    }
13805
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13806
0
        if (ctx->srvSt == ecSRV_INIT) {
13807
0
            ctx->srvSt =  ecSRV_SALT_GET;
13808
0
            return ctx->serverSalt;
13809
0
        }
13810
0
        else {
13811
0
            ctx->srvSt = ecSRV_BAD_STATE;
13812
0
            return NULL;
13813
0
        }
13814
0
    }
13815
13816
0
    return NULL;
13817
0
}
13818
13819
13820
/* optional set info, can be called before or after set_peer_salt */
13821
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
13822
0
{
13823
0
    if (ctx == NULL || info == 0 || sz < 0)
13824
0
        return BAD_FUNC_ARG;
13825
13826
0
    ctx->kdfInfo   = info;
13827
0
    ctx->kdfInfoSz = (word32)sz;
13828
13829
0
    return 0;
13830
0
}
13831
13832
13833
static const char* exchange_info = "Secure Message Exchange";
13834
13835
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
13836
0
{
13837
0
    byte tmp[EXCHANGE_SALT_SZ/2];
13838
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
13839
13840
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13841
0
        return BAD_FUNC_ARG;
13842
13843
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13844
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
13845
0
        if (ctx->cliSt == ecCLI_SALT_GET)
13846
0
            ctx->cliSt =  ecCLI_SALT_SET;
13847
0
        else {
13848
0
            ctx->cliSt =  ecCLI_BAD_STATE;
13849
0
            return BAD_STATE_E;
13850
0
        }
13851
0
    }
13852
0
    else {
13853
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
13854
0
        if (ctx->srvSt == ecSRV_SALT_GET)
13855
0
            ctx->srvSt =  ecSRV_SALT_SET;
13856
0
        else {
13857
0
            ctx->srvSt =  ecSRV_BAD_STATE;
13858
0
            return BAD_STATE_E;
13859
0
        }
13860
0
    }
13861
13862
    /* mix half and half */
13863
    /* tmp stores 2nd half of client before overwrite */
13864
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
13865
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
13866
0
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
13867
13868
0
    ctx->kdfSalt   = ctx->clientSalt;
13869
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
13870
13871
0
    ctx->macSalt   = ctx->serverSalt;
13872
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
13873
13874
0
    if (ctx->kdfInfo == NULL) {
13875
        /* default info */
13876
0
        ctx->kdfInfo   = (const byte*)exchange_info;
13877
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
13878
0
    }
13879
13880
0
    return 0;
13881
0
}
13882
13883
/* Set the salt pointer into context.
13884
 *
13885
 * @param  [in, out]  ctx   ECIES context object.
13886
 * @param  [in]       salt  Salt to use with KDF.
13887
 * @param  [in]       sz    Length of salt in bytes.
13888
 * @return  0 on success.
13889
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13890
 */
13891
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13892
0
{
13893
0
    if (ctx == NULL || (salt == NULL && sz != 0))
13894
0
        return BAD_FUNC_ARG;
13895
13896
    /* truncate salt if exceeds max */
13897
0
    if (sz > EXCHANGE_SALT_SZ)
13898
0
        sz = EXCHANGE_SALT_SZ;
13899
13900
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
13901
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
13902
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
13903
0
        ctx->cliSt = ecCLI_SALT_SET;
13904
0
        ctx->kdfSalt = ctx->clientSalt;
13905
0
    }
13906
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
13907
0
        ctx->srvSt = ecSRV_SALT_SET;
13908
0
        ctx->kdfSalt = ctx->serverSalt;
13909
0
    }
13910
13911
0
    if (salt != NULL) {
13912
0
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
13913
0
    }
13914
0
    ctx->kdfSaltSz = sz;
13915
13916
0
    return 0;
13917
0
}
13918
13919
/* Set your own salt. By default we generate a random salt for ourselves.
13920
 * This allows overriding that after init or reset.
13921
 *
13922
 * @param  [in, out]  ctx   ECIES context object.
13923
 * @param  [in]       salt  Salt to use for ourselves
13924
 * @param  [in]       sz    Length of salt in bytes.
13925
 * @return  0 on success.
13926
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
13927
 */
13928
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
13929
0
{
13930
0
    byte* saltBuffer;
13931
13932
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
13933
0
        return BAD_FUNC_ARG;
13934
13935
0
    if (sz > EXCHANGE_SALT_SZ)
13936
0
        sz = EXCHANGE_SALT_SZ;
13937
0
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
13938
0
        ctx->clientSalt :
13939
0
        ctx->serverSalt;
13940
0
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
13941
0
    XMEMCPY(saltBuffer, salt, sz);
13942
13943
0
    return 0;
13944
0
}
13945
13946
13947
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
13948
0
{
13949
0
    byte* saltBuffer;
13950
13951
0
    if (ctx == NULL || flags == 0)
13952
0
        return BAD_FUNC_ARG;
13953
13954
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
13955
13956
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
13957
0
}
13958
13959
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
13960
1.39k
{
13961
1.39k
    if (ctx) {
13962
1.39k
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
13963
13964
1.39k
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
13965
1.39k
        #ifdef WOLFSSL_AES_128
13966
1.39k
            ctx->encAlgo  = ecAES_128_CBC;
13967
        #else
13968
            ctx->encAlgo  = ecAES_256_CBC;
13969
        #endif
13970
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
13971
        #ifdef WOLFSSL_AES_256
13972
            ctx->encAlgo  = ecAES_256_CTR;
13973
        #else
13974
            ctx->encAlgo  = ecAES_128_CTR;
13975
        #endif
13976
    #else
13977
        #error "No valid encryption algorithm for ECIES configured."
13978
    #endif
13979
1.39k
        ctx->kdfAlgo  = ecHKDF_SHA256;
13980
1.39k
        ctx->macAlgo  = ecHMAC_SHA256;
13981
1.39k
        ctx->protocol = (byte)flags;
13982
1.39k
        ctx->rng      = rng;
13983
13984
1.39k
        if (flags == REQ_RESP_CLIENT)
13985
0
            ctx->cliSt = ecCLI_INIT;
13986
1.39k
        if (flags == REQ_RESP_SERVER)
13987
0
            ctx->srvSt = ecSRV_INIT;
13988
1.39k
    }
13989
1.39k
}
13990
13991
13992
/* allow ecc context reset so user doesn't have to init/free for reuse */
13993
WOLFSSL_ABI
13994
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
13995
0
{
13996
0
    if (ctx == NULL || rng == NULL)
13997
0
        return BAD_FUNC_ARG;
13998
13999
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
14000
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
14001
0
}
14002
14003
14004
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14005
0
{
14006
0
    int       ret = 0;
14007
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14008
0
                                                              DYNAMIC_TYPE_ECC);
14009
14010
0
    if (ctx) {
14011
0
        ctx->protocol = (byte)flags;
14012
0
        ctx->heap     = heap;
14013
0
    }
14014
14015
0
    ret = wc_ecc_ctx_reset(ctx, rng);
14016
0
    if (ret != 0) {
14017
0
        wc_ecc_ctx_free(ctx);
14018
0
        ctx = NULL;
14019
0
    }
14020
14021
0
    return ctx;
14022
0
}
14023
14024
14025
/* alloc/init and set defaults, return new Context  */
14026
WOLFSSL_ABI
14027
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14028
0
{
14029
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14030
0
}
14031
14032
14033
/* free any resources, clear any keys */
14034
WOLFSSL_ABI
14035
void wc_ecc_ctx_free(ecEncCtx* ctx)
14036
0
{
14037
0
    if (ctx) {
14038
0
        void* heap = ctx->heap;
14039
0
        ForceZero(ctx, sizeof(ecEncCtx));
14040
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14041
0
        (void)heap;
14042
0
    }
14043
0
}
14044
14045
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14046
                             int* keysLen, word32* digestSz, word32* blockSz)
14047
1.39k
{
14048
1.39k
    if (ctx) {
14049
1.39k
        switch (ctx->encAlgo) {
14050
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14051
1.39k
            case ecAES_128_CBC:
14052
1.39k
                *encKeySz = KEY_SIZE_128;
14053
1.39k
                *ivSz     = IV_SIZE_128;
14054
1.39k
                *blockSz  = WC_AES_BLOCK_SIZE;
14055
1.39k
                break;
14056
0
            case ecAES_256_CBC:
14057
0
                *encKeySz = KEY_SIZE_256;
14058
0
                *ivSz     = IV_SIZE_128;
14059
0
                *blockSz  = WC_AES_BLOCK_SIZE;
14060
0
                break;
14061
0
        #endif
14062
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14063
0
            case ecAES_128_CTR:
14064
0
                *encKeySz = KEY_SIZE_128;
14065
0
                *ivSz     = 12;
14066
0
                *blockSz  = 1;
14067
0
                break;
14068
0
            case ecAES_256_CTR:
14069
0
                *encKeySz = KEY_SIZE_256;
14070
0
                *ivSz     = 12;
14071
0
                *blockSz  = 1;
14072
0
                break;
14073
0
        #endif
14074
0
            default:
14075
0
                return BAD_FUNC_ARG;
14076
1.39k
        }
14077
14078
1.39k
        switch (ctx->macAlgo) {
14079
1.39k
            case ecHMAC_SHA256:
14080
1.39k
                *digestSz = WC_SHA256_DIGEST_SIZE;
14081
1.39k
                break;
14082
0
            default:
14083
0
                return BAD_FUNC_ARG;
14084
1.39k
        }
14085
1.39k
    } else
14086
0
        return BAD_FUNC_ARG;
14087
14088
#ifdef WOLFSSL_ECIES_OLD
14089
    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14090
#else
14091
1.39k
    *keysLen  = *encKeySz + (int)*digestSz;
14092
1.39k
#endif
14093
14094
1.39k
    return 0;
14095
1.39k
}
14096
14097
14098
/* ecc encrypt with shared secret run through kdf
14099
   ctx holds non default algos and inputs
14100
   msgSz should be the right size for encAlgo, i.e., already padded
14101
   return 0 on success */
14102
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14103
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14104
576
{
14105
576
    int          ret = 0;
14106
576
    word32       blockSz = 0;
14107
576
#ifndef WOLFSSL_ECIES_OLD
14108
576
#ifndef WOLFSSL_ECIES_GEN_IV
14109
576
    byte         iv[ECC_MAX_IV_SIZE];
14110
576
#endif
14111
576
    word32       pubKeySz = 0;
14112
576
#endif
14113
576
    word32       digestSz = 0;
14114
576
    ecEncCtx     localCtx;
14115
576
#ifdef WOLFSSL_SMALL_STACK
14116
576
    byte*        sharedSecret;
14117
576
    byte*        keys;
14118
#else
14119
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14120
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14121
#else
14122
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14123
#endif
14124
    byte         keys[ECC_BUFSIZE];         /* max size */
14125
#endif
14126
576
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14127
576
    word32       sharedSz = ECC_MAXSIZE;
14128
#else
14129
    /* 'Uncompressed' byte | public key x | public key y | secret */
14130
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14131
#endif
14132
576
    int          keysLen = 0;
14133
576
    int          encKeySz = 0;
14134
576
    int          ivSz = 0;
14135
576
    int          offset = 0;         /* keys offset if doing msg exchange */
14136
576
    byte*        encKey = NULL;
14137
576
    byte*        encIv = NULL;
14138
576
    byte*        macKey = NULL;
14139
14140
576
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14141
541
                           outSz  == NULL)
14142
35
        return BAD_FUNC_ARG;
14143
14144
541
    if (ctx == NULL) {  /* use defaults */
14145
541
        ecc_ctx_init(&localCtx, 0, NULL);
14146
541
        ctx = &localCtx;
14147
541
    }
14148
14149
541
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14150
541
                            &blockSz);
14151
541
    if (ret != 0)
14152
0
        return ret;
14153
14154
541
#ifndef WOLFSSL_ECIES_OLD
14155
541
    if (!compressed) {
14156
541
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14157
541
    }
14158
0
    else {
14159
0
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14160
0
    }
14161
#else
14162
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14163
#endif
14164
14165
541
    if (ctx->protocol == REQ_RESP_SERVER) {
14166
0
        offset = keysLen;
14167
0
        keysLen *= 2;
14168
14169
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
14170
0
            return BAD_STATE_E;
14171
14172
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14173
0
    }
14174
541
    else if (ctx->protocol == REQ_RESP_CLIENT) {
14175
0
        if (ctx->cliSt != ecCLI_SALT_SET)
14176
0
            return BAD_STATE_E;
14177
14178
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14179
0
    }
14180
14181
541
    if (keysLen > ECC_BUFSIZE) /* keys size */
14182
0
        return BUFFER_E;
14183
14184
541
    if ((msgSz % blockSz) != 0)
14185
39
        return BAD_PADDING_E;
14186
14187
#ifdef WOLFSSL_ECIES_OLD
14188
    if (*outSz < (msgSz + digestSz))
14189
        return BUFFER_E;
14190
#elif defined(WOLFSSL_ECIES_GEN_IV)
14191
    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14192
        return BUFFER_E;
14193
#else
14194
502
    if (*outSz < (pubKeySz + msgSz + digestSz))
14195
11
        return BUFFER_E;
14196
491
#endif
14197
14198
491
#ifdef ECC_TIMING_RESISTANT
14199
491
    if (ctx->rng != NULL && privKey->rng == NULL)
14200
0
        privKey->rng = ctx->rng;
14201
491
#endif
14202
14203
491
#ifndef WOLFSSL_ECIES_OLD
14204
491
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14205
491
#ifdef ECC_TIMING_RESISTANT
14206
491
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14207
#else
14208
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14209
#endif
14210
491
        if (ret != 0)
14211
173
            return ret;
14212
491
    }
14213
318
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14214
318
    if (ret != 0)
14215
8
        return ret;
14216
310
    out += pubKeySz;
14217
310
#endif
14218
14219
310
#ifdef WOLFSSL_SMALL_STACK
14220
310
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14221
310
    if (sharedSecret == NULL)
14222
4
        return MEMORY_E;
14223
14224
306
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14225
306
    if (keys == NULL) {
14226
7
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14227
7
        return MEMORY_E;
14228
7
    }
14229
299
#endif
14230
14231
299
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14232
14233
#ifdef WOLFSSL_ECIES_ISO18033
14234
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14235
    sharedSz -= pubKeySz;
14236
#endif
14237
14238
299
    do {
14239
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14240
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14241
        if (ret != 0)
14242
            break;
14243
    #endif
14244
299
    #ifndef WOLFSSL_ECIES_ISO18033
14245
299
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14246
    #else
14247
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14248
                                                                     &sharedSz);
14249
    #endif
14250
299
    }
14251
299
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14252
14253
299
    if (ret == 0) {
14254
    #ifdef WOLFSSL_ECIES_ISO18033
14255
        /* KDF data is encoded public key and secret. */
14256
        sharedSz += pubKeySz;
14257
    #endif
14258
288
        switch (ctx->kdfAlgo) {
14259
288
            case ecHKDF_SHA256 :
14260
288
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14261
288
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14262
288
                           keys, (word32)keysLen);
14263
288
                break;
14264
0
            case ecHKDF_SHA1 :
14265
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14266
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14267
0
                           keys, (word32)keysLen);
14268
0
                break;
14269
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14270
0
            case ecKDF_X963_SHA1 :
14271
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14272
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14273
0
                break;
14274
0
            case ecKDF_X963_SHA256 :
14275
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14276
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14277
0
                break;
14278
0
            case ecKDF_SHA1 :
14279
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14280
0
                           NULL, 0, keys, (word32)keysLen);
14281
0
                break;
14282
0
            case ecKDF_SHA256 :
14283
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14284
0
                           NULL, 0, keys, (word32)keysLen);
14285
0
                break;
14286
0
#endif
14287
14288
14289
0
            default:
14290
0
                ret = BAD_FUNC_ARG;
14291
0
                break;
14292
288
        }
14293
288
    }
14294
14295
299
    if (ret == 0) {
14296
    #ifdef WOLFSSL_ECIES_OLD
14297
        encKey = keys + offset;
14298
        encIv  = encKey + encKeySz;
14299
        macKey = encKey + encKeySz + ivSz;
14300
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14301
        encKey = keys + offset;
14302
        encIv  = out;
14303
        out += ivSz;
14304
        macKey = encKey + encKeySz;
14305
        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14306
    #else
14307
246
        XMEMSET(iv, 0, (size_t)ivSz);
14308
246
        encKey = keys + offset;
14309
246
        encIv  = iv;
14310
246
        macKey = encKey + encKeySz;
14311
246
    #endif
14312
246
    }
14313
14314
299
    if (ret == 0) {
14315
246
       switch (ctx->encAlgo) {
14316
246
            case ecAES_128_CBC:
14317
246
            case ecAES_256_CBC:
14318
246
            {
14319
246
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14320
246
            #ifdef WOLFSSL_SMALL_STACK
14321
246
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14322
246
                                          DYNAMIC_TYPE_AES);
14323
246
                if (aes == NULL) {
14324
10
                    ret = MEMORY_E;
14325
10
                    break;
14326
10
                }
14327
            #else
14328
                Aes aes[1];
14329
            #endif
14330
236
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14331
236
                if (ret == 0) {
14332
236
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14333
236
                                                                AES_ENCRYPTION);
14334
236
                    if (ret == 0) {
14335
236
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14336
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14337
                                                    defined(WC_ASYNC_ENABLE_AES)
14338
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14339
                                            WC_ASYNC_FLAG_NONE);
14340
                    #endif
14341
236
                    }
14342
236
                    wc_AesFree(aes);
14343
236
                }
14344
236
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14345
        #else
14346
                ret = NOT_COMPILED_IN;
14347
        #endif
14348
236
                break;
14349
246
            }
14350
0
            case ecAES_128_CTR:
14351
0
            case ecAES_256_CTR:
14352
0
            {
14353
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14354
0
                byte ctr_iv[WC_AES_BLOCK_SIZE];
14355
            #ifndef WOLFSSL_SMALL_STACK
14356
                Aes aes[1];
14357
            #else
14358
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14359
0
                                            DYNAMIC_TYPE_AES);
14360
0
                if (aes == NULL) {
14361
0
                    ret = MEMORY_E;
14362
0
                    break;
14363
0
                }
14364
0
            #endif
14365
14366
                /* Include 4 byte counter starting at all zeros. */
14367
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14368
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14369
0
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14370
14371
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14372
0
                if (ret == 0) {
14373
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14374
0
                                                                AES_ENCRYPTION);
14375
0
                    if (ret == 0) {
14376
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
14377
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14378
                                                    defined(WC_ASYNC_ENABLE_AES)
14379
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14380
                                            WC_ASYNC_FLAG_NONE);
14381
                    #endif
14382
0
                    }
14383
0
                    wc_AesFree(aes);
14384
0
                }
14385
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14386
        #else
14387
                ret = NOT_COMPILED_IN;
14388
        #endif
14389
0
                break;
14390
0
            }
14391
0
            default:
14392
0
                ret = BAD_FUNC_ARG;
14393
0
                break;
14394
246
        }
14395
246
    }
14396
14397
299
    if (ret == 0) {
14398
236
        switch (ctx->macAlgo) {
14399
236
            case ecHMAC_SHA256:
14400
236
            {
14401
236
            #ifdef WOLFSSL_SMALL_STACK
14402
236
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14403
236
                                             DYNAMIC_TYPE_HMAC);
14404
236
                if (hmac == NULL) {
14405
8
                    ret = MEMORY_E;
14406
8
                    break;
14407
8
                }
14408
            #else
14409
                Hmac hmac[1];
14410
            #endif
14411
228
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14412
228
                if (ret == 0) {
14413
228
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14414
228
                                                         WC_SHA256_DIGEST_SIZE);
14415
228
                    if (ret == 0) {
14416
228
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14417
228
                        ret = wc_HmacUpdate(hmac, out, msgSz);
14418
                    #else
14419
                        /* IV is before encrypted message. */
14420
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
14421
                    #endif
14422
228
                    }
14423
228
                    if (ret == 0)
14424
226
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14425
228
                    if (ret == 0)
14426
226
                        ret = wc_HmacFinal(hmac, out+msgSz);
14427
228
                    wc_HmacFree(hmac);
14428
228
                }
14429
228
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14430
228
                break;
14431
236
            }
14432
14433
0
            default:
14434
0
                ret = BAD_FUNC_ARG;
14435
0
                break;
14436
236
        }
14437
236
    }
14438
14439
299
    if (ret == 0) {
14440
#ifdef WOLFSSL_ECIES_OLD
14441
        *outSz = msgSz + digestSz;
14442
#elif defined(WOLFSSL_ECIES_GEN_IV)
14443
        *outSz = pubKeySz + ivSz + msgSz + digestSz;
14444
#else
14445
225
        *outSz = pubKeySz + msgSz + digestSz;
14446
225
#endif
14447
225
    }
14448
14449
299
    RESTORE_VECTOR_REGISTERS();
14450
14451
299
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14452
299
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14453
14454
299
    return ret;
14455
299
}
14456
14457
/* ecc encrypt with shared secret run through kdf
14458
   ctx holds non default algos and inputs
14459
   msgSz should be the right size for encAlgo, i.e., already padded
14460
   return 0 on success */
14461
WOLFSSL_ABI
14462
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14463
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14464
576
{
14465
576
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
14466
576
}
14467
14468
/* ecc decrypt with shared secret run through kdf
14469
   ctx holds non default algos and inputs
14470
   return 0 on success */
14471
WOLFSSL_ABI
14472
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14473
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
14474
877
{
14475
877
    int          ret = 0;
14476
877
    word32       blockSz = 0;
14477
877
#ifndef WOLFSSL_ECIES_OLD
14478
877
#ifndef WOLFSSL_ECIES_GEN_IV
14479
877
    byte         iv[ECC_MAX_IV_SIZE];
14480
877
#endif
14481
877
    word32       pubKeySz = 0;
14482
877
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
14483
877
#endif
14484
877
    word32       digestSz = 0;
14485
877
    ecEncCtx     localCtx;
14486
877
#ifdef WOLFSSL_SMALL_STACK
14487
877
    byte*        sharedSecret;
14488
877
    byte*        keys;
14489
#else
14490
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14491
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14492
#else
14493
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14494
#endif
14495
    byte         keys[ECC_BUFSIZE];         /* max size */
14496
#endif
14497
877
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14498
877
    word32       sharedSz = ECC_MAXSIZE;
14499
#else
14500
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
14501
#endif
14502
877
    int          keysLen = 0;
14503
877
    int          encKeySz = 0;
14504
877
    int          ivSz = 0;
14505
877
    int          offset = 0;       /* in case using msg exchange */
14506
877
    byte*        encKey = NULL;
14507
877
    const byte*  encIv = NULL;
14508
877
    byte*        macKey = NULL;
14509
14510
14511
877
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
14512
20
        return BAD_FUNC_ARG;
14513
#ifdef WOLFSSL_ECIES_OLD
14514
    if (pubKey == NULL)
14515
        return BAD_FUNC_ARG;
14516
#endif
14517
14518
857
    if (ctx == NULL) {  /* use defaults */
14519
857
        ecc_ctx_init(&localCtx, 0, NULL);
14520
857
        ctx = &localCtx;
14521
857
    }
14522
14523
857
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14524
857
                            &blockSz);
14525
857
    if (ret != 0)
14526
0
        return ret;
14527
14528
857
#ifndef WOLFSSL_ECIES_OLD
14529
857
    ret = ecc_public_key_size(privKey, &pubKeySz);
14530
857
    if (ret != 0)
14531
0
        return ret;
14532
857
#ifdef HAVE_COMP_KEY
14533
857
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
14534
637
        pubKeySz = (pubKeySz / 2) + 1;
14535
637
    }
14536
857
#endif /* HAVE_COMP_KEY */
14537
857
#endif /* WOLFSSL_ECIES_OLD */
14538
14539
857
    if (ctx->protocol == REQ_RESP_CLIENT) {
14540
0
        offset = keysLen;
14541
0
        keysLen *= 2;
14542
14543
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
14544
0
            return BAD_STATE_E;
14545
14546
0
        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14547
0
    }
14548
857
    else if (ctx->protocol == REQ_RESP_SERVER) {
14549
0
        if (ctx->srvSt != ecSRV_SALT_SET)
14550
0
            return BAD_STATE_E;
14551
14552
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
14553
0
    }
14554
14555
857
    if (keysLen > ECC_BUFSIZE) /* keys size */
14556
0
        return BUFFER_E;
14557
14558
#ifdef WOLFSSL_ECIES_OLD
14559
    if (((msgSz - digestSz) % blockSz) != 0)
14560
        return BAD_PADDING_E;
14561
14562
    if (*outSz < (msgSz - digestSz))
14563
        return BUFFER_E;
14564
#elif defined(WOLFSSL_ECIES_GEN_IV)
14565
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
14566
        return BAD_PADDING_E;
14567
14568
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
14569
        return BAD_FUNC_ARG;
14570
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
14571
        return BUFFER_E;
14572
#else
14573
857
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
14574
132
        return BAD_PADDING_E;
14575
14576
725
    if (msgSz < pubKeySz + blockSz + digestSz)
14577
13
        return BAD_FUNC_ARG;
14578
712
    if (*outSz < (msgSz - digestSz - pubKeySz))
14579
5
        return BUFFER_E;
14580
707
#endif
14581
14582
707
#ifdef ECC_TIMING_RESISTANT
14583
707
    if (ctx->rng != NULL && privKey->rng == NULL)
14584
0
        privKey->rng = ctx->rng;
14585
707
#endif
14586
14587
707
#ifdef WOLFSSL_SMALL_STACK
14588
707
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14589
707
    if (sharedSecret == NULL) {
14590
74
    #ifndef WOLFSSL_ECIES_OLD
14591
74
        if (pubKey == peerKey)
14592
0
            wc_ecc_free(peerKey);
14593
74
    #endif
14594
74
        return MEMORY_E;
14595
74
    }
14596
14597
633
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14598
633
    if (keys == NULL) {
14599
34
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14600
34
    #ifndef WOLFSSL_ECIES_OLD
14601
34
        if (pubKey == peerKey)
14602
0
            wc_ecc_free(peerKey);
14603
34
    #endif
14604
34
        return MEMORY_E;
14605
34
    }
14606
599
#endif
14607
14608
599
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14609
14610
599
#ifndef WOLFSSL_ECIES_OLD
14611
599
    if (pubKey == NULL) {
14612
0
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
14613
0
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
14614
0
        pubKey = peerKey;
14615
0
    }
14616
599
    else {
14617
        /* if a public key was passed in we should free it here before init
14618
         * and import */
14619
599
        wc_ecc_free(pubKey);
14620
599
    }
14621
599
    if (ret == 0) {
14622
599
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
14623
599
    }
14624
599
    if (ret == 0) {
14625
599
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
14626
599
    }
14627
599
    if (ret == 0) {
14628
        /* Point is not MACed. */
14629
210
        msg += pubKeySz;
14630
210
        msgSz -= pubKeySz;
14631
210
    }
14632
599
#endif
14633
14634
599
    if (ret == 0) {
14635
    #ifdef WOLFSSL_ECIES_ISO18033
14636
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
14637
        sharedSz -= pubKeySz;
14638
    #endif
14639
14640
210
        do {
14641
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14642
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
14643
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
14644
            if (ret != 0)
14645
                break;
14646
        #endif
14647
210
        #ifndef WOLFSSL_ECIES_ISO18033
14648
210
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
14649
210
                                                                    &sharedSz);
14650
        #else
14651
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
14652
                                                          pubKeySz, &sharedSz);
14653
        #endif
14654
210
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14655
210
    }
14656
599
    if (ret == 0) {
14657
    #ifdef WOLFSSL_ECIES_ISO18033
14658
        /* KDF data is encoded public key and secret. */
14659
        sharedSz += pubKeySz;
14660
    #endif
14661
187
        switch (ctx->kdfAlgo) {
14662
187
            case ecHKDF_SHA256 :
14663
187
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14664
187
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14665
187
                           keys, (word32)keysLen);
14666
187
                break;
14667
0
            case ecHKDF_SHA1 :
14668
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14669
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14670
0
                           keys, (word32)keysLen);
14671
0
                break;
14672
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14673
0
            case ecKDF_X963_SHA1 :
14674
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14675
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14676
0
                break;
14677
0
            case ecKDF_X963_SHA256 :
14678
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14679
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14680
0
                break;
14681
0
            case ecKDF_SHA1 :
14682
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14683
0
                           NULL, 0, keys, (word32)keysLen);
14684
0
                break;
14685
0
            case ecKDF_SHA256 :
14686
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14687
0
                           NULL, 0, keys, (word32)keysLen);
14688
0
                break;
14689
0
#endif
14690
14691
0
            default:
14692
0
                ret = BAD_FUNC_ARG;
14693
0
                break;
14694
187
         }
14695
187
    }
14696
14697
599
    if (ret == 0) {
14698
    #ifdef WOLFSSL_ECIES_OLD
14699
        encKey = keys + offset;
14700
        encIv  = encKey + encKeySz;
14701
        macKey = encKey + encKeySz + ivSz;
14702
    #elif defined(WOLFSSL_ECIES_GEN_IV)
14703
        encKey = keys + offset;
14704
        encIv  = msg;
14705
        msg   += ivSz;
14706
        msgSz -= ivSz;
14707
        macKey = encKey + encKeySz;
14708
    #else
14709
185
        XMEMSET(iv, 0, (size_t)ivSz);
14710
185
        encKey = keys + offset;
14711
185
        encIv  = iv;
14712
185
        macKey = encKey + encKeySz;
14713
185
    #endif
14714
14715
185
        switch (ctx->macAlgo) {
14716
185
            case ecHMAC_SHA256:
14717
185
            {
14718
185
                byte verify[WC_SHA256_DIGEST_SIZE];
14719
185
            #ifdef WOLFSSL_SMALL_STACK
14720
185
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
14721
185
                                             DYNAMIC_TYPE_HMAC);
14722
185
                if (hmac == NULL) {
14723
2
                    ret = MEMORY_E;
14724
2
                    break;
14725
2
                }
14726
            #else
14727
                Hmac hmac[1];
14728
            #endif
14729
183
                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
14730
183
                if (ret == 0) {
14731
183
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
14732
183
                                                         WC_SHA256_DIGEST_SIZE);
14733
183
                    if (ret == 0)
14734
183
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
14735
183
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
14736
                    #else
14737
                        /* IV is before encrypted message. */
14738
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
14739
                    #endif
14740
183
                    if (ret == 0)
14741
175
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
14742
14743
183
                    if (ret == 0)
14744
175
                        ret = wc_HmacFinal(hmac, verify);
14745
183
                    if ((ret == 0) && (XMEMCMP(verify, msg + msgSz - digestSz,
14746
167
                                                             digestSz) != 0)) {
14747
130
                        ret = HASH_TYPE_E;
14748
130
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
14749
130
                    }
14750
14751
183
                    wc_HmacFree(hmac);
14752
183
                }
14753
183
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
14754
183
                break;
14755
185
            }
14756
14757
0
            default:
14758
0
                ret = BAD_FUNC_ARG;
14759
0
                break;
14760
185
        }
14761
185
    }
14762
14763
599
    if (ret == 0) {
14764
37
        switch (ctx->encAlgo) {
14765
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14766
37
            case ecAES_128_CBC:
14767
37
            case ecAES_256_CBC:
14768
37
            {
14769
37
            #ifdef WOLFSSL_SMALL_STACK
14770
37
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14771
37
                                          DYNAMIC_TYPE_AES);
14772
37
                if (aes == NULL) {
14773
2
                    ret = MEMORY_E;
14774
2
                    break;
14775
2
                }
14776
            #else
14777
                Aes aes[1];
14778
            #endif
14779
35
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14780
35
                if (ret == 0) {
14781
35
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14782
35
                                                                AES_DECRYPTION);
14783
35
                    if (ret == 0) {
14784
35
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
14785
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14786
                                                    defined(WC_ASYNC_ENABLE_AES)
14787
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14788
                                                            WC_ASYNC_FLAG_NONE);
14789
                    #endif
14790
35
                    }
14791
35
                    wc_AesFree(aes);
14792
35
                }
14793
35
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14794
35
                break;
14795
37
            }
14796
0
        #endif
14797
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14798
0
            case ecAES_128_CTR:
14799
0
            case ecAES_256_CTR:
14800
0
            {
14801
0
            #ifdef WOLFSSL_SMALL_STACK
14802
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14803
0
                                          DYNAMIC_TYPE_AES);
14804
0
                if (aes == NULL) {
14805
0
                    ret = MEMORY_E;
14806
0
                    break;
14807
0
                }
14808
             #else
14809
                Aes aes[1];
14810
             #endif
14811
0
                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14812
0
                if (ret == 0) {
14813
0
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
14814
                    /* Make a 16 byte IV from the bytes passed in. */
14815
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
14816
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
14817
0
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
14818
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
14819
0
                                                                AES_ENCRYPTION);
14820
0
                    if (ret == 0) {
14821
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
14822
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14823
                                                    defined(WC_ASYNC_ENABLE_AES)
14824
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14825
                                                            WC_ASYNC_FLAG_NONE);
14826
                    #endif
14827
0
                    }
14828
0
                    wc_AesFree(aes);
14829
0
                }
14830
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
14831
0
                break;
14832
0
            }
14833
0
        #endif
14834
0
            default:
14835
0
                ret = BAD_FUNC_ARG;
14836
0
                break;
14837
37
        }
14838
37
    }
14839
14840
599
    if (ret == 0)
14841
35
       *outSz = msgSz - digestSz;
14842
14843
599
    RESTORE_VECTOR_REGISTERS();
14844
14845
599
#ifndef WOLFSSL_ECIES_OLD
14846
599
    if (pubKey == peerKey)
14847
0
        wc_ecc_free(peerKey);
14848
599
#endif
14849
599
#ifdef WOLFSSL_SMALL_STACK
14850
599
#ifndef WOLFSSL_ECIES_OLD
14851
599
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14852
599
#endif
14853
599
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14854
599
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14855
599
#endif
14856
14857
599
    return ret;
14858
599
}
14859
14860
14861
#endif /* HAVE_ECC_ENCRYPT */
14862
14863
14864
#ifdef HAVE_COMP_KEY
14865
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
14866
    !defined(WOLFSSL_CRYPTOCELL)
14867
14868
#ifndef WOLFSSL_SP_MATH
14869
#if !defined(SQRTMOD_USE_MOD_EXP)
14870
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
14871
 */
14872
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
14873
364
{
14874
364
#ifdef WOLFSSL_SMALL_STACK
14875
364
    mp_int*  a1 = NULL;
14876
364
    mp_int*  n1 = NULL;
14877
#else
14878
    mp_int   a1[1], n1[1];
14879
#endif
14880
364
    int      res;
14881
364
    int      s = 1;
14882
364
    int      k;
14883
364
    mp_int*  t[2];
14884
364
    mp_int*  ts;
14885
364
    mp_digit residue;
14886
14887
364
    if (mp_isneg(a) == MP_YES) {
14888
0
        return MP_VAL;
14889
0
    }
14890
364
    if (mp_isneg(n) == MP_YES) {
14891
0
        return MP_VAL;
14892
0
    }
14893
364
    if (mp_iseven(n) == MP_YES) {
14894
0
        return MP_VAL;
14895
0
    }
14896
14897
364
#ifdef WOLFSSL_SMALL_STACK
14898
364
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14899
364
    if (a1 == NULL) {
14900
1
        return MP_MEM;
14901
1
    }
14902
363
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
14903
363
    if (n1 == NULL) {
14904
1
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
14905
1
        return MP_MEM;
14906
1
    }
14907
362
#endif
14908
14909
362
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
14910
0
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14911
0
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14912
0
        return res;
14913
0
    }
14914
14915
362
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
14916
14917
362
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
14918
1
        goto done;
14919
1
    }
14920
14921
361
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
14922
1
        goto done;
14923
1
    }
14924
14925
360
    t[0] = a1;
14926
360
    t[1] = n1;
14927
14928
    /* Keep reducing until first number is 0. */
14929
10.9k
    while (!mp_iszero(t[0])) {
14930
        /* Divide by 2 until odd. */
14931
10.5k
        k = mp_cnt_lsb(t[0]);
14932
10.5k
        if (k > 0) {
14933
5.55k
            mp_rshb(t[0], k);
14934
14935
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
14936
             * Odd number of divides results in a negate.
14937
             */
14938
5.55k
            residue = t[1]->dp[0] & 7;
14939
5.55k
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
14940
1.82k
                s = -s;
14941
1.82k
            }
14942
5.55k
        }
14943
14944
        /* Swap t[0] and t[1]. */
14945
10.5k
        ts   = t[0];
14946
10.5k
        t[0] = t[1];
14947
10.5k
        t[1] = ts;
14948
14949
        /* Negate s if both numbers == 3 mod 4. */
14950
10.5k
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
14951
2.49k
             s = -s;
14952
2.49k
        }
14953
14954
        /* Reduce first number modulo second. */
14955
10.5k
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
14956
1.16k
            res = mp_sub(t[0], t[1], t[0]);
14957
1.16k
        }
14958
9.39k
        else {
14959
9.39k
            res = mp_mod(t[0], t[1], t[0]);
14960
9.39k
        }
14961
10.5k
        if (res != MP_OKAY) {
14962
11
            goto done;
14963
11
        }
14964
10.5k
    }
14965
14966
    /* When the two numbers have divisors in common. */
14967
349
    if (!mp_isone(t[1])) {
14968
0
        s = 0;
14969
0
    }
14970
349
    *c = s;
14971
14972
362
done:
14973
14974
362
    RESTORE_VECTOR_REGISTERS();
14975
14976
    /* cleanup */
14977
362
    mp_clear(n1);
14978
362
    mp_clear(a1);
14979
14980
362
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
14981
362
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
14982
14983
362
  return res;
14984
349
}
14985
#endif /* !SQRTMOD_USE_MOD_EXP */
14986
14987
14988
/* Solves the modular equation x^2 = n (mod p)
14989
 * where prime number is greater than 2 (odd prime).
14990
 * The result is returned in the third argument x
14991
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
14992
 */
14993
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
14994
126
{
14995
#if defined(SQRTMOD_USE_MOD_EXP)
14996
  int res;
14997
  mp_digit i;
14998
  mp_int e;
14999
15000
  /* first handle the simple cases n = 0 or n = 1 */
15001
  if (mp_cmp_d(n, 0) == MP_EQ) {
15002
      mp_zero(ret);
15003
      return MP_OKAY;
15004
  }
15005
  if (mp_cmp_d(n, 1) == MP_EQ) {
15006
      return mp_set(ret, 1);
15007
  }
15008
15009
  if (mp_iseven(prime)) {
15010
      return MP_VAL;
15011
  }
15012
15013
  SAVE_VECTOR_REGISTERS(return _svr_ret;);
15014
15015
  res = mp_init(&e);
15016
  if (res == MP_OKAY)
15017
      res = mp_mod_d(prime, 8, &i);
15018
  if (res == MP_OKAY && i == 1) {
15019
      return MP_VAL;
15020
  }
15021
  /* prime mod 8 = 5 */
15022
  else if (res == MP_OKAY && i == 5) {
15023
      res = mp_sub_d(prime, 1, &e);
15024
      if (res == MP_OKAY)
15025
          res = mp_div_2d(&e, 2, &e, NULL);
15026
  }
15027
  /* prime mod 4 = 3 */
15028
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
15029
      res = mp_add_d(prime, 1, &e);
15030
      if (res == MP_OKAY)
15031
          res = mp_div_2d(&e, 2, &e, NULL);
15032
  }
15033
  if (res == MP_OKAY)
15034
      res = mp_exptmod(n, &e, prime, ret);
15035
15036
  mp_clear(&e);
15037
15038
  RESTORE_VECTOR_REGISTERS();
15039
15040
  return res;
15041
#else
15042
126
  int res, legendre, done = 0;
15043
126
  mp_digit i;
15044
126
#ifdef WOLFSSL_SMALL_STACK
15045
126
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15046
126
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15047
126
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15048
126
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15049
126
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15050
126
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15051
126
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15052
126
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15053
126
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15054
126
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15055
#else
15056
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
15057
#endif
15058
15059
126
  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15060
15061
126
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15062
126
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15063
0
    res = MP_INIT_E;
15064
0
    goto out;
15065
0
  }
15066
15067
126
#ifdef WOLFSSL_SMALL_STACK
15068
126
  if ((t1 == NULL) ||
15069
124
      (C == NULL) ||
15070
123
      (Q == NULL) ||
15071
122
      (S == NULL) ||
15072
121
      (Z == NULL) ||
15073
120
      (M == NULL) ||
15074
119
      (T == NULL) ||
15075
118
      (R == NULL) ||
15076
117
      (N == NULL) ||
15077
115
      (two == NULL)) {
15078
12
    res = MP_MEM;
15079
12
    goto out;
15080
12
  }
15081
114
#endif
15082
15083
  /* first handle the simple cases n = 0 or n = 1 */
15084
114
  if (mp_cmp_d(n, 0) == MP_EQ) {
15085
0
    mp_zero(ret);
15086
0
    res = MP_OKAY;
15087
0
    goto out;
15088
0
  }
15089
114
  if (mp_cmp_d(n, 1) == MP_EQ) {
15090
0
    res = mp_set(ret, 1);
15091
0
    goto out;
15092
0
  }
15093
15094
  /* prime must be odd */
15095
114
  if (mp_cmp_d(prime, 2) == MP_EQ) {
15096
0
    res = MP_VAL;
15097
0
    goto out;
15098
0
  }
15099
15100
  /* reduce n to less than prime */
15101
114
  res = mp_mod(n, prime, N);
15102
114
  if (res != MP_OKAY) {
15103
2
    goto out;
15104
2
  }
15105
  /* when N is zero, sqrt is zero */
15106
112
  if (mp_iszero(N)) {
15107
0
    mp_set(ret, 0);
15108
0
    goto out;
15109
0
  }
15110
15111
  /* is quadratic non-residue mod prime */
15112
112
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15113
15
    goto out;
15114
15
  }
15115
97
  if (legendre == -1) {
15116
19
    res = MP_VAL;
15117
19
    goto out;
15118
19
  }
15119
15120
  /* SPECIAL CASE: if prime mod 4 == 3
15121
   * compute directly: res = n^(prime+1)/4 mod prime
15122
   * Handbook of Applied Cryptography algorithm 3.36
15123
   */
15124
78
  res = mp_mod_d(prime, 4, &i);
15125
78
  if (res == MP_OKAY && i == 3) {
15126
51
    res = mp_add_d(prime, 1, t1);
15127
15128
51
    if (res == MP_OKAY)
15129
51
      res = mp_div_2(t1, t1);
15130
51
    if (res == MP_OKAY)
15131
51
      res = mp_div_2(t1, t1);
15132
51
    if (res == MP_OKAY)
15133
51
      res = mp_exptmod(N, t1, prime, ret);
15134
15135
51
    done = 1;
15136
51
  }
15137
15138
  /* NOW: TonelliShanks algorithm */
15139
78
  if (res == MP_OKAY && done == 0) {
15140
15141
    /* factor out powers of 2 from prime-1, defining Q and S
15142
    *                                      as: prime-1 = Q*2^S */
15143
    /* Q = prime - 1 */
15144
27
    res = mp_copy(prime, Q);
15145
27
    if (res == MP_OKAY)
15146
27
      res = mp_sub_d(Q, 1, Q);
15147
15148
    /* S = 0 */
15149
27
    if (res == MP_OKAY)
15150
27
      mp_zero(S);
15151
15152
2.43k
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15153
      /* Q = Q / 2 */
15154
2.40k
      res = mp_div_2(Q, Q);
15155
15156
      /* S = S + 1 */
15157
2.40k
      if (res == MP_OKAY)
15158
2.40k
        res = mp_add_d(S, 1, S);
15159
2.40k
    }
15160
15161
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15162
    /* Z = 2 */
15163
27
    if (res == MP_OKAY)
15164
27
      res = mp_set_int(Z, 2);
15165
15166
252
    while (res == MP_OKAY) {
15167
252
      res = mp_jacobi(Z, prime, &legendre);
15168
252
      if (res == MP_OKAY && legendre == -1)
15169
27
        break;
15170
15171
225
#if defined(WOLFSSL_CUSTOM_CURVES)
15172
      /* P224R1 succeeds with a value of 11. */
15173
225
      if (mp_cmp_d(Z, 22) == MP_EQ) {
15174
        /* This is to clamp the loop in case 'prime' is not really prime */
15175
0
        res = MP_VAL;
15176
0
        break;
15177
0
      }
15178
225
#endif
15179
15180
      /* Z = Z + 1 */
15181
225
      if (res == MP_OKAY)
15182
225
        res = mp_add_d(Z, 1, Z);
15183
15184
225
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
15185
        /* This is to clamp the loop in case 'prime' is not really prime */
15186
0
        res = MP_VAL;
15187
0
        break;
15188
0
      }
15189
225
    }
15190
15191
    /* C = Z ^ Q mod prime */
15192
27
    if (res == MP_OKAY)
15193
27
      res = mp_exptmod(Z, Q, prime, C);
15194
15195
    /* t1 = (Q + 1) / 2 */
15196
27
    if (res == MP_OKAY)
15197
27
      res = mp_add_d(Q, 1, t1);
15198
27
    if (res == MP_OKAY)
15199
27
      res = mp_div_2(t1, t1);
15200
15201
    /* R = n ^ ((Q + 1) / 2) mod prime */
15202
27
    if (res == MP_OKAY)
15203
27
      res = mp_exptmod(N, t1, prime, R);
15204
15205
    /* T = n ^ Q mod prime */
15206
27
    if (res == MP_OKAY)
15207
27
      res = mp_exptmod(N, Q, prime, T);
15208
15209
    /* M = S */
15210
27
    if (res == MP_OKAY)
15211
27
      res = mp_copy(S, M);
15212
15213
27
    if (res == MP_OKAY)
15214
27
      res = mp_set_int(two, 2);
15215
15216
1.25k
    while (res == MP_OKAY && done == 0) {
15217
1.22k
      res = mp_copy(T, t1);
15218
15219
      /* reduce to 1 and count */
15220
1.22k
      i = 0;
15221
58.1k
      while (res == MP_OKAY) {
15222
58.1k
        if (mp_cmp_d(t1, 1) == MP_EQ)
15223
1.22k
            break;
15224
56.9k
        res = mp_exptmod(t1, two, prime, t1);
15225
56.9k
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
15226
          /* This is to clamp the loop in case 'prime' is not really prime */
15227
0
          res = MP_VAL;
15228
0
          break;
15229
0
        }
15230
56.9k
        if (res == MP_OKAY)
15231
56.9k
          i++;
15232
56.9k
      }
15233
1.22k
      if (res == MP_OKAY && i == 0) {
15234
27
        res = mp_copy(R, ret);
15235
27
        done = 1;
15236
27
      }
15237
15238
1.22k
      if (done == 0) {
15239
        /* t1 = 2 ^ (M - i - 1) */
15240
1.19k
        if (res == MP_OKAY)
15241
1.19k
          res = mp_sub_d(M, i, t1);
15242
1.19k
        if (res == MP_OKAY)
15243
1.19k
          res = mp_sub_d(t1, 1, t1);
15244
1.19k
        if (res == MP_OKAY)
15245
1.19k
          res = mp_exptmod(two, t1, prime, t1);
15246
15247
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15248
1.19k
        if (res == MP_OKAY)
15249
1.19k
          res = mp_exptmod(C, t1, prime, t1);
15250
15251
        /* C = (t1 * t1) mod prime */
15252
1.19k
        if (res == MP_OKAY)
15253
1.19k
          res = mp_sqrmod(t1, prime, C);
15254
15255
        /* R = (R * t1) mod prime */
15256
1.19k
        if (res == MP_OKAY)
15257
1.19k
          res = mp_mulmod(R, t1, prime, R);
15258
15259
        /* T = (T * C) mod prime */
15260
1.19k
        if (res == MP_OKAY)
15261
1.19k
          res = mp_mulmod(T, C, prime, T);
15262
15263
        /* M = i */
15264
1.19k
        if (res == MP_OKAY)
15265
1.19k
          res = mp_set(M, i);
15266
1.19k
      }
15267
1.22k
    }
15268
27
  }
15269
15270
126
  out:
15271
15272
126
  RESTORE_VECTOR_REGISTERS();
15273
15274
126
#ifdef WOLFSSL_SMALL_STACK
15275
126
  if (t1) {
15276
124
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15277
124
      mp_clear(t1);
15278
124
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15279
124
  }
15280
126
  if (C) {
15281
123
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15282
123
      mp_clear(C);
15283
123
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15284
123
  }
15285
126
  if (Q) {
15286
124
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15287
124
      mp_clear(Q);
15288
124
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15289
124
  }
15290
126
  if (S) {
15291
124
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15292
124
      mp_clear(S);
15293
124
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15294
124
  }
15295
126
  if (Z) {
15296
123
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15297
123
      mp_clear(Z);
15298
123
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15299
123
  }
15300
126
  if (M) {
15301
122
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15302
122
      mp_clear(M);
15303
122
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15304
122
  }
15305
126
  if (T) {
15306
122
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15307
122
      mp_clear(T);
15308
122
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15309
122
  }
15310
126
  if (R) {
15311
122
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15312
122
      mp_clear(R);
15313
122
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15314
122
  }
15315
126
  if (N) {
15316
122
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15317
122
      mp_clear(N);
15318
122
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15319
122
  }
15320
126
  if (two) {
15321
120
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15322
120
      mp_clear(two);
15323
120
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15324
120
  }
15325
#else
15326
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
15327
    mp_clear(t1);
15328
    mp_clear(C);
15329
    mp_clear(Q);
15330
    mp_clear(S);
15331
    mp_clear(Z);
15332
    mp_clear(M);
15333
    mp_clear(T);
15334
    mp_clear(R);
15335
    mp_clear(N);
15336
    mp_clear(two);
15337
  }
15338
#endif
15339
15340
126
  return res;
15341
78
#endif
15342
78
}
15343
#endif /* !WOLFSSL_SP_MATH */
15344
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
15345
15346
#ifdef HAVE_ECC_KEY_EXPORT
15347
/* export public ECC key in ANSI X9.63 format compressed */
15348
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
15349
257
{
15350
257
   word32 numlen;
15351
257
   int    ret = MP_OKAY;
15352
15353
257
   if (key == NULL || outLen == NULL)
15354
0
       return BAD_FUNC_ARG;
15355
15356
257
   if (key->type == ECC_PRIVATEKEY_ONLY)
15357
3
       return ECC_PRIVATEONLY_E;
15358
15359
254
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
15360
36
       return ECC_BAD_ARG_E;
15361
36
   }
15362
15363
218
   numlen = (word32)key->dp->size;
15364
15365
218
   if (*outLen < (1 + numlen)) {
15366
109
      *outLen = 1 + numlen;
15367
109
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
15368
109
   }
15369
15370
109
   if (out == NULL)
15371
0
       return BAD_FUNC_ARG;
15372
15373
109
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
15374
0
       return ECC_BAD_ARG_E;
15375
15376
   /* store first byte */
15377
109
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
15378
15379
   /* pad and store x */
15380
109
   XMEMSET(out+1, 0, numlen);
15381
109
   ret = mp_to_unsigned_bin(
15382
109
       key->pubkey.x,
15383
109
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
15384
109
   *outLen = 1 + numlen;
15385
15386
109
   return ret;
15387
109
}
15388
#endif /* HAVE_ECC_KEY_EXPORT */
15389
#endif /* HAVE_COMP_KEY */
15390
15391
#ifdef HAVE_OID_ENCODING
15392
int wc_ecc_oid_cache_init(void)
15393
{
15394
    int ret = 0;
15395
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15396
    ret = wc_InitMutex(&ecc_oid_cache_lock);
15397
#endif
15398
    return ret;
15399
}
15400
15401
void wc_ecc_oid_cache_free(void)
15402
{
15403
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
15404
    wc_FreeMutex(&ecc_oid_cache_lock);
15405
#endif
15406
}
15407
#endif /* HAVE_OID_ENCODING */
15408
15409
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
15410
6.03k
{
15411
6.03k
    int x;
15412
6.03k
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
15413
#ifdef HAVE_OID_ENCODING
15414
    oid_cache_t* o = NULL;
15415
#endif
15416
15417
6.03k
    if (oidSum == 0) {
15418
34
        return BAD_FUNC_ARG;
15419
34
    }
15420
15421
#ifdef HAVE_OID_ENCODING
15422
    #ifndef WOLFSSL_MUTEX_INITIALIZER
15423
        /* extra sanity check if wolfCrypt_Init not called */
15424
        if (eccOidLockInit == 0) {
15425
            wc_InitMutex(&ecc_oid_cache_lock);
15426
            eccOidLockInit = 1;
15427
        }
15428
    #endif
15429
15430
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
15431
        return BAD_MUTEX_E;
15432
    }
15433
#endif
15434
15435
    /* find matching OID sum (based on encoded value) */
15436
25.8k
    for (x = 0; ecc_sets[x].size != 0; x++) {
15437
23.7k
        if (ecc_sets[x].oidSum == oidSum) {
15438
        #ifdef HAVE_OID_ENCODING
15439
            /* check cache */
15440
            ret = 0;
15441
            o = &ecc_oid_cache[x];
15442
            if (o->oidSz == 0) {
15443
                o->oidSz = sizeof(o->oid);
15444
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
15445
                                                            o->oid, &o->oidSz);
15446
            }
15447
            if (oidSz) {
15448
                *oidSz = o->oidSz;
15449
            }
15450
            if (oid) {
15451
                *oid = o->oid;
15452
            }
15453
15454
            /* on success return curve id */
15455
            if (ret == 0) {
15456
                ret = ecc_sets[x].id;
15457
            }
15458
            break;
15459
        #else
15460
3.90k
            if (oidSz) {
15461
3.90k
                *oidSz = ecc_sets[x].oidSz;
15462
3.90k
            }
15463
3.90k
            if (oid) {
15464
3.90k
                *oid = ecc_sets[x].oid;
15465
3.90k
            }
15466
3.90k
            ret = ecc_sets[x].id;
15467
3.90k
            break;
15468
3.90k
        #endif
15469
3.90k
        }
15470
23.7k
    }
15471
15472
#ifdef HAVE_OID_ENCODING
15473
    wc_UnLockMutex(&ecc_oid_cache_lock);
15474
#endif
15475
15476
6.00k
    return ret;
15477
6.03k
}
15478
15479
#ifdef WOLFSSL_CUSTOM_CURVES
15480
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
15481
99
{
15482
99
    if (key == NULL || dp == NULL) {
15483
0
        return BAD_FUNC_ARG;
15484
0
    }
15485
15486
99
    key->idx = ECC_CUSTOM_IDX;
15487
99
    key->dp = dp;
15488
15489
99
    return 0;
15490
99
}
15491
#endif /* WOLFSSL_CUSTOM_CURVES */
15492
15493
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15494
15495
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
15496
0
{
15497
0
    int i;
15498
15499
    /* in network byte order so start at end and work back */
15500
0
    for (i = 3; i >= 0; i--) {
15501
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
15502
0
            return;
15503
0
    }
15504
0
}
15505
15506
/* ASN X9.63 Key Derivation Function (SEC1) */
15507
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
15508
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
15509
0
{
15510
0
    int ret;
15511
0
    word32 digestSz, copySz, remaining = outSz;
15512
0
    byte* outIdx;
15513
0
    byte  counter[4];
15514
0
    byte  tmp[WC_MAX_DIGEST_SIZE];
15515
15516
0
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
15517
15518
0
    if (secret == NULL || secretSz == 0 || out == NULL)
15519
0
        return BAD_FUNC_ARG;
15520
15521
    /* X9.63 allowed algos only */
15522
0
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
15523
0
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
15524
0
        type != WC_HASH_TYPE_SHA512)
15525
0
        return BAD_FUNC_ARG;
15526
15527
0
    ret = wc_HashGetDigestSize(type);
15528
0
    if (ret < 0)
15529
0
        return ret;
15530
0
    digestSz = (word32)ret;
15531
15532
0
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
15533
0
        return MEMORY_E);
15534
15535
0
    ret = wc_HashInit(hash, type);
15536
0
    if (ret != 0) {
15537
0
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15538
0
        return ret;
15539
0
    }
15540
15541
0
    outIdx = out;
15542
0
    XMEMSET(counter, 0, sizeof(counter));
15543
15544
0
    while (remaining > 0) {
15545
15546
0
        IncrementX963KdfCounter(counter);
15547
15548
0
        ret = wc_HashUpdate(hash, type, secret, secretSz);
15549
0
        if (ret != 0) {
15550
0
            break;
15551
0
        }
15552
15553
0
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
15554
0
        if (ret != 0) {
15555
0
            break;
15556
0
        }
15557
15558
0
        if (sinfo) {
15559
0
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
15560
0
            if (ret != 0) {
15561
0
                break;
15562
0
            }
15563
0
        }
15564
15565
0
        ret = wc_HashFinal(hash, type, tmp);
15566
0
        if (ret != 0) {
15567
0
            break;
15568
0
        }
15569
15570
0
        copySz = min(remaining, digestSz);
15571
0
        XMEMCPY(outIdx, tmp, copySz);
15572
15573
0
        remaining -= copySz;
15574
0
        outIdx += copySz;
15575
0
    }
15576
15577
0
    wc_HashFree(hash, type);
15578
15579
0
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
15580
15581
0
    return ret;
15582
0
}
15583
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
15584
15585
#ifdef WOLFSSL_SE050
15586
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
15587
 * keyId is a word32, can be used for key IDs larger than an int.
15588
 *
15589
 * key    initialized ecc_key struct
15590
 * keyId  hardware key ID which stores ECC key
15591
 * flags  optional flags, currently unused
15592
 *
15593
 * Return 0 on success, negative on error */
15594
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
15595
{
15596
    (void)flags;
15597
15598
    if (key == NULL) {
15599
        return BAD_FUNC_ARG;
15600
    }
15601
15602
    return se050_ecc_use_key_id(key, keyId);
15603
}
15604
15605
/* Get hardware key ID associated with this ecc_key structure.
15606
 *
15607
 * key    initialized ecc_key struct
15608
 * keyId  [OUT] output for key ID associated with this structure
15609
 *
15610
 * Returns 0 on success, negative on error.
15611
 */
15612
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
15613
{
15614
    if (key == NULL || keyId == NULL) {
15615
        return BAD_FUNC_ARG;
15616
    }
15617
15618
    return se050_ecc_get_key_id(key, keyId);
15619
}
15620
#endif /* WOLFSSL_SE050 */
15621
15622
15623
#ifdef WC_ECC_NONBLOCK
15624
/* Enable ECC support for non-blocking operations */
15625
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
15626
{
15627
    if (key) {
15628
        if (ctx) {
15629
            XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
15630
        }
15631
        key->nb_ctx = ctx;
15632
    }
15633
    return 0;
15634
}
15635
#endif /* WC_ECC_NONBLOCK */
15636
15637
#endif /* HAVE_ECC */